@@ -59,7 +59,15 @@ enum class SatisfiabilityResult {
59
59
Unknown
60
60
};
61
61
62
+ enum class CompareResult {
63
+ Same,
64
+ Different,
65
+ Top,
66
+ Unknown
67
+ };
68
+
62
69
using SR = SatisfiabilityResult;
70
+ using CR = CompareResult;
63
71
64
72
// FIXME: These AST matchers should also be exported via the
65
73
// NullPointerAnalysisModel class, for tests
@@ -228,7 +236,12 @@ void matchDereferenceExpr(const Stmt *stmt,
228
236
229
237
Value *RootValue = getValue (*Var, Env);
230
238
231
- Env.assume (Env.arena ().makeNot (getVal (kIsNull , *RootValue).formula ()));
239
+ BoolValue &IsNull = getVal (kIsNull , *RootValue);
240
+
241
+ if (&IsNull == &Env.makeTopBoolValue ())
242
+ return ;
243
+
244
+ Env.assume (Env.arena ().makeNot (IsNull.formula ()));
232
245
}
233
246
234
247
void matchNullCheckExpr (const Expr *NullCheck,
@@ -249,6 +262,11 @@ void matchNullCheckExpr(const Expr *NullCheck,
249
262
Arena &A = Env.arena ();
250
263
BoolValue &IsNonnull = getVal (kIsNonnull , *RootValue);
251
264
BoolValue &IsNull = getVal (kIsNull , *RootValue);
265
+
266
+ if (&IsNonnull == &Env.makeTopBoolValue () ||
267
+ &IsNull == &Env.makeTopBoolValue ())
268
+ return ;
269
+
252
270
BoolValue *CondValue = cast_or_null<BoolValue>(Env.getValue (*NullCheck));
253
271
if (!CondValue) {
254
272
CondValue = &A.makeAtomValue ();
@@ -277,6 +295,17 @@ void matchEqualExpr(const BinaryOperator *EqualExpr,
277
295
Value *LHSValue = getValue (*LHSVar, Env);
278
296
Value *RHSValue = getValue (*RHSVar, Env);
279
297
298
+ BoolValue &LHSNonnull = getVal (kIsNonnull , *LHSValue);
299
+ BoolValue &LHSNull = getVal (kIsNull , *LHSValue);
300
+ BoolValue &RHSNonnull = getVal (kIsNonnull , *RHSValue);
301
+ BoolValue &RHSNull = getVal (kIsNull , *RHSValue);
302
+
303
+ if (&LHSNonnull == &Env.makeTopBoolValue () ||
304
+ &RHSNonnull == &Env.makeTopBoolValue () ||
305
+ &LHSNull == &Env.makeTopBoolValue () ||
306
+ &RHSNull == &Env.makeTopBoolValue ())
307
+ return ;
308
+
280
309
BoolValue *CondValue = cast_or_null<BoolValue>(Env.getValue (*EqualExpr));
281
310
if (!CondValue) {
282
311
CondValue = &A.makeAtomValue ();
@@ -286,17 +315,15 @@ void matchEqualExpr(const BinaryOperator *EqualExpr,
286
315
const Formula &CondFormula = IsNotEqualsOp ? A.makeNot (CondValue->formula ())
287
316
: CondValue->formula ();
288
317
318
+ // FIXME: Simplify formulas
289
319
// If the pointers are equal, the nullability properties are the same.
290
320
Env.assume (A.makeImplies (CondFormula,
291
- A.makeAnd (A.makeEquals (getVal (kIsNull , *LHSValue).formula (),
292
- getVal (kIsNull , *RHSValue).formula ()),
293
- A.makeEquals (getVal (kIsNonnull , *LHSValue).formula (),
294
- getVal (kIsNonnull , *RHSValue).formula ()))));
321
+ A.makeAnd (A.makeEquals (LHSNull.formula (), RHSNull.formula ()),
322
+ A.makeEquals (LHSNonnull.formula (), RHSNonnull.formula ()))));
295
323
296
324
// If the pointers are not equal, at most one of the pointers is null.
297
325
Env.assume (A.makeImplies (A.makeNot (CondFormula),
298
- A.makeNot (A.makeAnd (getVal (kIsNull , *LHSValue).formula (),
299
- getVal (kIsNull , *RHSValue).formula ()))));
326
+ A.makeNot (A.makeAnd (LHSNull.formula (), RHSNull.formula ()))));
300
327
}
301
328
302
329
void matchNullptrExpr (const Expr *expr, const MatchFinder::MatchResult &Result,
@@ -307,6 +334,7 @@ void matchNullptrExpr(const Expr *expr, const MatchFinder::MatchResult &Result,
307
334
Value *RootValue = Env.getValue (*PrVar);
308
335
if (!RootValue) {
309
336
RootValue = Env.createValue (PrVar->getType ());
337
+ assert (RootValue && " Failed to create nullptr value" );
310
338
Env.setValue (*PrVar, *RootValue);
311
339
}
312
340
@@ -348,7 +376,7 @@ void matchAnyPointerExpr(const Expr *fncall,
348
376
349
377
Value *RootValue = Env.createValue (Var->getType ());
350
378
351
- initializeRootValue (*RootValue, Env);
379
+ // initializeRootValue(*RootValue, Env);
352
380
setUnknownValue (*Var, *RootValue, Env);
353
381
}
354
382
@@ -539,7 +567,7 @@ void NullPointerAnalysisModel::join(QualType Type, const Value &Val1,
539
567
auto *RHSVar = cast_or_null<BoolValue>(Val2.getProperty (Name));
540
568
541
569
if (LHSVar == RHSVar)
542
- return *LHSVar;
570
+ return LHSVar ? *LHSVar : MergedEnv. makeAtomicBoolValue () ;
543
571
544
572
SatisfiabilityResult LHSResult = computeSatisfiability (LHSVar, Env1);
545
573
SatisfiabilityResult RHSResult = computeSatisfiability (RHSVar, Env2);
@@ -588,37 +616,40 @@ ComparisonResult NullPointerAnalysisModel::compare(QualType Type,
588
616
return ComparisonResult::Unknown;
589
617
590
618
// Evaluate values, but different values compare to Unknown.
591
- auto CompareValues = [&](llvm::StringRef Name) -> ComparisonResult {
619
+ auto CompareValues = [&](llvm::StringRef Name) -> CR {
592
620
auto *LHSVar = cast_or_null<BoolValue>(Val1.getProperty (Name));
593
621
auto *RHSVar = cast_or_null<BoolValue>(Val2.getProperty (Name));
594
622
595
623
if (LHSVar == RHSVar)
596
- return ComparisonResult ::Same;
624
+ return (LHSVar == &Env1. makeTopBoolValue ()) ? CR::Top : CR ::Same;
597
625
598
626
SatisfiabilityResult LHSResult = computeSatisfiability (LHSVar, Env1);
599
627
SatisfiabilityResult RHSResult = computeSatisfiability (RHSVar, Env2);
600
628
601
629
if (LHSResult == SR::Top || RHSResult == SR::Top)
602
- return ComparisonResult::Same ;
630
+ return CR::Top ;
603
631
604
632
if (LHSResult == SR::Unknown || RHSResult == SR::Unknown)
605
- return ComparisonResult ::Unknown;
633
+ return CR ::Unknown;
606
634
607
635
if (LHSResult == RHSResult)
608
- return ComparisonResult ::Same;
636
+ return CR ::Same;
609
637
610
- return ComparisonResult ::Different;
638
+ return CR ::Different;
611
639
};
612
640
613
- ComparisonResult NullComparison = CompareValues (kIsNull );
614
- ComparisonResult NonnullComparison = CompareValues (kIsNonnull );
641
+ CR NullComparison = CompareValues (kIsNull );
642
+ CR NonnullComparison = CompareValues (kIsNonnull );
643
+
644
+ if (NullComparison == CR::Top || NonnullComparison == CR::Top)
645
+ return ComparisonResult::Same;
615
646
616
- if (NullComparison == ComparisonResult ::Different ||
617
- NonnullComparison == ComparisonResult ::Different)
647
+ if (NullComparison == CR ::Different ||
648
+ NonnullComparison == CR ::Different)
618
649
return ComparisonResult::Different;
619
650
620
- if (NullComparison == ComparisonResult ::Unknown ||
621
- NonnullComparison == ComparisonResult ::Unknown)
651
+ if (NullComparison == CR ::Unknown ||
652
+ NonnullComparison == CR ::Unknown)
622
653
return ComparisonResult::Unknown;
623
654
624
655
return ComparisonResult::Same;
@@ -632,7 +663,7 @@ ComparisonResult compareAndReplace(QualType Type, Value &Val1,
632
663
if (!Type->isAnyPointerType ())
633
664
return ComparisonResult::Unknown;
634
665
635
- auto FastCompareValues = [&](llvm::StringRef Name) -> ComparisonResult {
666
+ auto FastCompareValues = [&](llvm::StringRef Name) -> CR {
636
667
auto *LHSVar = cast_or_null<BoolValue>(Val1.getProperty (Name));
637
668
auto *RHSVar = cast_or_null<BoolValue>(Val2.getProperty (Name));
638
669
@@ -641,28 +672,31 @@ ComparisonResult compareAndReplace(QualType Type, Value &Val1,
641
672
642
673
if (LHSResult == SR::Top || RHSResult == SR::Top) {
643
674
Val2.setProperty (Name, Env2.makeTopBoolValue ());
644
- return ComparisonResult::Same ;
675
+ return CR::Top ;
645
676
}
646
677
647
678
if (LHSResult == SR::Unknown || RHSResult == SR::Unknown)
648
- return ComparisonResult ::Unknown;
679
+ return CR ::Unknown;
649
680
650
681
if (LHSResult == RHSResult)
651
- return ComparisonResult ::Same;
682
+ return CR ::Same;
652
683
653
684
Val2.setProperty (Name, Env2.makeTopBoolValue ());
654
- return ComparisonResult ::Different;
685
+ return CR ::Different;
655
686
};
656
687
657
- ComparisonResult NullComparison = FastCompareValues (kIsNull );
658
- ComparisonResult NonnullComparison = FastCompareValues (kIsNonnull );
688
+ CR NullComparison = FastCompareValues (kIsNull );
689
+ CR NonnullComparison = FastCompareValues (kIsNonnull );
690
+
691
+ if (NullComparison == CR::Top || NonnullComparison == CR::Top)
692
+ return ComparisonResult::Same;
659
693
660
- if (NullComparison == ComparisonResult ::Different ||
661
- NonnullComparison == ComparisonResult ::Different)
694
+ if (NullComparison == CR ::Different ||
695
+ NonnullComparison == CR ::Different)
662
696
return ComparisonResult::Different;
663
697
664
- if (NullComparison == ComparisonResult ::Unknown ||
665
- NonnullComparison == ComparisonResult ::Unknown)
698
+ if (NullComparison == CR ::Unknown ||
699
+ NonnullComparison == CR ::Unknown)
666
700
return ComparisonResult::Unknown;
667
701
668
702
return ComparisonResult::Same;
0 commit comments