r224271 - Handle errors in lambda prototype instantiation correctly

Reid Kleckner reid at kleckner.net
Mon Dec 15 13:07:16 PST 2014


Author: rnk
Date: Mon Dec 15 15:07:16 2014
New Revision: 224271

URL: http://llvm.org/viewvc/llvm-project?rev=224271&view=rev
Log:
Handle errors in lambda prototype instantiation correctly

Previously we would attempt to build a TypeSourceInfo for a null type,
and then we would forget to pop the function scope before returning an
error.

Reviewers: rsmith

Differential Revision: http://reviews.llvm.org/D6665

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaCXX/lambda-expressions.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=224271&r1=224270&r2=224271&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Dec 15 15:07:16 2014
@@ -3107,6 +3107,18 @@ public:
     Sema &S;
   };
 
+  /// An RAII helper that pops function a function scope on exit.
+  struct FunctionScopeRAII {
+    Sema &S;
+    bool Active;
+    FunctionScopeRAII(Sema &S) : Active(true), S(S) {}
+    ~FunctionScopeRAII() {
+      if (Active)
+        S.PopFunctionScopeInfo();
+    }
+    void disable() { Active = false; }
+  };
+
   StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
                                    SourceLocation StartLoc,
                                    SourceLocation EndLoc);

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=224271&r1=224270&r2=224271&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Dec 15 15:07:16 2014
@@ -9121,6 +9121,8 @@ TreeTransform<Derived>::TransformLambdaE
   }
 
   LambdaScopeInfo *LSI = getSema().PushLambdaScope();
+  Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
+
   // Transform the template parameters, and add them to the current
   // instantiation scope. The null case is handled correctly.
   LSI->GLTemplateParameterList = getDerived().TransformTemplateParameterList(
@@ -9145,10 +9147,10 @@ TreeTransform<Derived>::TransformLambdaE
           return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI,
                                               ExceptionStorage, Changed);
         });
+    if (NewCallOpType.isNull())
+      return ExprError();
     NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context,
                                                         NewCallOpType);
-    if (!NewCallOpTSI)
-      return ExprError();
   }
 
   // Create the local class that will describe the lambda.
@@ -9168,6 +9170,10 @@ TreeTransform<Derived>::TransformLambdaE
 
   getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
 
+  // TransformLambdaScope will manage the function scope, so we can disable the
+  // cleanup.
+  FuncScopeCleanup.disable();
+
   return getDerived().TransformLambdaScope(E, NewCallOperator, 
       InitCaptureExprsAndTypes);
 }

Modified: cfe/trunk/test/SemaCXX/lambda-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/lambda-expressions.cpp?rev=224271&r1=224270&r2=224271&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/lambda-expressions.cpp (original)
+++ cfe/trunk/test/SemaCXX/lambda-expressions.cpp Mon Dec 15 15:07:16 2014
@@ -425,3 +425,17 @@ namespace lambda_in_default_mem_init {
   }
   template void g<int>();
 }
+
+namespace error_in_transform_prototype {
+  template<class T>
+  void f(T t) {
+    // expected-error at +2 {{type 'int' cannot be used prior to '::' because it has no members}}
+    // expected-error at +1 {{no member named 'ns' in 'error_in_transform_prototype::S'}}
+    auto x = [](typename T::ns::type &k) {};
+  }
+  class S {};
+  void foo() {
+    f(5); // expected-note {{requested here}}
+    f(S()); // expected-note {{requested here}}
+  }
+}





More information about the cfe-commits mailing list