// 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

#include "nullability/pointer_nullability_analysis.h"

#include <memory>
#include <optional>
#include <utility>

#include "absl/base/nullability.h"
#include "nullability/pointer_nullability.h"
#include "nullability/pointer_nullability_lattice.h"
#include "nullability/pragma.h"
#include "nullability/type_nullability.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Expr.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Testing/CommandLineArgs.h"
#include "clang/Testing/TestAST.h"
#include "llvm/Support/Error.h"
#include "external/llvm-project/third-party/unittest/googlemock/include/gmock/gmock.h"
#include "external/llvm-project/third-party/unittest/googletest/include/gtest/gtest.h"

namespace clang::tidy::nullability {
namespace {

using ::clang::ast_matchers::declRefExpr;
using ::clang::ast_matchers::functionDecl;
using ::clang::ast_matchers::hasName;
using ::clang::ast_matchers::match;
using ::clang::ast_matchers::selectFirst;
using ::clang::ast_matchers::to;
using ::testing::ElementsAre;
using ::testing::Pointee;

NamedDecl *absl_nonnull lookup(StringRef Name, const DeclContext &DC) {
  auto Result = DC.lookup(&DC.getParentASTContext().Idents.get(Name));
  EXPECT_TRUE(Result.isSingleResult()) << Name;
  return Result.front();
}

std::optional<bool> evaluate(const dataflow::Formula &B,
                             dataflow::Environment &Env) {
  if (Env.proves(B)) return true;
  if (Env.proves(Env.arena().makeNot(B))) return false;
  return std::nullopt;
}

TEST(PointerNullabilityAnalysis, AssignNullabilityVariable) {
  // Annotations on p constrain nullability of the return value.
  // This tests we can compute that relationship symbolically.
  llvm::StringRef Src = R"cpp(
    int *target(int *p) {
      int *q = p;
      return q;
    }
  )cpp";
  TestInputs Inputs(Src);
  Inputs.Language = TestLanguage::Lang_CXX17;
  TestAST AST(Inputs);
  auto *Target = cast<FunctionDecl>(
      lookup("target", *AST.context().getTranslationUnitDecl()));
  auto *P = Target->getParamDecl(0);

  // Run the analysis, with p's annotations bound to variables.
  dataflow::DataflowAnalysisContext::Options Opts;
  // Track return values, but don't actually descend into callees
  Opts.ContextSensitiveOpts.emplace();
  Opts.ContextSensitiveOpts->Depth = 0;
  dataflow::DataflowAnalysisContext DACtx(
      std::make_unique<dataflow::WatchedLiteralsSolver>(), Opts);
  auto &A = DACtx.arena();
  auto ACFG = dataflow::AdornedCFG::build(*Target);
  dataflow::Environment Env(DACtx, *Target);
  NullabilityPragmas NoPragmas;
  PointerNullabilityAnalysis Analysis(AST.context(), Env, NoPragmas);
  auto PN = Analysis.assignNullabilityVariable(P, A);
  auto ExitState = std::move(
      cantFail(dataflow::runDataflowAnalysis(*ACFG, Analysis, std::move(Env)))
          .front());
  ASSERT_TRUE(ExitState.has_value());
  // Get the nullability model of the return value.
  auto *Ret =
      dyn_cast_or_null<dataflow::PointerValue>(ExitState->Env.getReturnValue());
  ASSERT_NE(Ret, nullptr);
  auto State = getPointerNullState(*Ret);
  ASSERT_NE(State.FromNullable, nullptr);
  ASSERT_NE(State.IsNull, nullptr);

  // The param nullability hasn't been fixed.
  EXPECT_EQ(std::nullopt, evaluate(PN.isNonnull(A), ExitState->Env));
  EXPECT_EQ(std::nullopt, evaluate(PN.isNullable(A), ExitState->Env));
  // Nor has the the nullability of the returned pointer.
  EXPECT_EQ(std::nullopt, evaluate(*State.FromNullable, ExitState->Env));
  EXPECT_EQ(std::nullopt, evaluate(*State.IsNull, ExitState->Env));
  // However, the two are linked as expected.
  EXPECT_EQ(true,
            evaluate(A.makeImplies(PN.isNonnull(A), A.makeNot(*State.IsNull)),
                     ExitState->Env));
  EXPECT_EQ(true, evaluate(A.makeEquals(PN.isNullable(A), *State.FromNullable),
                           ExitState->Env));
}

MATCHER_P(concreteNullability, Nullability, "") {
  return !arg.isSymbolic() && arg.concrete() == Nullability;
}

TEST(PointerNullabilityAnalysis,
     ResugarDeclRefExprFunctionTemplateWithParamAfterPack) {
  const llvm::StringRef Src = R"cpp(
    template <typename... X, typename T>
    T func(T t);

    void target() {
      bool* _Nonnull* _Nullable A = nullptr;
      func<int*, int>(A);
    }
  )cpp";

  TestInputs Inputs(Src);
  Inputs.Language = TestLanguage::Lang_CXX17;
  TestAST AST(Inputs);
  auto *Target = cast<FunctionDecl>(
      lookup("target", *AST.context().getTranslationUnitDecl()));

  // Run the analysis.
  dataflow::DataflowAnalysisContext DACtx(
      std::make_unique<dataflow::WatchedLiteralsSolver>());
  auto ACFG = dataflow::AdornedCFG::build(*Target);
  dataflow::Environment Env(DACtx, *Target);
  NullabilityPragmas NoPragmas;
  PointerNullabilityAnalysis Analysis(AST.context(), Env, NoPragmas);
  auto ExitState = std::move(
      cantFail(dataflow::runDataflowAnalysis(*ACFG, Analysis, std::move(Env)))
          .front());
  ASSERT_TRUE(ExitState.has_value());
  // Get the nullability recorded for the DeclRefExpr in the call to func.
  auto *DRE = selectFirst<DeclRefExpr>(
      "dre", match(declRefExpr(to(functionDecl(hasName("func")))).bind("dre"),
                   AST.context()));
  ASSERT_NE(DRE, nullptr);
  const TypeNullability *FuncNullability =
      ExitState->Lattice.getTypeNullability(DRE);

  // TODO(b/268345783): Nullability should be Nullable, Nonnull, Nullable,
  // Nonnull, but we don't handle template params correctly for functions with a
  // template parameter following a template parameter pack. For now, we at
  // least don't fail an assert during the analysis if this test passes.
  EXPECT_THAT(
      FuncNullability,
      Pointee(ElementsAre(concreteNullability(NullabilityKind::Unspecified),
                          concreteNullability(NullabilityKind::Unspecified),
                          concreteNullability(NullabilityKind::Unspecified),
                          concreteNullability(NullabilityKind::Unspecified))));
}

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