r242132 - Classes inside lambdas are local not nested.

Serge Pavlov sepavloff at gmail.com
Tue Jul 14 03:02:10 PDT 2015


Author: sepavloff
Date: Tue Jul 14 05:02:10 2015
New Revision: 242132

URL: http://llvm.org/viewvc/llvm-project?rev=242132&view=rev
Log:
Classes inside lambdas are local not nested.

If a lambda used as default argument in a method declaration contained
a local class, that class was incorrectly recognized as nested class.
In this case compiler tried to postpone parsing of this class until
the enclosing class is finished, which caused crashes in some cases.

This change fixes PR13987.

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

Modified:
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp
    cfe/trunk/test/SemaCXX/lambda-expressions.cpp

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=242132&r1=242131&r2=242132&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Jul 14 05:02:10 2015
@@ -2815,16 +2815,10 @@ void Parser::ParseCXXMemberSpecification
         break;
       }
 
-      if ((S->getFlags() & Scope::FnScope)) {
-        // If we're in a function or function template declared in the
-        // body of a class, then this is a local class rather than a
-        // nested class.
-        const Scope *Parent = S->getParent();
-        if (Parent->isTemplateParamScope())
-          Parent = Parent->getParent();
-        if (Parent->isClassScope())
-          break;
-      }
+      if ((S->getFlags() & Scope::FnScope))
+        // If we're in a function or function template then this is a local
+        // class rather than a nested class.
+        break;
     }
   }
 

Modified: cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp?rev=242132&r1=242131&r2=242132&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-generic-lambdas.cpp Tue Jul 14 05:02:10 2015
@@ -948,3 +948,41 @@ auto f(T x) {
 
 auto x = f(0)();
 }
+
+namespace PR13987 {
+class Enclosing {
+  void Method(char c = []()->char {
+    int d = [](auto x)->int {
+        struct LocalClass {
+          int Method() { return 0; }
+        };
+      return 0;
+    }(0);
+    return d; }()
+  );
+};
+
+class Enclosing2 {
+  void Method(char c = [](auto x)->char {
+    int d = []()->int {
+        struct LocalClass {
+          int Method() { return 0; }
+        };
+      return 0;
+    }();
+    return d; }(0)
+  );
+};
+
+class Enclosing3 {
+  void Method(char c = [](auto x)->char {
+    int d = [](auto y)->int {
+        struct LocalClass {
+          int Method() { return 0; }
+        };
+      return 0;
+    }(0);
+    return d; }(0)
+  );
+};
+}

Modified: cfe/trunk/test/SemaCXX/lambda-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/lambda-expressions.cpp?rev=242132&r1=242131&r2=242132&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/lambda-expressions.cpp (original)
+++ cfe/trunk/test/SemaCXX/lambda-expressions.cpp Tue Jul 14 05:02:10 2015
@@ -446,3 +446,33 @@ namespace PR21857 {
   template<typename Fn> fun<Fn> wrap(Fn fn);
   auto x = wrap([](){});
 }
+
+namespace PR13987 {
+class Enclosing {
+  void Method(char c = []()->char {
+    int d = []()->int {
+        struct LocalClass {
+          int Method() { return 0; }
+        };
+      return 0;
+    }();
+    return d; }()
+  );
+};
+}
+
+namespace PR23860 {
+template <class> struct A {
+  void f(int x = []() {
+    struct B {
+      void g() {}
+    };
+    return 0;
+  }());
+};
+
+int main() {
+}
+
+A<int> a;
+}





More information about the cfe-commits mailing list