@@ -514,8 +514,17 @@ TEST_F(NoreturnDestructorTest, ConditionalOperatorNestedBranchReturns) {
514
514
class SpecialBoolAnalysis final
515
515
: public DataflowAnalysis<SpecialBoolAnalysis, NoopLattice> {
516
516
public:
517
- explicit SpecialBoolAnalysis (ASTContext &Context)
518
- : DataflowAnalysis<SpecialBoolAnalysis, NoopLattice>(Context) {}
517
+ explicit SpecialBoolAnalysis (ASTContext &Context, Environment &Env)
518
+ : DataflowAnalysis<SpecialBoolAnalysis, NoopLattice>(Context) {
519
+ Env.getDataflowAnalysisContext ().setSyntheticFieldCallback (
520
+ [](QualType Ty) -> llvm::StringMap<QualType> {
521
+ RecordDecl *RD = Ty->getAsRecordDecl ();
522
+ if (RD == nullptr || RD->getIdentifier () == nullptr ||
523
+ RD->getName () != " SpecialBool" )
524
+ return {};
525
+ return {{" is_set" , RD->getASTContext ().BoolTy }};
526
+ });
527
+ }
519
528
520
529
static NoopLattice initialElement () { return {}; }
521
530
@@ -530,67 +539,18 @@ class SpecialBoolAnalysis final
530
539
if (const auto *E = selectFirst<CXXConstructExpr>(
531
540
" call" , match (cxxConstructExpr (HasSpecialBoolType).bind (" call" ), *S,
532
541
getASTContext ()))) {
533
- cast<RecordValue> (Env.getValue (*E))
534
- -> setProperty ( " is_set " , Env.getBoolLiteralValue (false ));
542
+ Env. setValue (Env.getResultObjectLocation (*E). getSyntheticField ( " is_set " ),
543
+ Env.getBoolLiteralValue (false ));
535
544
} else if (const auto *E = selectFirst<CXXMemberCallExpr>(
536
545
" call" , match (cxxMemberCallExpr (callee (cxxMethodDecl (ofClass (
537
546
SpecialBoolRecordDecl))))
538
547
.bind (" call" ),
539
548
*S, getASTContext ()))) {
540
- auto &ObjectLoc =
541
- *cast<RecordStorageLocation>(getImplicitObjectLocation (*E, Env));
542
-
543
- refreshRecordValue (ObjectLoc, Env)
544
- .setProperty (" is_set" , Env.getBoolLiteralValue (true ));
549
+ if (RecordStorageLocation *ObjectLoc = getImplicitObjectLocation (*E, Env))
550
+ Env.setValue (ObjectLoc->getSyntheticField (" is_set" ),
551
+ Env.getBoolLiteralValue (true ));
545
552
}
546
553
}
547
-
548
- ComparisonResult compare (QualType Type, const Value &Val1,
549
- const Environment &Env1, const Value &Val2,
550
- const Environment &Env2) override {
551
- const auto *Decl = Type->getAsCXXRecordDecl ();
552
- if (Decl == nullptr || Decl->getIdentifier () == nullptr ||
553
- Decl->getName () != " SpecialBool" )
554
- return ComparisonResult::Unknown;
555
-
556
- auto *IsSet1 = cast_or_null<BoolValue>(Val1.getProperty (" is_set" ));
557
- auto *IsSet2 = cast_or_null<BoolValue>(Val2.getProperty (" is_set" ));
558
- if (IsSet1 == nullptr )
559
- return IsSet2 == nullptr ? ComparisonResult::Same
560
- : ComparisonResult::Different;
561
-
562
- if (IsSet2 == nullptr )
563
- return ComparisonResult::Different;
564
-
565
- return Env1.proves (IsSet1->formula ()) == Env2.proves (IsSet2->formula ())
566
- ? ComparisonResult::Same
567
- : ComparisonResult::Different;
568
- }
569
-
570
- // Always returns `true` to accept the `MergedVal`.
571
- bool merge (QualType Type, const Value &Val1, const Environment &Env1,
572
- const Value &Val2, const Environment &Env2, Value &MergedVal,
573
- Environment &MergedEnv) override {
574
- const auto *Decl = Type->getAsCXXRecordDecl ();
575
- if (Decl == nullptr || Decl->getIdentifier () == nullptr ||
576
- Decl->getName () != " SpecialBool" )
577
- return true ;
578
-
579
- auto *IsSet1 = cast_or_null<BoolValue>(Val1.getProperty (" is_set" ));
580
- if (IsSet1 == nullptr )
581
- return true ;
582
-
583
- auto *IsSet2 = cast_or_null<BoolValue>(Val2.getProperty (" is_set" ));
584
- if (IsSet2 == nullptr )
585
- return true ;
586
-
587
- auto &IsSet = MergedEnv.makeAtomicBoolValue ();
588
- MergedVal.setProperty (" is_set" , IsSet);
589
- if (Env1.proves (IsSet1->formula ()) && Env2.proves (IsSet2->formula ()))
590
- MergedEnv.assume (IsSet.formula ());
591
-
592
- return true ;
593
- }
594
554
};
595
555
596
556
class JoinFlowConditionsTest : public Test {
@@ -602,7 +562,7 @@ class JoinFlowConditionsTest : public Test {
602
562
AnalysisInputs<SpecialBoolAnalysis>(
603
563
Code, ast_matchers::hasName (" target" ),
604
564
[](ASTContext &Context, Environment &Env) {
605
- return SpecialBoolAnalysis (Context);
565
+ return SpecialBoolAnalysis (Context, Env );
606
566
})
607
567
.withASTBuildArgs ({" -fsyntax-only" , " -std=c++17" }),
608
568
/* VerifyResults=*/ [&Match](const llvm::StringMap<
@@ -650,7 +610,9 @@ TEST_F(JoinFlowConditionsTest, JoinDistinctButProvablyEquivalentValues) {
650
610
ASSERT_THAT (FooDecl, NotNull ());
651
611
652
612
auto GetFoo = [FooDecl](const Environment &Env) -> const Formula & {
653
- return cast<BoolValue>(Env.getValue (*FooDecl)->getProperty (" is_set" ))
613
+ auto *Loc =
614
+ cast<RecordStorageLocation>(Env.getStorageLocation (*FooDecl));
615
+ return cast<BoolValue>(Env.getValue (Loc->getSyntheticField (" is_set" )))
654
616
->formula ();
655
617
};
656
618
0 commit comments