@@ -211,6 +211,8 @@ void setUnknownValue(const Expr &E, Value &Val, Environment &Env) {
211
211
Env.setValue (E, Val);
212
212
}
213
213
214
+ // Gets a pointer's value, and initializes it to (Unknown, Unknown) if it hasn't
215
+ // been initialized already.
214
216
Value *getValue (const Expr &Var, Environment &Env) {
215
217
if (Value *EnvVal = Env.getValue (Var)) {
216
218
// FIXME: The framework usually creates the values for us, but without the
@@ -220,13 +222,20 @@ Value *getValue(const Expr &Var, Environment &Env) {
220
222
return EnvVal;
221
223
}
222
224
223
- Value *RootValue = Env. createValue (Var. getType ()) ;
225
+ return nullptr ;
224
226
225
- initializeRootValue (*RootValue, Env);
226
-
227
- setUnknownValue (Var, *RootValue, Env);
227
+ // Value *RootValue = Env.createValue(Var.getType());
228
+ //
229
+ // initializeRootValue(*RootValue, Env);
230
+ //
231
+ // setUnknownValue(Var, *RootValue, Env);
232
+ //
233
+ // return RootValue;
234
+ }
228
235
229
- return RootValue;
236
+ bool hasTopOrNullValue (const Value *Val, const Environment &Env) {
237
+ return !Val || isa_and_present<TopBoolValue>(Val->getProperty (kIsNull )) ||
238
+ isa_and_present<TopBoolValue>(Val->getProperty (kIsNonnull ));
230
239
}
231
240
232
241
void matchDereferenceExpr (const Stmt *stmt,
@@ -236,12 +245,11 @@ void matchDereferenceExpr(const Stmt *stmt,
236
245
assert (Var != nullptr );
237
246
238
247
Value *RootValue = getValue (*Var, Env);
248
+ if (hasTopOrNullValue (RootValue, Env))
249
+ return ;
239
250
240
251
BoolValue &IsNull = getVal (kIsNull , *RootValue);
241
252
242
- if (&IsNull == &Env.makeTopBoolValue ())
243
- return ;
244
-
245
253
Env.assume (Env.arena ().makeNot (IsNull.formula ()));
246
254
}
247
255
@@ -259,15 +267,13 @@ void matchNullCheckExpr(const Expr *NullCheck,
259
267
}
260
268
261
269
Value *RootValue = getValue (*Var, Env);
270
+ if (hasTopOrNullValue (RootValue, Env))
271
+ return ;
262
272
263
273
Arena &A = Env.arena ();
264
274
BoolValue &IsNonnull = getVal (kIsNonnull , *RootValue);
265
275
BoolValue &IsNull = getVal (kIsNull , *RootValue);
266
276
267
- if (&IsNonnull == &Env.makeTopBoolValue () ||
268
- &IsNull == &Env.makeTopBoolValue ())
269
- return ;
270
-
271
277
BoolValue *CondValue = cast_or_null<BoolValue>(Env.getValue (*NullCheck));
272
278
if (!CondValue) {
273
279
CondValue = &A.makeAtomValue ();
@@ -296,17 +302,14 @@ void matchEqualExpr(const BinaryOperator *EqualExpr,
296
302
Value *LHSValue = getValue (*LHSVar, Env);
297
303
Value *RHSValue = getValue (*RHSVar, Env);
298
304
305
+ if (hasTopOrNullValue (LHSValue, Env) || hasTopOrNullValue (RHSValue, Env))
306
+ return ;
307
+
299
308
BoolValue &LHSNonnull = getVal (kIsNonnull , *LHSValue);
300
309
BoolValue &LHSNull = getVal (kIsNull , *LHSValue);
301
310
BoolValue &RHSNonnull = getVal (kIsNonnull , *RHSValue);
302
311
BoolValue &RHSNull = getVal (kIsNull , *RHSValue);
303
312
304
- if (&LHSNonnull == &Env.makeTopBoolValue () ||
305
- &RHSNonnull == &Env.makeTopBoolValue () ||
306
- &LHSNull == &Env.makeTopBoolValue () ||
307
- &RHSNull == &Env.makeTopBoolValue ())
308
- return ;
309
-
310
313
BoolValue *CondValue = cast_or_null<BoolValue>(Env.getValue (*EqualExpr));
311
314
if (!CondValue) {
312
315
CondValue = &A.makeAtomValue ();
@@ -349,6 +352,7 @@ void matchAddressofExpr(const Expr *expr,
349
352
const auto *Var = Result.Nodes .getNodeAs <Expr>(kVar );
350
353
assert (Var != nullptr );
351
354
355
+ // FIXME: Use atoms or export to separate function
352
356
Value *RootValue = Env.getValue (*Var);
353
357
if (!RootValue) {
354
358
RootValue = Env.createValue (Var->getType ());
@@ -397,7 +401,8 @@ void matchPtrArgFunctionExpr(const CallExpr *fncall,
397
401
}
398
402
}
399
403
400
- if (fncall->getCallReturnType (*Result.Context )->isPointerType ()) {
404
+ if (fncall->getCallReturnType (*Result.Context )->isPointerType () &&
405
+ !Env.getValue (*fncall)) {
401
406
Value *RootValue = Env.createValue (
402
407
fncall->getCallReturnType (*Result.Context ));
403
408
if (!RootValue)
@@ -415,13 +420,15 @@ void matchAnyPointerExpr(const Expr *fncall,
415
420
const auto *Var = Result.Nodes .getNodeAs <Expr>(kVar );
416
421
assert (Var != nullptr );
417
422
418
- // Initialize to (Unknown, Unknown)
423
+ // In some cases, prvalues are not automatically initialized
424
+ // Initialize these values, but don't set null-ness values for performance
419
425
if (Env.getValue (*Var))
420
426
return ;
421
427
422
428
Value *RootValue = Env.createValue (Var->getType ());
429
+ if (!RootValue)
430
+ return ;
423
431
424
- // initializeRootValue(*RootValue, Env);
425
432
setUnknownValue (*Var, *RootValue, Env);
426
433
}
427
434
@@ -527,12 +534,14 @@ diagnoseEqualExpr(const Expr *PtrCheck, const MatchFinder::MatchResult &Result,
527
534
std::vector<SourceLocation> NullVarLocations;
528
535
529
536
if (Value *LHSValue = Env.getValue (*LHSVar);
537
+ LHSValue->getProperty (kIsNonnull ) &&
530
538
Env.proves (A.makeNot (getVal (kIsNonnull , *LHSValue).formula ()))) {
531
539
WarningLocToVal.try_emplace (LHSVar->getBeginLoc (), LHSValue);
532
540
NullVarLocations.push_back (LHSVar->getBeginLoc ());
533
541
}
534
542
535
543
if (Value *RHSValue = Env.getValue (*RHSVar);
544
+ RHSValue->getProperty (kIsNonnull ) &&
536
545
Env.proves (A.makeNot (getVal (kIsNonnull , *RHSValue).formula ()))) {
537
546
WarningLocToVal.try_emplace (RHSVar->getBeginLoc (), RHSValue);
538
547
NullVarLocations.push_back (RHSVar->getBeginLoc ());
@@ -647,8 +656,7 @@ void NullPointerAnalysisModel::join(QualType Type, const Value &Val1,
647
656
BoolValue &NonnullValue = MergeValues (kIsNonnull );
648
657
BoolValue &NullValue = MergeValues (kIsNull );
649
658
650
- if (&NonnullValue == &MergedEnv.makeTopBoolValue () ||
651
- &NullValue == &MergedEnv.makeTopBoolValue ()) {
659
+ if (isa<TopBoolValue>(NonnullValue) || isa<TopBoolValue>(NullValue)) {
652
660
MergedVal.setProperty (kIsNonnull , MergedEnv.makeTopBoolValue ());
653
661
MergedVal.setProperty (kIsNull , MergedEnv.makeTopBoolValue ());
654
662
} else {
@@ -673,8 +681,12 @@ ComparisonResult NullPointerAnalysisModel::compare(QualType Type,
673
681
auto *LHSVar = cast_or_null<BoolValue>(Val1.getProperty (Name));
674
682
auto *RHSVar = cast_or_null<BoolValue>(Val2.getProperty (Name));
675
683
684
+ if (isa_and_present<TopBoolValue>(LHSVar) ||
685
+ isa_and_present<TopBoolValue>(RHSVar))
686
+ return CR::Top;
687
+
676
688
if (LHSVar == RHSVar)
677
- return (LHSVar == &Env1. makeTopBoolValue ()) ? CR::Top : CR::Same;
689
+ return CR::Same;
678
690
679
691
SatisfiabilityResult LHSResult = computeSatisfiability (LHSVar, Env1);
680
692
SatisfiabilityResult RHSResult = computeSatisfiability (RHSVar, Env2);
0 commit comments