[PATCH] D11832: [Patch] [Analyzer] false positive: Potential leak connected with memcpy (PR 22954)

Devin Coughlin via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 25 17:34:21 PDT 2015


dcoughlin added a comment.

Thanks for adding handling of the symbolic cases! Some more comments inline.


================
Comment at: lib/StaticAnalyzer/Checkers/CStringChecker.cpp:825
@@ -816,1 +824,3 @@
 
+ProgramStateRef CStringChecker::IsFirstBufInBound(CheckerContext &C,
+                                                  ProgramStateRef state,
----------------
It seems odd that you return a ProgramStateRef here but don't use it in the only caller of this function. Could you just return a boolean instead? Alternatively, if you really want to add the assumption that the buffer is valid to the post-state, then you should thread the state returned from the call to this function through the rest of CStringChecker::InvalidateBuffer.

================
Comment at: lib/StaticAnalyzer/Checkers/CStringChecker.cpp:840
@@ +839,3 @@
+  Optional<NonLoc> Length = LengthVal.getAs<NonLoc>();
+  if (!Length)
+    return state;
----------------
You have a lot of early returns of the form:

  if (!Foo)
    return state;

that don't seem to be exercised in your tests. Can these actually trigger? If so, you should add tests for these cases. If not, maybe asserts/cast<T>()/castAs<T>() would be more appropriate.

Also: should these early returns return state? Or should they return null?



================
Comment at: lib/StaticAnalyzer/Checkers/CStringChecker.cpp:851
@@ +850,3 @@
+  SVal BufStart = svalBuilder.evalCast(BufVal, PtrTy, FirstBuf->getType());
+  if (Optional<Loc> BufLoc = BufStart.getAs<Loc>()) {
+
----------------
Can you rewrite this if/else to avoid the indentation? (See http://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return).

================
Comment at: lib/StaticAnalyzer/Checkers/CStringChecker.cpp:866
@@ +865,3 @@
+    assert(ER->getValueType() == C.getASTContext().CharTy &&
+           "CheckLocation should only be called with char* ElementRegions");
+
----------------
"CheckLocation" is copy pasta here.

================
Comment at: lib/StaticAnalyzer/Core/RegionStore.cpp:1115
@@ +1114,3 @@
+      // or have a symbolic offset.
+      if (SuperR) {
+        if (const ClusterBindings *C = B.lookup(SuperR)) {
----------------
This nesting is getting pretty deep. Can you invert some guards and change to goto/continue where appropriate.

For example:
  if (!SuperR)
    goto conjure_default;

and

  const ClusterBindings *C = B.lookup(SuperR)
  if (!C)
    continue;

================
Comment at: lib/StaticAnalyzer/Core/RegionStore.cpp:1125
@@ +1124,3 @@
+                 ((*ROffset >= LowerOffset && *ROffset < UpperOffset) ||
+                  (LowerOffset == UpperOffset && *ROffset == LowerOffset)))) {
+              B = B.removeBinding(I.getKey());
----------------
Please add a comment here to say that this is to handle arrays of 0 elements and arrays of 0-sized elements.

================
Comment at: lib/StaticAnalyzer/Core/RegionStore.cpp:1132
@@ +1131,3 @@
+              if (R)
+                if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
+                  VisitBinding(V);
----------------
If you are not going to use the result, you can use isa<SymbolicRegion>(R) here instead of dyn_cast.

================
Comment at: test/Analysis/pr22954.c:476
@@ +475,3 @@
+  clang_analyzer_eval(m->s3[3] == 1); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(m->s3[i] == 1); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(l->s1[0] == 1); // expected-warning{{UNKNOWN}}
----------------
Should this test m->s3[j] as well?

================
Comment at: test/Analysis/pr22954.c:498
@@ +497,3 @@
+}
+
+
----------------
Can you also add a test where the size argument to memcpy is the result of sizeof()?


http://reviews.llvm.org/D11832





More information about the cfe-commits mailing list