//==- GTestChecker.cpp - Model gtest API --*- C++ -*-==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This checker models the behavior of un-inlined APIs from the gtest
// unit-testing library to avoid false positives when using assertions from
// that library.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/LangOptions.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>

using namespace clang;
using namespace ento;

// Modeling of un-inlined AssertionResult constructors
//
// The gtest unit testing API provides macros for assertions that expand
// into an if statement that calls a series of constructors and returns
// when the "assertion" is false.
//
// For example,
//
//   ASSERT_TRUE(a == b)
//
// expands into:
//
//   switch (0)
//   case 0:
//   default:
//     if (const ::testing::AssertionResult gtest_ar_ =
//             ::testing::AssertionResult((a == b)))
//       ;
//     else
//       return ::testing::internal::AssertHelper(
//                  ::testing::TestPartResult::kFatalFailure,
//                  "<path to project>",
//                  <line number>,
//                  ::testing::internal::GetBoolAssertionFailureMessage(
//                      gtest_ar_, "a == b", "false", "true")
//                      .c_str()) = ::testing::Message();
//
// where AssertionResult is defined similarly to
//
//   class AssertionResult {
//   public:
//     AssertionResult(const AssertionResult& other);
//     explicit AssertionResult(bool success) : success_(success) {}
//     operator bool() const { return success_; }
//     ...
//     private:
//     bool success_;
//   };
//
// In order for the analyzer to correctly handle this assertion, it needs to
// know that the boolean value of the expression "a == b" is stored the
// 'success_' field of the original AssertionResult temporary and propagated
// (via the copy constructor) into the 'success_' field of the object stored
// in 'gtest_ar_'.  That boolean value will then be returned from the bool
// conversion method in the if statement. This guarantees that the assertion
// holds when the return path is not taken.
//
// If the success value is not properly propagated, then the eager case split
// on evaluating the expression can cause pernicious false positives
// on the non-return path:
//
//   ASSERT(ptr != NULL)
//   *ptr = 7; // False positive null pointer dereference here
//
// Unfortunately, the bool constructor cannot be inlined (because its
// implementation is not present in the headers) and the copy constructor is
// not inlined (because it is constructed into a temporary and the analyzer
// does not inline these since it does not yet reliably call temporary
// destructors).
//
// This checker compensates for the missing inlining by propagating the
// _success value across the bool and copy constructors so the assertion behaves
// as expected.

namespace {
class GTestChecker : public Checker<check::PostCall> {

  mutable IdentifierInfo *AssertionResultII;
  mutable IdentifierInfo *SuccessII;

public:
  GTestChecker();

  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;

private:
  void modelAssertionResultBoolConstructor(const CXXConstructorCall *Call,
                                           bool IsRef, CheckerContext &C) const;

  void modelAssertionResultCopyConstructor(const CXXConstructorCall *Call,
                                           CheckerContext &C) const;

  void initIdentifierInfo(ASTContext &Ctx) const;

  SVal
  getAssertionResultSuccessFieldValue(const CXXRecordDecl *AssertionResultDecl,
                                      SVal Instance,
                                      ProgramStateRef State) const;

  static ProgramStateRef assumeValuesEqual(SVal Val1, SVal Val2,
                                           ProgramStateRef State,
                                           CheckerContext &C);
};
} // End anonymous namespace.

GTestChecker::GTestChecker() : AssertionResultII(nullptr), SuccessII(nullptr) {}

/// Model a call to an un-inlined AssertionResult(bool) or
/// AssertionResult(bool &, ...).
/// To do so, constrain the value of the newly-constructed instance's 'success_'
/// field to be equal to the passed-in boolean value.
///
/// \param IsRef Whether the boolean parameter is a reference or not.
void GTestChecker::modelAssertionResultBoolConstructor(
    const CXXConstructorCall *Call, bool IsRef, CheckerContext &C) const {
  assert(Call->getNumArgs() >= 1 && Call->getNumArgs() <= 2);

  ProgramStateRef State = C.getState();
  SVal BooleanArgVal = Call->getArgSVal(0);
  if (IsRef) {
    // The argument is a reference, so load from it to get the boolean value.
    if (!isa<Loc>(BooleanArgVal))
      return;
    BooleanArgVal = C.getState()->getSVal(BooleanArgVal.castAs<Loc>());
  }

  SVal ThisVal = Call->getCXXThisVal();

  SVal ThisSuccess = getAssertionResultSuccessFieldValue(
      Call->getDecl()->getParent(), ThisVal, State);

  State = assumeValuesEqual(ThisSuccess, BooleanArgVal, State, C);
  C.addTransition(State);
}

/// Model a call to an un-inlined AssertionResult copy constructor:
///
///   AssertionResult(const &AssertionResult other)
///
/// To do so, constrain the value of the newly-constructed instance's
/// 'success_' field to be equal to the value of the pass-in instance's
/// 'success_' field.
void GTestChecker::modelAssertionResultCopyConstructor(
    const CXXConstructorCall *Call, CheckerContext &C) const {
  assert(Call->getNumArgs() == 1);

  // The first parameter of the copy constructor must be the other
  // instance to initialize this instances fields from.
  SVal OtherVal = Call->getArgSVal(0);
  SVal ThisVal = Call->getCXXThisVal();

  const CXXRecordDecl *AssertResultClassDecl = Call->getDecl()->getParent();
  ProgramStateRef State = C.getState();

  SVal ThisSuccess = getAssertionResultSuccessFieldValue(AssertResultClassDecl,
                                                         ThisVal, State);
  SVal OtherSuccess = getAssertionResultSuccessFieldValue(AssertResultClassDecl,
                                                          OtherVal, State);

  State = assumeValuesEqual(ThisSuccess, OtherSuccess, State, C);
  C.addTransition(State);
}

/// Model calls to AssertionResult constructors that are not inlined.
void GTestChecker::checkPostCall(const CallEvent &Call,
                                 CheckerContext &C) const {
  /// If the constructor was inlined, there is no need model it.
  if (C.wasInlined)
    return;

  initIdentifierInfo(C.getASTContext());

  auto *CtorCall = dyn_cast<CXXConstructorCall>(&Call);
  if (!CtorCall)
    return;

  const CXXConstructorDecl *CtorDecl = CtorCall->getDecl();
  const CXXRecordDecl *CtorParent = CtorDecl->getParent();
  if (CtorParent->getIdentifier() != AssertionResultII)
    return;

  unsigned ParamCount = CtorDecl->getNumParams();

  // Call the appropriate modeling method based the parameters and their
  // types.

  // We have AssertionResult(const &AssertionResult)
  if (CtorDecl->isCopyConstructor() && ParamCount == 1) {
    modelAssertionResultCopyConstructor(CtorCall, C);
    return;
  }

  // There are two possible boolean constructors, depending on which
  // version of gtest is being used:
  //
  // v1.7 and earlier:
  //      AssertionResult(bool success)
  //
  // v1.8 and greater:
  //      template <typename T>
  //      AssertionResult(const T& success,
  //                      typename internal::EnableIf<
  //                          !internal::ImplicitlyConvertible<T,
  //                              AssertionResult>::value>::type*)
  //
  CanQualType BoolTy = C.getASTContext().BoolTy;
  if (ParamCount == 1 && CtorDecl->getParamDecl(0)->getType() == BoolTy) {
    // We have AssertionResult(bool)
    modelAssertionResultBoolConstructor(CtorCall, /*IsRef=*/false, C);
    return;
  }
  if (ParamCount == 2){
    auto *RefTy = CtorDecl->getParamDecl(0)->getType()->getAs<ReferenceType>();
    if (RefTy &&
        RefTy->getPointeeType()->getCanonicalTypeUnqualified() == BoolTy) {
      // We have AssertionResult(bool &, ...)
      modelAssertionResultBoolConstructor(CtorCall, /*IsRef=*/true, C);
      return;
    }
  }
}

void GTestChecker::initIdentifierInfo(ASTContext &Ctx) const {
  if (AssertionResultII)
    return;

  AssertionResultII = &Ctx.Idents.get("AssertionResult");
  SuccessII = &Ctx.Idents.get("success_");
}

/// Returns the value stored in the 'success_' field of the passed-in
/// AssertionResult instance.
SVal GTestChecker::getAssertionResultSuccessFieldValue(
    const CXXRecordDecl *AssertionResultDecl, SVal Instance,
    ProgramStateRef State) const {

  DeclContext::lookup_result Result = AssertionResultDecl->lookup(SuccessII);
  if (Result.empty())
    return UnknownVal();

  auto *SuccessField = dyn_cast<FieldDecl>(Result.front());
  if (!SuccessField)
    return UnknownVal();

  std::optional<Loc> FieldLoc =
      State->getLValue(SuccessField, Instance).getAs<Loc>();
  if (!FieldLoc)
    return UnknownVal();

  return State->getSVal(*FieldLoc);
}

/// Constrain the passed-in state to assume two values are equal.
ProgramStateRef GTestChecker::assumeValuesEqual(SVal Val1, SVal Val2,
                                                ProgramStateRef State,
                                                CheckerContext &C) {
  auto DVal1 = Val1.getAs<DefinedOrUnknownSVal>();
  auto DVal2 = Val2.getAs<DefinedOrUnknownSVal>();
  if (!DVal1 || !DVal2)
    return State;

  auto ValuesEqual =
      C.getSValBuilder().evalEQ(State, *DVal1, *DVal2).getAs<DefinedSVal>();
  if (!ValuesEqual)
    return State;

  State = C.getConstraintManager().assume(State, *ValuesEqual, true);
  return State;
}

void ento::registerGTestChecker(CheckerManager &Mgr) {
  Mgr.registerChecker<GTestChecker>();
}

bool ento::shouldRegisterGTestChecker(const CheckerManager &mgr) {
  // gtest is a C++ API so there is no sense running the checker
  // if not compiling for C++.
  const LangOptions &LO = mgr.getLangOpts();
  return LO.CPlusPlus;
}
