[clang] [clang][dataflow] Convert `SpecialBoolAnalysis` to synthetic fields. (PR #74706)

2023-12-11 Thread via cfe-commits

https://github.com/martinboehme closed 
https://github.com/llvm/llvm-project/pull/74706
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][dataflow] Convert `SpecialBoolAnalysis` to synthetic fields. (PR #74706)

2023-12-08 Thread Gábor Horváth via cfe-commits

https://github.com/Xazax-hun approved this pull request.


https://github.com/llvm/llvm-project/pull/74706
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][dataflow] Convert `SpecialBoolAnalysis` to synthetic fields. (PR #74706)

2023-12-07 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (martinboehme)


Changes

We're working towards eliminating `RecordValue`; this eliminates one more
blocker on that path.


---
Full diff: https://github.com/llvm/llvm-project/pull/74706.diff


1 Files Affected:

- (modified) 
clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp 
(+20-58) 


``diff
diff --git 
a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
index f92afd8c3d84a..4c3cb322eacfb 100644
--- a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
@@ -514,8 +514,17 @@ TEST_F(NoreturnDestructorTest, 
ConditionalOperatorNestedBranchReturns) {
 class SpecialBoolAnalysis final
 : public DataflowAnalysis {
 public:
-  explicit SpecialBoolAnalysis(ASTContext )
-  : DataflowAnalysis(Context) {}
+  explicit SpecialBoolAnalysis(ASTContext , Environment )
+  : DataflowAnalysis(Context) {
+Env.getDataflowAnalysisContext().setSyntheticFieldCallback(
+[](QualType Ty) -> llvm::StringMap {
+  RecordDecl *RD = Ty->getAsRecordDecl();
+  if (RD == nullptr || RD->getIdentifier() == nullptr ||
+  RD->getName() != "SpecialBool")
+return {};
+  return {{"is_set", RD->getASTContext().BoolTy}};
+});
+  }
 
   static NoopLattice initialElement() { return {}; }
 
@@ -530,67 +539,18 @@ class SpecialBoolAnalysis final
 if (const auto *E = selectFirst(
 "call", match(cxxConstructExpr(HasSpecialBoolType).bind("call"), 
*S,
   getASTContext( {
-  cast(Env.getValue(*E))
-  ->setProperty("is_set", Env.getBoolLiteralValue(false));
+  Env.setValue(Env.getResultObjectLocation(*E).getSyntheticField("is_set"),
+   Env.getBoolLiteralValue(false));
 } else if (const auto *E = selectFirst(
"call", 
match(cxxMemberCallExpr(callee(cxxMethodDecl(ofClass(

SpecialBoolRecordDecl
  .bind("call"),
  *S, getASTContext( {
-  auto  =
-  *cast(getImplicitObjectLocation(*E, Env));
-
-  refreshRecordValue(ObjectLoc, Env)
-  .setProperty("is_set", Env.getBoolLiteralValue(true));
+  if (RecordStorageLocation *ObjectLoc = getImplicitObjectLocation(*E, 
Env))
+Env.setValue(ObjectLoc->getSyntheticField("is_set"),
+ Env.getBoolLiteralValue(true));
 }
   }
-
-  ComparisonResult compare(QualType Type, const Value ,
-   const Environment , const Value ,
-   const Environment ) override {
-const auto *Decl = Type->getAsCXXRecordDecl();
-if (Decl == nullptr || Decl->getIdentifier() == nullptr ||
-Decl->getName() != "SpecialBool")
-  return ComparisonResult::Unknown;
-
-auto *IsSet1 = cast_or_null(Val1.getProperty("is_set"));
-auto *IsSet2 = cast_or_null(Val2.getProperty("is_set"));
-if (IsSet1 == nullptr)
-  return IsSet2 == nullptr ? ComparisonResult::Same
-   : ComparisonResult::Different;
-
-if (IsSet2 == nullptr)
-  return ComparisonResult::Different;
-
-return Env1.proves(IsSet1->formula()) == Env2.proves(IsSet2->formula())
-   ? ComparisonResult::Same
-   : ComparisonResult::Different;
-  }
-
-  // Always returns `true` to accept the `MergedVal`.
-  bool merge(QualType Type, const Value , const Environment ,
- const Value , const Environment , Value ,
- Environment ) override {
-const auto *Decl = Type->getAsCXXRecordDecl();
-if (Decl == nullptr || Decl->getIdentifier() == nullptr ||
-Decl->getName() != "SpecialBool")
-  return true;
-
-auto *IsSet1 = cast_or_null(Val1.getProperty("is_set"));
-if (IsSet1 == nullptr)
-  return true;
-
-auto *IsSet2 = cast_or_null(Val2.getProperty("is_set"));
-if (IsSet2 == nullptr)
-  return true;
-
-auto  = MergedEnv.makeAtomicBoolValue();
-MergedVal.setProperty("is_set", IsSet);
-if (Env1.proves(IsSet1->formula()) && Env2.proves(IsSet2->formula()))
-  MergedEnv.assume(IsSet.formula());
-
-return true;
-  }
 };
 
 class JoinFlowConditionsTest : public Test {
@@ -602,7 +562,7 @@ class JoinFlowConditionsTest : public Test {
 AnalysisInputs(
 Code, ast_matchers::hasName("target"),
 [](ASTContext , Environment ) {
-  return SpecialBoolAnalysis(Context);
+  return SpecialBoolAnalysis(Context, Env);
 })
 .withASTBuildArgs({"-fsyntax-only", "-std=c++17"}),
 /*VerifyResults=*/[](const llvm::StringMap<
@@ -650,7 +610,9 @@ 

[clang] [clang][dataflow] Convert `SpecialBoolAnalysis` to synthetic fields. (PR #74706)

2023-12-07 Thread via cfe-commits

https://github.com/martinboehme created 
https://github.com/llvm/llvm-project/pull/74706

We're working towards eliminating `RecordValue`; this eliminates one more
blocker on that path.


>From 064a3b51400e158aeb074a1e6db8fbfd2b011949 Mon Sep 17 00:00:00 2001
From: Martin Braenne 
Date: Thu, 7 Dec 2023 09:48:15 +
Subject: [PATCH] [clang][dataflow] Convert `SpecialBoolAnalysis` to synthetic
 fields.

We're working towards eliminating `RecordValue`; this eliminates one more
blocker on that path.
---
 .../TypeErasedDataflowAnalysisTest.cpp| 78 +--
 1 file changed, 20 insertions(+), 58 deletions(-)

diff --git 
a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
index f92afd8c3d84a..4c3cb322eacfb 100644
--- a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp
@@ -514,8 +514,17 @@ TEST_F(NoreturnDestructorTest, 
ConditionalOperatorNestedBranchReturns) {
 class SpecialBoolAnalysis final
 : public DataflowAnalysis {
 public:
-  explicit SpecialBoolAnalysis(ASTContext )
-  : DataflowAnalysis(Context) {}
+  explicit SpecialBoolAnalysis(ASTContext , Environment )
+  : DataflowAnalysis(Context) {
+Env.getDataflowAnalysisContext().setSyntheticFieldCallback(
+[](QualType Ty) -> llvm::StringMap {
+  RecordDecl *RD = Ty->getAsRecordDecl();
+  if (RD == nullptr || RD->getIdentifier() == nullptr ||
+  RD->getName() != "SpecialBool")
+return {};
+  return {{"is_set", RD->getASTContext().BoolTy}};
+});
+  }
 
   static NoopLattice initialElement() { return {}; }
 
@@ -530,67 +539,18 @@ class SpecialBoolAnalysis final
 if (const auto *E = selectFirst(
 "call", match(cxxConstructExpr(HasSpecialBoolType).bind("call"), 
*S,
   getASTContext( {
-  cast(Env.getValue(*E))
-  ->setProperty("is_set", Env.getBoolLiteralValue(false));
+  Env.setValue(Env.getResultObjectLocation(*E).getSyntheticField("is_set"),
+   Env.getBoolLiteralValue(false));
 } else if (const auto *E = selectFirst(
"call", 
match(cxxMemberCallExpr(callee(cxxMethodDecl(ofClass(

SpecialBoolRecordDecl
  .bind("call"),
  *S, getASTContext( {
-  auto  =
-  *cast(getImplicitObjectLocation(*E, Env));
-
-  refreshRecordValue(ObjectLoc, Env)
-  .setProperty("is_set", Env.getBoolLiteralValue(true));
+  if (RecordStorageLocation *ObjectLoc = getImplicitObjectLocation(*E, 
Env))
+Env.setValue(ObjectLoc->getSyntheticField("is_set"),
+ Env.getBoolLiteralValue(true));
 }
   }
-
-  ComparisonResult compare(QualType Type, const Value ,
-   const Environment , const Value ,
-   const Environment ) override {
-const auto *Decl = Type->getAsCXXRecordDecl();
-if (Decl == nullptr || Decl->getIdentifier() == nullptr ||
-Decl->getName() != "SpecialBool")
-  return ComparisonResult::Unknown;
-
-auto *IsSet1 = cast_or_null(Val1.getProperty("is_set"));
-auto *IsSet2 = cast_or_null(Val2.getProperty("is_set"));
-if (IsSet1 == nullptr)
-  return IsSet2 == nullptr ? ComparisonResult::Same
-   : ComparisonResult::Different;
-
-if (IsSet2 == nullptr)
-  return ComparisonResult::Different;
-
-return Env1.proves(IsSet1->formula()) == Env2.proves(IsSet2->formula())
-   ? ComparisonResult::Same
-   : ComparisonResult::Different;
-  }
-
-  // Always returns `true` to accept the `MergedVal`.
-  bool merge(QualType Type, const Value , const Environment ,
- const Value , const Environment , Value ,
- Environment ) override {
-const auto *Decl = Type->getAsCXXRecordDecl();
-if (Decl == nullptr || Decl->getIdentifier() == nullptr ||
-Decl->getName() != "SpecialBool")
-  return true;
-
-auto *IsSet1 = cast_or_null(Val1.getProperty("is_set"));
-if (IsSet1 == nullptr)
-  return true;
-
-auto *IsSet2 = cast_or_null(Val2.getProperty("is_set"));
-if (IsSet2 == nullptr)
-  return true;
-
-auto  = MergedEnv.makeAtomicBoolValue();
-MergedVal.setProperty("is_set", IsSet);
-if (Env1.proves(IsSet1->formula()) && Env2.proves(IsSet2->formula()))
-  MergedEnv.assume(IsSet.formula());
-
-return true;
-  }
 };
 
 class JoinFlowConditionsTest : public Test {
@@ -602,7 +562,7 @@ class JoinFlowConditionsTest : public Test {
 AnalysisInputs(
 Code, ast_matchers::hasName("target"),
 [](ASTContext , Environment ) {
-  return