[llvm-branch-commits] [cfe-branch] r214742 - Merging r214050:

Bill Wendling isanbard at gmail.com
Mon Aug 4 11:19:14 PDT 2014


Author: void
Date: Mon Aug  4 13:19:14 2014
New Revision: 214742

URL: http://llvm.org/viewvc/llvm-project?rev=214742&view=rev
Log:
Merging r214050:
------------------------------------------------------------------------
r214050 | rsmith | 2014-07-26 22:12:49 -0700 (Sat, 26 Jul 2014) | 7 lines

When looking for temporary dtors while building the CFG, do not walk into
lambda expressions (other than their capture initializers) nor blocks. Do walk
into default argument expressions and default initializer expressions.

These bugs were causing us to produce broken CFGs whenever a lambda expression
was used to initialize a libstdc++ std::function object!

------------------------------------------------------------------------

Modified:
    cfe/branches/release_35/   (props changed)
    cfe/branches/release_35/include/clang/AST/ExprCXX.h
    cfe/branches/release_35/lib/Analysis/CFG.cpp
    cfe/branches/release_35/test/SemaCXX/return-noreturn.cpp

Propchange: cfe/branches/release_35/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Aug  4 13:19:14 2014
@@ -1,4 +1,4 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:213609,213611,213613,213741,213840,213902,213912,213993,213998,214008,214208,214471
+/cfe/trunk:213609,213611,213613,213741,213840,213902,213912,213993,213998,214008,214050,214208,214471
 /cfe/trunk/test:170344
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/release_35/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_35/include/clang/AST/ExprCXX.h?rev=214742&r1=214741&r2=214742&view=diff
==============================================================================
--- cfe/branches/release_35/include/clang/AST/ExprCXX.h (original)
+++ cfe/branches/release_35/include/clang/AST/ExprCXX.h Mon Aug  4 13:19:14 2014
@@ -1479,6 +1479,12 @@ public:
   /// arguments.
   typedef Expr **capture_init_iterator;
 
+  /// \brief Retrieve the initialization expressions for this lambda's captures.
+  llvm::iterator_range<capture_init_iterator> capture_inits() const {
+    return llvm::iterator_range<capture_init_iterator>(capture_init_begin(),
+                                                       capture_init_end());
+  }
+
   /// \brief Retrieve the first initialization argument for this
   /// lambda expression (which initializes the first capture field).
   capture_init_iterator capture_init_begin() const {

Modified: cfe/branches/release_35/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_35/lib/Analysis/CFG.cpp?rev=214742&r1=214741&r2=214742&view=diff
==============================================================================
--- cfe/branches/release_35/lib/Analysis/CFG.cpp (original)
+++ cfe/branches/release_35/lib/Analysis/CFG.cpp Mon Aug  4 13:19:14 2014
@@ -3495,10 +3495,35 @@ tryAgain:
     case Stmt::ParenExprClass:
       E = cast<ParenExpr>(E)->getSubExpr();
       goto tryAgain;
-      
+
     case Stmt::MaterializeTemporaryExprClass:
       E = cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr();
       goto tryAgain;
+
+    case Stmt::BlockExprClass:
+      // Don't recurse into blocks; their subexpressions don't get evaluated
+      // here.
+      return Block;
+
+    case Stmt::LambdaExprClass: {
+      // For lambda expressions, only recurse into the capture initializers,
+      // and not the body.
+      auto *LE = cast<LambdaExpr>(E);
+      CFGBlock *B = Block;
+      for (Expr *Init : LE->capture_inits()) {
+        if (CFGBlock *R = VisitForTemporaryDtors(Init))
+          B = R;
+      }
+      return B;
+    }
+
+    case Stmt::CXXDefaultArgExprClass:
+      E = cast<CXXDefaultArgExpr>(E)->getExpr();
+      goto tryAgain;
+
+    case Stmt::CXXDefaultInitExprClass:
+      E = cast<CXXDefaultInitExpr>(E)->getExpr();
+      goto tryAgain;
   }
 }
 

Modified: cfe/branches/release_35/test/SemaCXX/return-noreturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_35/test/SemaCXX/return-noreturn.cpp?rev=214742&r1=214741&r2=214742&view=diff
==============================================================================
--- cfe/branches/release_35/test/SemaCXX/return-noreturn.cpp (original)
+++ cfe/branches/release_35/test/SemaCXX/return-noreturn.cpp Mon Aug  4 13:19:14 2014
@@ -146,3 +146,25 @@ void PR9412_f() {
     PR9412_t<PR9412_Exact>(); // expected-note {{in instantiation of function template specialization 'PR9412_t<0>' requested here}}
 }
 
+#if __cplusplus >= 201103L
+namespace LambdaVsTemporaryDtor {
+  struct Y { ~Y(); };
+  struct X { template<typename T> X(T, Y = Y()) {} };
+
+  struct Fatal { ~Fatal() __attribute__((noreturn)); };
+  struct FatalCopy { FatalCopy(); FatalCopy(const FatalCopy&, Fatal F = Fatal()); };
+
+  void foo();
+
+  int bar() {
+    X work([](){ Fatal(); });
+    foo();
+  } // expected-warning {{control reaches end of non-void function}}
+
+  int baz() {
+    FatalCopy fc;
+    X work([fc](){});
+    foo();
+  } // ok, initialization of lambda does not return
+}
+#endif





More information about the llvm-branch-commits mailing list