Skip to content

Commit 268e913

Browse files
committed
Aggressive Top skipping, first pass
1 parent 672223e commit 268e913

File tree

1 file changed

+66
-32
lines changed

1 file changed

+66
-32
lines changed

clang/lib/Analysis/FlowSensitive/Models/NullPointerAnalysisModel.cpp

Lines changed: 66 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,15 @@ enum class SatisfiabilityResult {
5959
Unknown
6060
};
6161

62+
enum class CompareResult {
63+
Same,
64+
Different,
65+
Top,
66+
Unknown
67+
};
68+
6269
using SR = SatisfiabilityResult;
70+
using CR = CompareResult;
6371

6472
// FIXME: These AST matchers should also be exported via the
6573
// NullPointerAnalysisModel class, for tests
@@ -228,7 +236,12 @@ void matchDereferenceExpr(const Stmt *stmt,
228236

229237
Value *RootValue = getValue(*Var, Env);
230238

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()));
232245
}
233246

234247
void matchNullCheckExpr(const Expr *NullCheck,
@@ -249,6 +262,11 @@ void matchNullCheckExpr(const Expr *NullCheck,
249262
Arena &A = Env.arena();
250263
BoolValue &IsNonnull = getVal(kIsNonnull, *RootValue);
251264
BoolValue &IsNull = getVal(kIsNull, *RootValue);
265+
266+
if (&IsNonnull == &Env.makeTopBoolValue() ||
267+
&IsNull == &Env.makeTopBoolValue())
268+
return;
269+
252270
BoolValue *CondValue = cast_or_null<BoolValue>(Env.getValue(*NullCheck));
253271
if (!CondValue) {
254272
CondValue = &A.makeAtomValue();
@@ -277,6 +295,17 @@ void matchEqualExpr(const BinaryOperator *EqualExpr,
277295
Value *LHSValue = getValue(*LHSVar, Env);
278296
Value *RHSValue = getValue(*RHSVar, Env);
279297

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+
280309
BoolValue *CondValue = cast_or_null<BoolValue>(Env.getValue(*EqualExpr));
281310
if (!CondValue) {
282311
CondValue = &A.makeAtomValue();
@@ -286,17 +315,15 @@ void matchEqualExpr(const BinaryOperator *EqualExpr,
286315
const Formula &CondFormula = IsNotEqualsOp ? A.makeNot(CondValue->formula())
287316
: CondValue->formula();
288317

318+
// FIXME: Simplify formulas
289319
// If the pointers are equal, the nullability properties are the same.
290320
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()))));
295323

296324
// If the pointers are not equal, at most one of the pointers is null.
297325
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()))));
300327
}
301328

302329
void matchNullptrExpr(const Expr *expr, const MatchFinder::MatchResult &Result,
@@ -307,6 +334,7 @@ void matchNullptrExpr(const Expr *expr, const MatchFinder::MatchResult &Result,
307334
Value *RootValue = Env.getValue(*PrVar);
308335
if (!RootValue) {
309336
RootValue = Env.createValue(PrVar->getType());
337+
assert(RootValue && "Failed to create nullptr value");
310338
Env.setValue(*PrVar, *RootValue);
311339
}
312340

@@ -348,7 +376,7 @@ void matchAnyPointerExpr(const Expr *fncall,
348376

349377
Value *RootValue = Env.createValue(Var->getType());
350378

351-
initializeRootValue(*RootValue, Env);
379+
// initializeRootValue(*RootValue, Env);
352380
setUnknownValue(*Var, *RootValue, Env);
353381
}
354382

@@ -539,7 +567,7 @@ void NullPointerAnalysisModel::join(QualType Type, const Value &Val1,
539567
auto *RHSVar = cast_or_null<BoolValue>(Val2.getProperty(Name));
540568

541569
if (LHSVar == RHSVar)
542-
return *LHSVar;
570+
return LHSVar ? *LHSVar : MergedEnv.makeAtomicBoolValue();
543571

544572
SatisfiabilityResult LHSResult = computeSatisfiability(LHSVar, Env1);
545573
SatisfiabilityResult RHSResult = computeSatisfiability(RHSVar, Env2);
@@ -588,37 +616,40 @@ ComparisonResult NullPointerAnalysisModel::compare(QualType Type,
588616
return ComparisonResult::Unknown;
589617

590618
// Evaluate values, but different values compare to Unknown.
591-
auto CompareValues = [&](llvm::StringRef Name) -> ComparisonResult {
619+
auto CompareValues = [&](llvm::StringRef Name) -> CR {
592620
auto *LHSVar = cast_or_null<BoolValue>(Val1.getProperty(Name));
593621
auto *RHSVar = cast_or_null<BoolValue>(Val2.getProperty(Name));
594622

595623
if (LHSVar == RHSVar)
596-
return ComparisonResult::Same;
624+
return (LHSVar == &Env1.makeTopBoolValue()) ? CR::Top : CR::Same;
597625

598626
SatisfiabilityResult LHSResult = computeSatisfiability(LHSVar, Env1);
599627
SatisfiabilityResult RHSResult = computeSatisfiability(RHSVar, Env2);
600628

601629
if (LHSResult == SR::Top || RHSResult == SR::Top)
602-
return ComparisonResult::Same;
630+
return CR::Top;
603631

604632
if (LHSResult == SR::Unknown || RHSResult == SR::Unknown)
605-
return ComparisonResult::Unknown;
633+
return CR::Unknown;
606634

607635
if (LHSResult == RHSResult)
608-
return ComparisonResult::Same;
636+
return CR::Same;
609637

610-
return ComparisonResult::Different;
638+
return CR::Different;
611639
};
612640

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;
615646

616-
if (NullComparison == ComparisonResult::Different ||
617-
NonnullComparison == ComparisonResult::Different)
647+
if (NullComparison == CR::Different ||
648+
NonnullComparison == CR::Different)
618649
return ComparisonResult::Different;
619650

620-
if (NullComparison == ComparisonResult::Unknown ||
621-
NonnullComparison == ComparisonResult::Unknown)
651+
if (NullComparison == CR::Unknown ||
652+
NonnullComparison == CR::Unknown)
622653
return ComparisonResult::Unknown;
623654

624655
return ComparisonResult::Same;
@@ -632,7 +663,7 @@ ComparisonResult compareAndReplace(QualType Type, Value &Val1,
632663
if (!Type->isAnyPointerType())
633664
return ComparisonResult::Unknown;
634665

635-
auto FastCompareValues = [&](llvm::StringRef Name) -> ComparisonResult {
666+
auto FastCompareValues = [&](llvm::StringRef Name) -> CR {
636667
auto *LHSVar = cast_or_null<BoolValue>(Val1.getProperty(Name));
637668
auto *RHSVar = cast_or_null<BoolValue>(Val2.getProperty(Name));
638669

@@ -641,28 +672,31 @@ ComparisonResult compareAndReplace(QualType Type, Value &Val1,
641672

642673
if (LHSResult == SR::Top || RHSResult == SR::Top) {
643674
Val2.setProperty(Name, Env2.makeTopBoolValue());
644-
return ComparisonResult::Same;
675+
return CR::Top;
645676
}
646677

647678
if (LHSResult == SR::Unknown || RHSResult == SR::Unknown)
648-
return ComparisonResult::Unknown;
679+
return CR::Unknown;
649680

650681
if (LHSResult == RHSResult)
651-
return ComparisonResult::Same;
682+
return CR::Same;
652683

653684
Val2.setProperty(Name, Env2.makeTopBoolValue());
654-
return ComparisonResult::Different;
685+
return CR::Different;
655686
};
656687

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;
659693

660-
if (NullComparison == ComparisonResult::Different ||
661-
NonnullComparison == ComparisonResult::Different)
694+
if (NullComparison == CR::Different ||
695+
NonnullComparison == CR::Different)
662696
return ComparisonResult::Different;
663697

664-
if (NullComparison == ComparisonResult::Unknown ||
665-
NonnullComparison == ComparisonResult::Unknown)
698+
if (NullComparison == CR::Unknown ||
699+
NonnullComparison == CR::Unknown)
666700
return ComparisonResult::Unknown;
667701

668702
return ComparisonResult::Same;

0 commit comments

Comments
 (0)