// 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 "nullability/pointer_nullability.h"
#include "nullability/pointer_nullability_lattice.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
#include "clang/Basic/LLVM.h"
#include "clang/Testing/TestAST.h"
#include "llvm/Support/Error.h"
#include "third_party/llvm/llvm-project/third-party/unittest/googletest/include/gtest/gtest.h"

namespace clang::tidy::nullability {
namespace {

NamedDecl *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(dataflow::BoolValue &B,
                             dataflow::Environment &Env) {
  if (Env.flowConditionImplies(B)) return true;
  if (Env.flowConditionImplies(Env.makeNot(B))) return false;
  return std::nullopt;
}

TEST(PointerNullabilityAnalysis, AssignNullabilityVariable) {
  // Annotations on p constrain nullabiilty of the return value.
  // This tests we can compute that relationship symbolically.
  TestAST AST(R"cpp(
    int *target(int *p) {
      int *q = p;
      return q;
    }
  )cpp");
  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 CFCtx = dataflow::ControlFlowContext::build(*Target);
  PointerNullabilityAnalysis Analysis(AST.context());
  auto [PNonnull, PNullable] = Analysis.assignNullabilityVariable(P, A);
  auto ExitState =
      *cantFail(dataflow::runDataflowAnalysis(
                    *CFCtx, Analysis, dataflow::Environment(DACtx, *Target)))
           .front();
  // Get the nullability model of the return value.
  auto *Ret =
      dyn_cast_or_null<dataflow::PointerValue>(ExitState.Env.getReturnValue());
  ASSERT_NE(Ret, nullptr);
  auto [RetKnown, RetNull] = getPointerNullState(*Ret);

  // The param nullability hasn't been fixed.
  EXPECT_EQ(std::nullopt, evaluate(*PNonnull, ExitState.Env));
  EXPECT_EQ(std::nullopt, evaluate(*PNullable, ExitState.Env));
  // Nor has the the nullability of the returned pointer.
  EXPECT_EQ(std::nullopt, evaluate(RetKnown, ExitState.Env));
  EXPECT_EQ(std::nullopt, evaluate(RetNull, ExitState.Env));
  // However, the two are linked as expected.
  EXPECT_EQ(true, evaluate(A.makeImplies(*PNonnull, A.makeNot(RetNull)),
                           ExitState.Env));
  EXPECT_EQ(true,
            evaluate(A.makeEquals(A.makeOr(*PNonnull, *PNullable), RetKnown),
                     ExitState.Env));
}

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