[clang] [clang][dataflow] Convert `SpecialBoolAnalysis` to synthetic fields. (PR #74706)
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)
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)
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)
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