NoQ updated this revision to Diff 195810.
NoQ added a comment.
This revision is now accepted and ready to land.

Don't canonicalize the decl in the body farm. The decl supplied by the 
AnalysisDeclContext is already the correct one (and not necessarily the 
canonical one).

Keep the defensive behavior for NoStoreFuncVisitor because it's generally the 
right thing to do for future-proofness.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60808/new/

https://reviews.llvm.org/D60808

Files:
  clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
  clang/lib/Analysis/BodyFarm.cpp
  clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
  clang/test/Analysis/OSAtomic_mac.c

Index: clang/test/Analysis/OSAtomic_mac.c
===================================================================
--- /dev/null
+++ clang/test/Analysis/OSAtomic_mac.c
@@ -0,0 +1,27 @@
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,debug.ExprInspection\
+// RUN:                    -analyzer-output=text -verify %s
+
+int OSAtomicCompareAndSwapPtrBarrier(*, *, **);
+int OSAtomicCompareAndSwapPtrBarrier() {
+  // There is some body in the actual header,
+  // but we should trust our BodyFarm instead.
+}
+
+int *invalidSLocOnRedecl() {
+  // Was crashing when trying to throw a report about returning an uninitialized
+  // value to the caller. FIXME: We should probably still throw that report,
+  // something like "The "compare" part of CompareAndSwap depends on an
+  // undefined value".
+  int *b;
+  OSAtomicCompareAndSwapPtrBarrier(0, 0, &b); // no-crash
+  return b;
+}
+
+void testThatItActuallyWorks() {
+  void *x = 0;
+  int res = OSAtomicCompareAndSwapPtrBarrier(0, &x, &x);
+  clang_analyzer_eval(res); // expected-warning{{TRUE}}
+                            // expected-note@-1{{TRUE}}
+  clang_analyzer_eval(x == &x); // expected-warning{{TRUE}}
+                                // expected-note@-1{{TRUE}}
+}
Index: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -335,7 +335,7 @@
         if (RegionOfInterest->isSubRegionOf(SelfRegion) &&
             potentiallyWritesIntoIvar(Call->getRuntimeDefinition().getDecl(),
                                       IvarR->getDecl()))
-          return maybeEmitNode(R, *Call, N, {}, SelfRegion, "self",
+          return maybeEmitNote(R, *Call, N, {}, SelfRegion, "self",
                                /*FirstIsReferenceType=*/false, 1);
       }
     }
@@ -344,7 +344,7 @@
       const MemRegion *ThisR = CCall->getCXXThisVal().getAsRegion();
       if (RegionOfInterest->isSubRegionOf(ThisR)
           && !CCall->getDecl()->isImplicit())
-        return maybeEmitNode(R, *Call, N, {}, ThisR, "this",
+        return maybeEmitNote(R, *Call, N, {}, ThisR, "this",
                              /*FirstIsReferenceType=*/false, 1);
 
       // Do not generate diagnostics for not modified parameters in
@@ -363,7 +363,7 @@
       QualType T = PVD->getType();
       while (const MemRegion *MR = V.getAsRegion()) {
         if (RegionOfInterest->isSubRegionOf(MR) && !isPointerToConst(T))
-          return maybeEmitNode(R, *Call, N, {}, MR, ParamName,
+          return maybeEmitNote(R, *Call, N, {}, MR, ParamName,
                                ParamIsReferenceType, IndirectionLevel);
 
         QualType PT = T->getPointeeType();
@@ -371,7 +371,7 @@
 
         if (const RecordDecl *RD = PT->getAsRecordDecl())
           if (auto P = findRegionOfInterestInRecord(RD, State, MR))
-            return maybeEmitNode(R, *Call, N, *P, RegionOfInterest, ParamName,
+            return maybeEmitNote(R, *Call, N, *P, RegionOfInterest, ParamName,
                                  ParamIsReferenceType, IndirectionLevel);
 
         V = State->getSVal(MR, PT);
@@ -549,7 +549,7 @@
   /// \return Diagnostics piece for region not modified in the current function,
   /// if it decides to emit one.
   std::shared_ptr<PathDiagnosticPiece>
-  maybeEmitNode(BugReport &R, const CallEvent &Call, const ExplodedNode *N,
+  maybeEmitNote(BugReport &R, const CallEvent &Call, const ExplodedNode *N,
                 const RegionVector &FieldChain, const MemRegion *MatchedRegion,
                 StringRef FirstElement, bool FirstIsReferenceType,
                 unsigned IndirectionLevel) {
@@ -579,6 +579,11 @@
     PathDiagnosticLocation L =
         PathDiagnosticLocation::create(N->getLocation(), SM);
 
+    // For now this shouldn't trigger, but once it does, we'll need to decide
+    // if these reports are worth suppressing as well.
+    if (!L.hasValidLocation())
+      return nullptr;
+
     SmallString<256> sbuf;
     llvm::raw_svector_ostream os(sbuf);
     os << "Returning without writing to '";
Index: clang/lib/Analysis/BodyFarm.cpp
===================================================================
--- clang/lib/Analysis/BodyFarm.cpp
+++ clang/lib/Analysis/BodyFarm.cpp
@@ -665,8 +665,6 @@
 }
 
 Stmt *BodyFarm::getBody(const FunctionDecl *D) {
-  D = D->getCanonicalDecl();
-
   Optional<Stmt *> &Val = Bodies[D];
   if (Val.hasValue())
     return Val.getValue();
Index: clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -313,6 +313,8 @@
 
   bool hasRange() const { return K == StmtK || K == RangeK || K == DeclK; }
 
+  bool hasValidLocation() const { return asLocation().isValid(); }
+
   void invalidate() {
     *this = PathDiagnosticLocation();
   }
@@ -468,7 +470,7 @@
                           PathDiagnosticPiece::Kind k,
                           bool addPosRange = true)
       : PathDiagnosticPiece(s, k), Pos(pos) {
-    assert(Pos.isValid() && Pos.asLocation().isValid() &&
+    assert(Pos.isValid() && Pos.hasValidLocation() &&
            "PathDiagnosticSpotPiece's must have a valid location.");
     if (addPosRange && Pos.hasRange()) addRange(Pos.asRange());
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to