[PATCH] Handle errors in lambda prototype instantiation correctly

Reid Kleckner rnk at google.com
Mon Dec 15 11:28:44 PST 2014


Hi rsmith,

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.

http://reviews.llvm.org/D6665

Files:
  include/clang/Sema/Sema.h
  lib/Sema/TreeTransform.h
  test/SemaCXX/lambda-expressions.cpp

Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -3101,6 +3101,18 @@
     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);
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -9121,6 +9121,8 @@
   }
 
   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 @@
           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 @@
 
   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);
 }
Index: test/SemaCXX/lambda-expressions.cpp
===================================================================
--- test/SemaCXX/lambda-expressions.cpp
+++ test/SemaCXX/lambda-expressions.cpp
@@ -425,3 +425,17 @@
   }
   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}}
+  }
+}

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D6665.17297.patch
Type: text/x-patch
Size: 2757 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20141215/556f9745/attachment.bin>


More information about the cfe-commits mailing list