[clang] e0cc28d - Revert "[clang][dataflow] Add analysis that detects unsafe accesses to optionals"

Stanislav Gatev via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 9 01:51:45 PST 2022


Author: Stanislav Gatev
Date: 2022-03-09T09:51:03Z
New Revision: e0cc28dfdc67105974924cce42bb8c85bd44925a

URL: https://github.com/llvm/llvm-project/commit/e0cc28dfdc67105974924cce42bb8c85bd44925a
DIFF: https://github.com/llvm/llvm-project/commit/e0cc28dfdc67105974924cce42bb8c85bd44925a.diff

LOG: Revert "[clang][dataflow] Add analysis that detects unsafe accesses to optionals"

This reverts commit ce205cffdfa0f16ce9441ba46fa43e23cecf8be7.

Added: 
    clang/unittests/Analysis/FlowSensitive/TestingSupport.cpp
    clang/unittests/Analysis/FlowSensitive/TestingSupport.h

Modified: 
    clang/lib/Analysis/FlowSensitive/CMakeLists.txt
    clang/unittests/Analysis/FlowSensitive/CMakeLists.txt
    clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
    clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
    clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp
    clang/unittests/Analysis/FlowSensitive/SingleVarConstantPropagationTest.cpp
    clang/unittests/Analysis/FlowSensitive/TestingSupportTest.cpp
    clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
    clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp

Removed: 
    clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
    clang/include/clang/Analysis/FlowSensitive/TestingSupport.h
    clang/lib/Analysis/FlowSensitive/Models/CMakeLists.txt
    clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
    clang/lib/Analysis/FlowSensitive/TestingSupport.cpp
    clang/unittests/Analysis/FlowSensitive/Models/CMakeLists.txt
    clang/unittests/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModelTest.cpp


################################################################################
diff  --git a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
deleted file mode 100644
index e5ad0cadd7bd9..0000000000000
--- a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_UNCHECKEDOPTIONALACCESSMODEL_H
-#define CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_UNCHECKEDOPTIONALACCESSMODEL_H
-
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
-#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
-#include "clang/Analysis/FlowSensitive/MatchSwitch.h"
-#include "clang/Analysis/FlowSensitive/SourceLocationsLattice.h"
-
-namespace clang {
-namespace dataflow {
-
-/// Dataflow analysis that discovers unsafe accesses of optional values and
-/// adds the respective source locations to the lattice.
-///
-/// Models the `std::optional`, `absl::optional`, and `base::Optional` types.
-///
-/// FIXME: Consider separating the models from the unchecked access analysis.
-class UncheckedOptionalAccessModel
-    : public DataflowAnalysis<UncheckedOptionalAccessModel,
-                              SourceLocationsLattice> {
-public:
-  explicit UncheckedOptionalAccessModel(ASTContext &AstContext);
-
-  static SourceLocationsLattice initialElement() {
-    return SourceLocationsLattice();
-  }
-
-  void transfer(const Stmt *Stmt, SourceLocationsLattice &State,
-                Environment &Env);
-
-private:
-  MatchSwitch<TransferState<SourceLocationsLattice>> TransferMatchSwitch;
-};
-
-} // namespace dataflow
-} // namespace clang
-
-#endif // CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_UNCHECKEDOPTIONALACCESSMODEL_H

diff  --git a/clang/lib/Analysis/FlowSensitive/CMakeLists.txt b/clang/lib/Analysis/FlowSensitive/CMakeLists.txt
index df7a09f24f05d..cfe3c8e77b4fd 100644
--- a/clang/lib/Analysis/FlowSensitive/CMakeLists.txt
+++ b/clang/lib/Analysis/FlowSensitive/CMakeLists.txt
@@ -3,7 +3,6 @@ add_clang_library(clangAnalysisFlowSensitive
   DataflowAnalysisContext.cpp
   DataflowEnvironment.cpp
   SourceLocationsLattice.cpp
-  TestingSupport.cpp
   Transfer.cpp
   TypeErasedDataflowAnalysis.cpp
   WatchedLiteralsSolver.cpp
@@ -13,5 +12,3 @@ add_clang_library(clangAnalysisFlowSensitive
   clangAST
   clangBasic
   )
-
-add_subdirectory(Models)

diff  --git a/clang/lib/Analysis/FlowSensitive/Models/CMakeLists.txt b/clang/lib/Analysis/FlowSensitive/Models/CMakeLists.txt
deleted file mode 100644
index 5bed00c4bfdc6..0000000000000
--- a/clang/lib/Analysis/FlowSensitive/Models/CMakeLists.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-add_clang_library(clangAnalysisFlowSensitiveModels
-  UncheckedOptionalAccessModel.cpp
-
-  LINK_LIBS
-  clangAnalysis
-  clangAnalysisFlowSensitive
-  clangAST
-  clangASTMatchers
-  clangBasic
-  )

diff  --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
deleted file mode 100644
index bb6aa5ff74e2c..0000000000000
--- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-#include "clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/Stmt.h"
-#include "clang/ASTMatchers/ASTMatchers.h"
-#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
-#include "clang/Analysis/FlowSensitive/MatchSwitch.h"
-#include "clang/Analysis/FlowSensitive/SourceLocationsLattice.h"
-#include "clang/Analysis/FlowSensitive/Value.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Casting.h"
-#include <cassert>
-
-namespace clang {
-namespace dataflow {
-namespace {
-
-using namespace ::clang::ast_matchers;
-
-using LatticeTransferState = TransferState<SourceLocationsLattice>;
-
-static auto optionalClass() {
-  return classTemplateSpecializationDecl(
-      anyOf(hasName("std::optional"), hasName("std::__optional_storage_base"),
-            hasName("__optional_destruct_base"), hasName("absl::optional"),
-            hasName("base::Optional")),
-      hasTemplateArgument(0, refersToType(type().bind("T"))));
-}
-
-static auto hasOptionalType() { return hasType(optionalClass()); }
-
-static auto isOptionalMemberCallWithName(llvm::StringRef MemberName) {
-  return cxxMemberCallExpr(
-      on(expr(unless(cxxThisExpr()))),
-      callee(cxxMethodDecl(hasName(MemberName), ofClass(optionalClass()))));
-}
-
-static auto isOptionalOperatorCallWithName(llvm::StringRef OperatorName) {
-  return cxxOperatorCallExpr(hasOverloadedOperatorName(OperatorName),
-                             callee(cxxMethodDecl(ofClass(optionalClass()))));
-}
-
-/// Returns the symbolic value that represents the "has_value" property of the
-/// optional value `Val`. Returns null if `Val` is null.
-static BoolValue *getHasValue(Value *Val) {
-  if (auto *OptionalVal = cast_or_null<StructValue>(Val)) {
-    return cast<BoolValue>(OptionalVal->getProperty("has_value"));
-  }
-  return nullptr;
-}
-
-static void initializeOptionalReference(const Expr *OptionalExpr,
-                                        LatticeTransferState &State) {
-  if (auto *OptionalVal = cast_or_null<StructValue>(
-          State.Env.getValue(*OptionalExpr, SkipPast::Reference))) {
-    if (OptionalVal->getProperty("has_value") == nullptr) {
-      OptionalVal->setProperty("has_value", State.Env.makeAtomicBoolValue());
-    }
-  }
-}
-
-static void transferUnwrapCall(const Expr *UnwrapExpr, const Expr *ObjectExpr,
-                               LatticeTransferState &State) {
-  if (auto *OptionalVal = cast_or_null<StructValue>(
-          State.Env.getValue(*ObjectExpr, SkipPast::ReferenceThenPointer))) {
-    auto *HasValueVal = getHasValue(OptionalVal);
-    assert(HasValueVal != nullptr);
-
-    if (State.Env.flowConditionImplies(*HasValueVal))
-      return;
-  }
-
-  // Record that this unwrap is *not* provably safe.
-  State.Lattice.getSourceLocations().insert(ObjectExpr->getBeginLoc());
-}
-
-static void transferOptionalHasValueCall(const CXXMemberCallExpr *CallExpr,
-                                         LatticeTransferState &State) {
-  if (auto *OptionalVal = cast_or_null<StructValue>(
-          State.Env.getValue(*CallExpr->getImplicitObjectArgument(),
-                             SkipPast::ReferenceThenPointer))) {
-    auto *HasValueVal = getHasValue(OptionalVal);
-    assert(HasValueVal != nullptr);
-
-    auto &CallExprLoc = State.Env.createStorageLocation(*CallExpr);
-    State.Env.setValue(CallExprLoc, *HasValueVal);
-    State.Env.setStorageLocation(*CallExpr, CallExprLoc);
-  }
-}
-
-static auto buildTransferMatchSwitch() {
-  return MatchSwitchBuilder<LatticeTransferState>()
-      // Attach a symbolic "has_value" state to optional values that we see for
-      // the first time.
-      .CaseOf(expr(anyOf(declRefExpr(), memberExpr()), hasOptionalType()),
-              initializeOptionalReference)
-
-      // optional::value
-      .CaseOf(
-          isOptionalMemberCallWithName("value"),
-          +[](const CXXMemberCallExpr *E, LatticeTransferState &State) {
-            transferUnwrapCall(E, E->getImplicitObjectArgument(), State);
-          })
-
-      // optional::operator*, optional::operator->
-      .CaseOf(
-          expr(anyOf(isOptionalOperatorCallWithName("*"),
-                     isOptionalOperatorCallWithName("->"))),
-          +[](const CallExpr *E, LatticeTransferState &State) {
-            transferUnwrapCall(E, E->getArg(0), State);
-          })
-
-      // optional::has_value
-      .CaseOf(isOptionalMemberCallWithName("has_value"),
-              transferOptionalHasValueCall)
-
-      .Build();
-}
-
-} // namespace
-
-UncheckedOptionalAccessModel::UncheckedOptionalAccessModel(ASTContext &Ctx)
-    : DataflowAnalysis<UncheckedOptionalAccessModel, SourceLocationsLattice>(
-          Ctx),
-      TransferMatchSwitch(buildTransferMatchSwitch()) {}
-
-void UncheckedOptionalAccessModel::transfer(const Stmt *S,
-                                            SourceLocationsLattice &L,
-                                            Environment &Env) {
-  LatticeTransferState State(L, Env);
-  TransferMatchSwitch(*S, getASTContext(), State);
-}
-
-} // namespace dataflow
-} // namespace clang

diff  --git a/clang/unittests/Analysis/FlowSensitive/CMakeLists.txt b/clang/unittests/Analysis/FlowSensitive/CMakeLists.txt
index 131b62c9158b5..d2608503a5396 100644
--- a/clang/unittests/Analysis/FlowSensitive/CMakeLists.txt
+++ b/clang/unittests/Analysis/FlowSensitive/CMakeLists.txt
@@ -11,6 +11,7 @@ add_clang_unittest(ClangAnalysisFlowSensitiveTests
   MultiVarConstantPropagationTest.cpp
   SingleVarConstantPropagationTest.cpp
   SourceLocationsLatticeTest.cpp
+  TestingSupport.cpp
   TestingSupportTest.cpp
   TransferTest.cpp
   TypeErasedDataflowAnalysisTest.cpp
@@ -35,5 +36,3 @@ target_link_libraries(ClangAnalysisFlowSensitiveTests
   PRIVATE
   LLVMTestingSupport
   )
-
-add_subdirectory(Models)

diff  --git a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
index ef0049f2a7059..51b40f2319878 100644
--- a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
@@ -8,8 +8,8 @@
 
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "NoopAnalysis.h"
+#include "TestingSupport.h"
 #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
-#include "clang/Analysis/FlowSensitive/TestingSupport.h"
 #include "clang/Analysis/FlowSensitive/Value.h"
 #include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
 #include "gmock/gmock.h"

diff  --git a/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp b/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
index 9b59ee2a4df4c..b99e5c6e1c0b0 100644
--- a/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Analysis/FlowSensitive/MatchSwitch.h"
+#include "TestingSupport.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
@@ -23,7 +24,6 @@
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/DataflowLattice.h"
 #include "clang/Analysis/FlowSensitive/MapLattice.h"
-#include "clang/Analysis/FlowSensitive/TestingSupport.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"

diff  --git a/clang/unittests/Analysis/FlowSensitive/Models/CMakeLists.txt b/clang/unittests/Analysis/FlowSensitive/Models/CMakeLists.txt
deleted file mode 100644
index df378c47f1e73..0000000000000
--- a/clang/unittests/Analysis/FlowSensitive/Models/CMakeLists.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-set(LLVM_LINK_COMPONENTS
-  FrontendOpenMP
-  Support
-  )
-
-add_clang_unittest(ClangAnalysisFlowSensitiveModelsTests
-  UncheckedOptionalAccessModelTest.cpp
-  )
-
-clang_target_link_libraries(ClangAnalysisFlowSensitiveModelsTests
-  PRIVATE
-  clangAnalysis
-  clangAnalysisFlowSensitive
-  clangAnalysisFlowSensitiveModels
-  clangAST
-  clangASTMatchers
-  clangBasic
-  clangFrontend
-  clangLex
-  clangSerialization
-  clangTesting
-  clangTooling
-  )
-
-target_link_libraries(ClangAnalysisFlowSensitiveModelsTests
-  PRIVATE
-  LLVMTestingSupport
-  )

diff  --git a/clang/unittests/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModelTest.cpp b/clang/unittests/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModelTest.cpp
deleted file mode 100644
index 5d99d79efd323..0000000000000
--- a/clang/unittests/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModelTest.cpp
+++ /dev/null
@@ -1,332 +0,0 @@
-#include "clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/ASTMatchers/ASTMatchers.h"
-#include "clang/Analysis/FlowSensitive/SourceLocationsLattice.h"
-#include "clang/Analysis/FlowSensitive/TestingSupport.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Error.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include <string>
-#include <utility>
-#include <vector>
-
-using namespace clang;
-using namespace dataflow;
-using namespace test;
-
-using ::testing::Pair;
-using ::testing::UnorderedElementsAre;
-
-static constexpr char StdTypeTraitsHeader[] = R"(
-namespace std {
-
-template< class T > struct remove_reference      {typedef T type;};
-template< class T > struct remove_reference<T&>  {typedef T type;};
-template< class T > struct remove_reference<T&&> {typedef T type;};
-
-template <class T>
-  using remove_reference_t = typename remove_reference<T>::type;
-
-} // namespace std
-)";
-
-static constexpr char StdUtilityHeader[] = R"(
-#include "std_type_traits.h"
-
-namespace std {
-
-template <typename T>
-constexpr std::remove_reference_t<T>&& move(T&& x);
-
-} // namespace std
-)";
-
-static constexpr char StdOptionalHeader[] = R"(
-namespace std {
-
-template <typename T>
-class optional {
- public:
-  constexpr optional() noexcept;
-
-  const T& operator*() const&;
-  T& operator*() &;
-  const T&& operator*() const&&;
-  T&& operator*() &&;
-
-  const T* operator->() const;
-  T* operator->();
-
-  const T& value() const&;
-  T& value() &;
-  const T&& value() const&&;
-  T&& value() &&;
-
-  constexpr bool has_value() const noexcept;
-};
-
-} // namespace std
-)";
-
-static constexpr char AbslOptionalHeader[] = R"(
-namespace absl {
-
-template <typename T>
-class optional {
- public:
-  constexpr optional() noexcept;
-
-  const T& operator*() const&;
-  T& operator*() &;
-  const T&& operator*() const&&;
-  T&& operator*() &&;
-
-  const T* operator->() const;
-  T* operator->();
-
-  const T& value() const&;
-  T& value() &;
-  const T&& value() const&&;
-  T&& value() &&;
-
-  constexpr bool has_value() const noexcept;
-};
-
-} // namespace absl
-)";
-
-static constexpr char BaseOptionalHeader[] = R"(
-namespace base {
-
-template <typename T>
-class Optional {
- public:
-  constexpr Optional() noexcept;
-
-  const T& operator*() const&;
-  T& operator*() &;
-  const T&& operator*() const&&;
-  T&& operator*() &&;
-
-  const T* operator->() const;
-  T* operator->();
-
-  const T& value() const&;
-  T& value() &;
-  const T&& value() const&&;
-  T&& value() &&;
-
-  constexpr bool has_value() const noexcept;
-};
-
-} // namespace base
-)";
-
-/// Converts `L` to string.
-static std::string ConvertToString(const SourceLocationsLattice &L,
-                                   const ASTContext &Ctx) {
-  return L.getSourceLocations().empty() ? "safe"
-                                        : "unsafe: " + DebugString(L, Ctx);
-}
-
-/// Replaces all occurrences of `Pattern` in `S` with `Replacement`.
-static void ReplaceAllOccurrences(std::string &S, const std::string &Pattern,
-                                  const std::string &Replacement) {
-  size_t Pos = 0;
-  while (true) {
-    Pos = S.find(Pattern, Pos);
-    if (Pos == std::string::npos)
-      break;
-    S.replace(Pos, Pattern.size(), Replacement);
-  }
-}
-
-struct OptionalTypeIdentifier {
-  std::string NamespaceName;
-  std::string TypeName;
-};
-
-class UncheckedOptionalAccessTest
-    : public ::testing::TestWithParam<OptionalTypeIdentifier> {
-protected:
-  template <typename LatticeChecksMatcher>
-  void ExpectLatticeChecksFor(std::string SourceCode,
-                              LatticeChecksMatcher MatchesLatticeChecks) {
-    ExpectLatticeChecksFor(SourceCode, ast_matchers::hasName("target"),
-                           MatchesLatticeChecks);
-  }
-
-private:
-  template <typename FuncDeclMatcher, typename LatticeChecksMatcher>
-  void ExpectLatticeChecksFor(std::string SourceCode,
-                              FuncDeclMatcher FuncMatcher,
-                              LatticeChecksMatcher MatchesLatticeChecks) {
-    ReplaceAllOccurrences(SourceCode, "$ns", GetParam().NamespaceName);
-    ReplaceAllOccurrences(SourceCode, "$optional", GetParam().TypeName);
-
-    std::vector<std::pair<std::string, std::string>> Headers;
-    Headers.emplace_back("std_type_traits.h", StdTypeTraitsHeader);
-    Headers.emplace_back("std_utility.h", StdUtilityHeader);
-    Headers.emplace_back("std_optional.h", StdOptionalHeader);
-    Headers.emplace_back("absl_optional.h", AbslOptionalHeader);
-    Headers.emplace_back("base_optional.h", BaseOptionalHeader);
-    Headers.emplace_back("unchecked_optional_access_test.h", R"(
-      #include "absl_optional.h"
-      #include "base_optional.h"
-      #include "std_optional.h"
-      #include "std_utility.h"
-    )");
-    const tooling::FileContentMappings FileContents(Headers.begin(),
-                                                    Headers.end());
-    llvm::Error Error = checkDataflow<UncheckedOptionalAccessModel>(
-        SourceCode, FuncMatcher,
-        [](ASTContext &Ctx, Environment &) {
-          return UncheckedOptionalAccessModel(Ctx);
-        },
-        [&MatchesLatticeChecks](
-            llvm::ArrayRef<std::pair<
-                std::string, DataflowAnalysisState<SourceLocationsLattice>>>
-                CheckToLatticeMap,
-            ASTContext &Ctx) {
-          // FIXME: Consider using a matcher instead of translating
-          // `CheckToLatticeMap` to `CheckToStringifiedLatticeMap`.
-          std::vector<std::pair<std::string, std::string>>
-              CheckToStringifiedLatticeMap;
-          for (const auto &E : CheckToLatticeMap) {
-            CheckToStringifiedLatticeMap.emplace_back(
-                E.first, ConvertToString(E.second.Lattice, Ctx));
-          }
-          EXPECT_THAT(CheckToStringifiedLatticeMap, MatchesLatticeChecks);
-        },
-        {"-fsyntax-only", "-std=c++17", "-Wno-undefined-inline"}, FileContents);
-    if (Error)
-      FAIL() << llvm::toString(std::move(Error));
-  }
-};
-
-INSTANTIATE_TEST_SUITE_P(
-    UncheckedOptionalUseTestInst, UncheckedOptionalAccessTest,
-    ::testing::Values(OptionalTypeIdentifier{"std", "optional"},
-                      OptionalTypeIdentifier{"absl", "optional"},
-                      OptionalTypeIdentifier{"base", "Optional"}),
-    [](const ::testing::TestParamInfo<OptionalTypeIdentifier> &Info) {
-      return Info.param.NamespaceName;
-    });
-
-TEST_P(UncheckedOptionalAccessTest, EmptyFunctionBody) {
-  ExpectLatticeChecksFor(R"(
-    void target() {
-      (void)0;
-      /*[[check]]*/
-    }
-  )",
-                         UnorderedElementsAre(Pair("check", "safe")));
-}
-
-TEST_P(UncheckedOptionalAccessTest, UnwrapUsingValueNoCheck) {
-  ExpectLatticeChecksFor(
-      R"(
-    #include "unchecked_optional_access_test.h"
-
-    void target($ns::$optional<int> opt) {
-      opt.value();
-      /*[[check]]*/
-    }
-  )",
-      UnorderedElementsAre(Pair("check", "unsafe: input.cc:5:7")));
-
-  ExpectLatticeChecksFor(
-      R"(
-    #include "unchecked_optional_access_test.h"
-
-    void target($ns::$optional<int> opt) {
-      std::move(opt).value();
-      /*[[check]]*/
-    }
-  )",
-      UnorderedElementsAre(Pair("check", "unsafe: input.cc:5:7")));
-}
-
-TEST_P(UncheckedOptionalAccessTest, UnwrapUsingOperatorStarNoCheck) {
-  ExpectLatticeChecksFor(
-      R"(
-    #include "unchecked_optional_access_test.h"
-
-    void target($ns::$optional<int> opt) {
-      *opt;
-      /*[[check]]*/
-    }
-  )",
-      UnorderedElementsAre(Pair("check", "unsafe: input.cc:5:8")));
-
-  ExpectLatticeChecksFor(
-      R"(
-    #include "unchecked_optional_access_test.h"
-
-    void target($ns::$optional<int> opt) {
-      *std::move(opt);
-      /*[[check]]*/
-    }
-  )",
-      UnorderedElementsAre(Pair("check", "unsafe: input.cc:5:8")));
-}
-
-TEST_P(UncheckedOptionalAccessTest, UnwrapUsingOperatorArrowNoCheck) {
-  ExpectLatticeChecksFor(
-      R"(
-    #include "unchecked_optional_access_test.h"
-
-    struct Foo {
-      void foo();
-    };
-
-    void target($ns::$optional<Foo> opt) {
-      opt->foo();
-      /*[[check]]*/
-    }
-  )",
-      UnorderedElementsAre(Pair("check", "unsafe: input.cc:9:7")));
-
-  ExpectLatticeChecksFor(
-      R"(
-    #include "unchecked_optional_access_test.h"
-
-    struct Foo {
-      void foo();
-    };
-
-    void target($ns::$optional<Foo> opt) {
-      std::move(opt)->foo();
-      /*[[check]]*/
-    }
-  )",
-      UnorderedElementsAre(Pair("check", "unsafe: input.cc:9:7")));
-}
-
-TEST_P(UncheckedOptionalAccessTest, UnwrapWithCheck) {
-  ExpectLatticeChecksFor(R"(
-    #include "unchecked_optional_access_test.h"
-
-    void target($ns::$optional<int> opt) {
-      if (opt.has_value()) {
-        opt.value();
-        /*[[check]]*/
-      }
-    }
-  )",
-                         UnorderedElementsAre(Pair("check", "safe")));
-}
-
-// FIXME: Add support for:
-// - constructors (default, copy, move, non-standard)
-// - assignment operators (default, copy, move, non-standard)
-// - operator bool
-// - emplace
-// - reset
-// - value_or
-// - swap
-// - make_optional
-// - invalidation (passing optional by non-const reference/pointer)

diff  --git a/clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp b/clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp
index e246da75e32a8..9535f99c5aea4 100644
--- a/clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp
@@ -12,6 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "TestingSupport.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
@@ -22,7 +23,6 @@
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/DataflowLattice.h"
 #include "clang/Analysis/FlowSensitive/MapLattice.h"
-#include "clang/Analysis/FlowSensitive/TestingSupport.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"

diff  --git a/clang/unittests/Analysis/FlowSensitive/SingleVarConstantPropagationTest.cpp b/clang/unittests/Analysis/FlowSensitive/SingleVarConstantPropagationTest.cpp
index 6d35f05b11866..e14724931a7c0 100644
--- a/clang/unittests/Analysis/FlowSensitive/SingleVarConstantPropagationTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/SingleVarConstantPropagationTest.cpp
@@ -12,6 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "TestingSupport.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
@@ -21,7 +22,6 @@
 #include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/DataflowLattice.h"
-#include "clang/Analysis/FlowSensitive/TestingSupport.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"

diff  --git a/clang/lib/Analysis/FlowSensitive/TestingSupport.cpp b/clang/unittests/Analysis/FlowSensitive/TestingSupport.cpp
similarity index 98%
rename from clang/lib/Analysis/FlowSensitive/TestingSupport.cpp
rename to clang/unittests/Analysis/FlowSensitive/TestingSupport.cpp
index 17c0189b2a915..4c5efa7504048 100644
--- a/clang/lib/Analysis/FlowSensitive/TestingSupport.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TestingSupport.cpp
@@ -1,4 +1,4 @@
-#include "clang/Analysis/FlowSensitive/TestingSupport.h"
+#include "TestingSupport.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Stmt.h"

diff  --git a/clang/include/clang/Analysis/FlowSensitive/TestingSupport.h b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h
similarity index 97%
rename from clang/include/clang/Analysis/FlowSensitive/TestingSupport.h
rename to clang/unittests/Analysis/FlowSensitive/TestingSupport.h
index 9878081934865..957d73fd6d0c4 100644
--- a/clang/include/clang/Analysis/FlowSensitive/TestingSupport.h
+++ b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h
@@ -10,8 +10,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef CLANG_ANALYSIS_FLOWSENSITIVE_TESTING_SUPPORT_H
-#define CLANG_ANALYSIS_FLOWSENSITIVE_TESTING_SUPPORT_H
+#ifndef LLVM_CLANG_ANALYSIS_FLOW_SENSITIVE_TESTING_SUPPORT_H_
+#define LLVM_CLANG_ANALYSIS_FLOW_SENSITIVE_TESTING_SUPPORT_H_
 
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
@@ -179,4 +179,4 @@ const ValueDecl *findValueDecl(ASTContext &ASTCtx, llvm::StringRef Name);
 } // namespace dataflow
 } // namespace clang
 
-#endif // CLANG_ANALYSIS_FLOWSENSITIVE_TESTING_SUPPORT_H
+#endif // LLVM_CLANG_ANALYSIS_FLOW_SENSITIVE_TESTING_SUPPORT_H_

diff  --git a/clang/unittests/Analysis/FlowSensitive/TestingSupportTest.cpp b/clang/unittests/Analysis/FlowSensitive/TestingSupportTest.cpp
index 8703273a5f394..960879025307f 100644
--- a/clang/unittests/Analysis/FlowSensitive/TestingSupportTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TestingSupportTest.cpp
@@ -1,4 +1,4 @@
-#include "clang/Analysis/FlowSensitive/TestingSupport.h"
+#include "TestingSupport.h"
 #include "NoopAnalysis.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"

diff  --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index 66ca0d0ccfa6e..49aaca9a7588c 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -7,13 +7,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "NoopAnalysis.h"
+#include "TestingSupport.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/StorageLocation.h"
-#include "clang/Analysis/FlowSensitive/TestingSupport.h"
 #include "clang/Analysis/FlowSensitive/Value.h"
 #include "clang/Basic/LangStandard.h"
 #include "llvm/ADT/ArrayRef.h"

diff  --git a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
index 06d8891ffcc61..f93b3fc2e8ed8 100644
--- a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "NoopAnalysis.h"
+#include "TestingSupport.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
@@ -16,7 +17,6 @@
 #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/DataflowLattice.h"
-#include "clang/Analysis/FlowSensitive/TestingSupport.h"
 #include "clang/Analysis/FlowSensitive/Value.h"
 #include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
 #include "clang/Tooling/Tooling.h"


        


More information about the cfe-commits mailing list