[cfe-commits] r162817 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp test/Analysis/temporaries.cpp

Jordan Rose jordan_rose at apple.com
Tue Aug 28 18:11:59 PDT 2012


Author: jrose
Date: Tue Aug 28 20:11:59 2012
New Revision: 162817

URL: http://llvm.org/viewvc/llvm-project?rev=162817&view=rev
Log:
[analyzer] C++ objects returned on the stack may be wrapped in ExprWithCleanups.

In C++, objects being returned on the stack are actually copy-constructed into
the return value. That means that when a temporary is returned, it still has
to be destroyed, i.e. the returned expression will be wrapped in an
ExprWithCleanups node. Our "returning stack memory" checker needs to look
through this node to see if we really are returning an object by value.

PR13722

Added:
    cfe/trunk/test/Analysis/temporaries.cpp
Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp?rev=162817&r1=162816&r2=162817&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp Tue Aug 28 20:11:59 2012
@@ -118,6 +118,7 @@
   const Expr *RetE = RS->getRetValue();
   if (!RetE)
     return;
+  RetE = RetE->IgnoreParens();
 
   const LocationContext *LCtx = C.getLocationContext();
   SVal V = C.getState()->getSVal(RetE, LCtx);
@@ -144,7 +145,10 @@
     return;
 
   // Returning a record by value is fine. (In this case, the returned
-  // expression will be a copy-constructor.)
+  // expression will be a copy-constructor, possibly wrapped in an
+  // ExprWithCleanups node.)
+  if (const ExprWithCleanups *Cleanup = dyn_cast<ExprWithCleanups>(RetE))
+    RetE = Cleanup->getSubExpr();
   if (isa<CXXConstructExpr>(RetE) && RetE->getType()->isRecordType())
     return;
 

Added: cfe/trunk/test/Analysis/temporaries.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temporaries.cpp?rev=162817&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/temporaries.cpp (added)
+++ cfe/trunk/test/Analysis/temporaries.cpp Tue Aug 28 20:11:59 2012
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify -w %s
+
+struct Trivial {
+  Trivial(int x) : value(x) {}
+  int value;
+};
+
+struct NonTrivial : public Trivial {
+  NonTrivial(int x) : Trivial(x) {}
+  ~NonTrivial();
+};
+
+
+Trivial getTrivial() {
+  return Trivial(42); // no-warning
+}
+
+const Trivial &getTrivialRef() {
+  return Trivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'struct Trivial' returned to caller}}
+}
+
+
+NonTrivial getNonTrivial() {
+  return NonTrivial(42); // no-warning
+}
+
+const NonTrivial &getNonTrivialRef() {
+  return NonTrivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'struct NonTrivial' returned to caller}}
+}
+





More information about the cfe-commits mailing list