[PATCH] D142741: Fix ProgramState::isNull for non-region symbols

Christopher Bazley via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 27 08:54:12 PST 2023


chrisbazley created this revision.
Herald added subscribers: steakhal, martong.
Herald added a reviewer: NoQ.
Herald added a project: All.
chrisbazley requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This method was good at telling that a pointer
definitely is null, but bad at telling that it
definitely isn't null. For example, it returned
'not sure' in the following trivial case:

int main(void)
{

  int p;
  int _Optional *q = &p;
  if (q) {
    *q = 0; // spurious warning
  }
  return 0;

}

When analyzing the above program, the statement
if (q) does not create a constraint such as range
[1, 18446744073709551615] for use in future
inferences about the value of q. The reason is
that SimpleConstraintManager::assumeInternal
replaces the condition specified by its caller with
1 if invoked on a symbol (such as q) that lacks an
associated memory region. Constraints are not
recorded for integer constants.

Added fallback in ProgramState::isNull to do the same
conversion and check for a zero result if invoked
on an expression which is not a constant and does
not wrap a symbol (or wraps a symbol that lacks a
memory region).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D142741

Files:
  clang/lib/StaticAnalyzer/Core/ProgramState.cpp


Index: clang/lib/StaticAnalyzer/Core/ProgramState.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ clang/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -386,8 +386,24 @@
     return false;
 
   SymbolRef Sym = V.getAsSymbol(/* IncludeBaseRegion */ true);
-  if (!Sym)
+  if (!Sym) {
+    if (Optional<Loc> LV = V.getAs<Loc>()) {
+      SValBuilder &SVB = stateMgr->getSValBuilder();
+      QualType T;
+      const MemRegion *MR = LV->getAsRegion();
+      if (const TypedRegion *TR = dyn_cast_or_null<TypedRegion>(MR))
+        T = TR->getLocationType();
+      else
+        T = SVB.getContext().VoidPtrTy;
+
+      V = SVB.evalCast(*LV, SVB.getContext().BoolTy, T);
+      auto const integer = V.getAsInteger();
+      if (integer) {
+        return integer->isZero();
+      }
+    }
     return ConditionTruthVal();
+  }
 
   return getStateManager().ConstraintMgr->isNull(this, Sym);
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D142741.492789.patch
Type: text/x-patch
Size: 968 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230127/34f51c1e/attachment.bin>


More information about the cfe-commits mailing list