[cfe-commits] r164586 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/Sema.cpp lib/Sema/SemaOverload.cpp test/SemaCXX/trailing-return-0x.cpp

Richard Smith richard-llvm at metafoo.co.uk
Mon Sep 24 21:46:06 PDT 2012


Author: rsmith
Date: Mon Sep 24 23:46:05 2012
New Revision: 164586

URL: http://llvm.org/viewvc/llvm-project?rev=164586&view=rev
Log:
Fix crash when a decltype expression in a trailing return type refers to the
function being instantiated. An error recovery codepath was recursively
performing name lookup (and triggering an unbounded stack of template
instantiations which blew out the stack before hitting the depth limit).

Patch by Wei Pan!

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/SemaCXX/trailing-return-0x.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=164586&r1=164585&r2=164586&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Sep 24 23:46:05 2012
@@ -234,6 +234,12 @@
   /// VisContext - Manages the stack for \#pragma GCC visibility.
   void *VisContext; // Really a "PragmaVisStack*"
 
+  /// \brief Flag indicating if Sema is building a recovery call expression.
+  ///
+  /// This flag is used to avoid building recovery call expressions
+  /// if Sema is already doing so, which would cause infinite recursions.
+  bool IsBuildingRecoveryCallExpr;
+
   /// ExprNeedsCleanups - True if the current evaluation context
   /// requires cleanups to be run at its conclusion.
   bool ExprNeedsCleanups;

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=164586&r1=164585&r2=164586&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Mon Sep 24 23:46:05 2012
@@ -90,6 +90,7 @@
     CollectStats(false), ExternalSource(0), CodeCompleter(CodeCompleter),
     CurContext(0), OriginalLexicalContext(0),
     PackContext(0), MSStructPragmaOn(false), VisContext(0),
+    IsBuildingRecoveryCallExpr(false),
     ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0),
     IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
     NSNumberDecl(0),

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=164586&r1=164585&r2=164586&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Sep 24 23:46:05 2012
@@ -9655,6 +9655,20 @@
     return false;
   }
 };
+
+class BuildRecoveryCallExprRAII {
+  Sema &SemaRef;
+public:
+  BuildRecoveryCallExprRAII(Sema &S) : SemaRef(S) {
+    assert(SemaRef.IsBuildingRecoveryCallExpr == false);
+    SemaRef.IsBuildingRecoveryCallExpr = true;
+  }
+
+  ~BuildRecoveryCallExprRAII() {
+    SemaRef.IsBuildingRecoveryCallExpr = false;
+  }
+};
+
 }
 
 /// Attempts to recover from a call where no functions were found.
@@ -9667,6 +9681,15 @@
                       llvm::MutableArrayRef<Expr *> Args,
                       SourceLocation RParenLoc,
                       bool EmptyLookup, bool AllowTypoCorrection) {
+  // Do not try to recover if it is already building a recovery call.
+  // This stops infinite loops for template instantiations like
+  //
+  // template <typename T> auto foo(T t) -> decltype(foo(t)) {}
+  // template <typename T> auto foo(T t) -> decltype(foo(&t)) {}
+  //
+  if (SemaRef.IsBuildingRecoveryCallExpr)
+    return ExprError();
+  BuildRecoveryCallExprRAII RCE(SemaRef);
 
   CXXScopeSpec SS;
   SS.Adopt(ULE->getQualifierLoc());

Modified: cfe/trunk/test/SemaCXX/trailing-return-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/trailing-return-0x.cpp?rev=164586&r1=164585&r2=164586&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/trailing-return-0x.cpp (original)
+++ cfe/trunk/test/SemaCXX/trailing-return-0x.cpp Mon Sep 24 23:46:05 2012
@@ -69,3 +69,19 @@
 only<int> p2 = xx.f(0L);
 only<double> p3 = xx.g(0L, 1.0);
 only<double> p4 = xx.get_nested<double>().h(0L, 1.0, 3.14f);
+
+namespace PR12053 {
+  template <typename T>
+  auto f1(T t) -> decltype(f1(t)) {} // expected-note{{candidate template ignored}}
+  
+  void test_f1() {
+    f1(0); // expected-error{{no matching function for call to 'f1'}}
+  }
+  
+  template <typename T>
+  auto f2(T t) -> decltype(f2(&t)) {} // expected-note{{candidate template ignored}}
+  
+  void test_f2() {
+    f2(0); // expected-error{{no matching function for call to 'f2'}}
+  }
+}





More information about the cfe-commits mailing list