// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// Tests for nullability annotations on fields.

#include "nullability/test/check_diagnostics.h"
#include "external/llvm-project/third-party/unittest/googletest/include/gtest/gtest.h"

namespace clang::tidy::nullability {
namespace {

TEST(PointerNullabilityTest, NonNullFieldsOfPointerType) {
  // dereference field of pointer type
  EXPECT_TRUE(checkDiagnostics(R"cc(
    struct Foo {
      Foo *_Nonnull ptr;
    };
    void target(Foo foo) { *foo.ptr; }
  )cc"));

  // dereference field of pointer type in member function
  EXPECT_TRUE(checkDiagnostics(R"cc(
    struct Foo {
      Foo *_Nonnull ptr;
      void target() { *ptr; }
    };
  )cc"));
}

TEST(PointerNullabilityTest, NullableFieldsOfPointerType) {
  // dereference field of pointer type
  EXPECT_TRUE(checkDiagnostics(R"cc(
    struct Foo {
      Foo *_Nullable ptr;
    };
    void target(Foo foo) {
      *foo.ptr;  // [[unsafe]]
      if (foo.ptr) {
        *foo.ptr;
      } else {
        *foo.ptr;  // [[unsafe]]
      }
      *foo.ptr;  // [[unsafe]]
    }
  )cc"));

  // dereference field of pointer type in member function
  EXPECT_TRUE(checkDiagnostics(R"cc(
    struct Foo {
      Foo *_Nullable ptr;
      void target() {
        *ptr;  // [[unsafe]]
        if (ptr) {
          *ptr;
        } else {
          *ptr;  // [[unsafe]]
        }
        *ptr;  // [[unsafe]]
      }
    };
  )cc"));
}

TEST(PointerNullabilityTest, UnknownFieldsOfPointerType) {
  // dereference field of pointer type
  EXPECT_TRUE(checkDiagnostics(R"cc(
    struct Foo {
      Foo *ptr;
    };
    void target(Foo foo) { *foo.ptr; }
  )cc"));

  // dereference field of pointer type in member function
  EXPECT_TRUE(checkDiagnostics(R"cc(
    struct Foo {
      Foo *ptr;
      void target() { *ptr; }
    };
  )cc"));
}

TEST(PointerNullabilityTest, ChainedFieldDeref) {
  EXPECT_TRUE(checkDiagnostics(R"cc(
    struct S {
      S *_Nonnull nonnull;
      S *_Nullable nullable;
      S *unknown;
    };
    void target(S &s) {
      *(*s.nonnull).nonnull;
      *(*s.nonnull).nullable;  // [[unsafe]]
      *(*s.nonnull).unknown;

      s.nonnull->nonnull->nonnull;
      s.nonnull->nonnull->nullable;
      s.nonnull->nullable->nonnull;  // [[unsafe]]
      s.nonnull->unknown->nonnull;

      *&s;
    }
  )cc"));
}

// This is a crash repro. It sets up a situation where we're merging pointers
// that don't have a null state to check that we don't crash in this case.
TEST(PointerNullabilityTest, MergePointersWithoutNullState) {
  EXPECT_TRUE(checkDiagnostics(R"cc(
    struct S {
      void *p;
    };
    void target(bool cond) {
      S src, dst;
      if (cond) dst = src;

      // `dst` has different values in the two branches that merge here, so we
      // will attempt to merge the values of `dst.p` from the two branches.

      // These lines are only here to ensure that `p` is modeled.
      S unrelated;
      unrelated.p;
    }
  )cc"));
}

TEST(PointerNullabilityTest, CreatesConsistentPointerValueForField) {
  // This is a repro for a false positive.
  // The call to `some_func()` clears the value of `p_`.
  // Our logic for creating new pointer values used to work only on prvalues,
  // so it would create two independent pointer values for the two accesses of
  // `p_`, and hence we would not be able to conclude that `p_` was null in the
  // `p_->target()` call.
  EXPECT_TRUE(checkDiagnostics(R"cc(
    struct S {
      S* _Nullable const p_;
      void target() {
        some_func();

        if (p_ != nullptr)
          p_->target();  // p_ needs to be a member variable to repro.
      }
      void some_func();
    };
  )cc"));
}

}  // namespace
}  // namespace clang::tidy::nullability
