r338935 - [analyzer] Do not crash in NoStoreFuncVisitor notes if an unexpected region is found.

George Karpenkov via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 3 16:19:08 PDT 2018


Author: george.karpenkov
Date: Fri Aug  3 16:19:07 2018
New Revision: 338935

URL: http://llvm.org/viewvc/llvm-project?rev=338935&view=rev
Log:
[analyzer] Do not crash in NoStoreFuncVisitor notes if an unexpected region is found.

Just do not generate the note at all in that case.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
    cfe/trunk/test/Analysis/diagnostics/no-store-func-path-notes.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=338935&r1=338934&r2=338935&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Fri Aug  3 16:19:07 2018
@@ -351,10 +351,7 @@ public:
 
     ArrayRef<ParmVarDecl *> parameters = getCallParameters(Call);
     for (unsigned I = 0; I < Call->getNumArgs() && I < parameters.size(); ++I) {
-      Optional<unsigned> AdjustedIdx = Call->getAdjustedParameterIndex(I);
-      if (!AdjustedIdx)
-        continue;
-      const ParmVarDecl *PVD = parameters[*AdjustedIdx];
+      const ParmVarDecl *PVD = parameters[I];
       SVal S = Call->getArgSVal(I);
       bool ParamIsReferenceType = PVD->getType()->isReferenceType();
       std::string ParamName = PVD->getNameAsString();
@@ -565,15 +562,19 @@ private:
     SmallString<256> sbuf;
     llvm::raw_svector_ostream os(sbuf);
     os << "Returning without writing to '";
-    prettyPrintRegionName(FirstElement, FirstIsReferenceType, MatchedRegion,
-                          FieldChain, IndirectionLevel, os);
+
+    // Do not generate the note if failed to pretty-print.
+    if (!prettyPrintRegionName(FirstElement, FirstIsReferenceType,
+                               MatchedRegion, FieldChain, IndirectionLevel, os))
+      return nullptr;
 
     os << "'";
     return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
   }
 
   /// Pretty-print region \p MatchedRegion to \p os.
-  void prettyPrintRegionName(StringRef FirstElement, bool FirstIsReferenceType,
+  /// \return Whether printing succeeded.
+  bool prettyPrintRegionName(StringRef FirstElement, bool FirstIsReferenceType,
                              const MemRegion *MatchedRegion,
                              const RegionVector &FieldChain,
                              int IndirectionLevel,
@@ -598,6 +599,7 @@ private:
     for (const MemRegion *R : RegionSequence) {
 
       // Just keep going up to the base region.
+      // Element regions may appear due to casts.
       if (isa<CXXBaseObjectRegion>(R) || isa<CXXTempObjectRegion>(R))
         continue;
 
@@ -608,6 +610,10 @@ private:
 
       os << Sep;
 
+      // Can only reasonably pretty-print DeclRegions.
+      if (!isa<DeclRegion>(R))
+        return false;
+
       const auto *DR = cast<DeclRegion>(R);
       Sep = DR->getValueType()->isAnyPointerType() ? "->" : ".";
       DR->getDecl()->getDeclName().print(os, PP);
@@ -617,6 +623,7 @@ private:
       prettyPrintFirstElement(FirstElement,
                               /*MoreItemsExpected=*/false, IndirectionLevel,
                               os);
+    return true;
   }
 
   /// Print first item in the chain, return new separator.

Modified: cfe/trunk/test/Analysis/diagnostics/no-store-func-path-notes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/no-store-func-path-notes.cpp?rev=338935&r1=338934&r2=338935&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/diagnostics/no-store-func-path-notes.cpp (original)
+++ cfe/trunk/test/Analysis/diagnostics/no-store-func-path-notes.cpp Fri Aug  3 16:19:07 2018
@@ -333,3 +333,27 @@ int useMaybeInitializeIndirectlyWithPoin
   return z; // expected-warning{{Undefined or garbage value returned to caller}}
             // expected-note at -1{{Undefined or garbage value returned to caller}}
 }
+
+////////
+
+struct HasFieldA {
+  int x;
+};
+
+struct HasFieldB {
+  int x;
+};
+
+void maybeInitializeHasField(HasFieldA *b) {
+  if (coin()) // expected-note{{Assuming the condition is false}}
+              // expected-note at -1{{Taking false branch}}
+    ((HasFieldB*)b)->x = 120;
+}
+
+int forceElementRegionApperence() {
+  HasFieldA a;
+  maybeInitializeHasField(&a); // expected-note{{Calling 'maybeInitializeHasField'}}
+                               // expected-note at -1{{Returning from 'maybeInitializeHasField'}}
+  return ((HasFieldB*)&a)->x; // expected-warning{{Undefined or garbage value returned to caller}}
+                              // expected-note at -1{{Undefined or garbage value returned to caller}}
+}




More information about the cfe-commits mailing list