This revision was automatically updated to reflect the committed changes.
Closed by commit rL326926: Push a function scope when parsing function bodies 
without a declaration (authored by rnk, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D43980?vs=136635&id=137436#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43980

Files:
  cfe/trunk/lib/Sema/SemaDecl.cpp
  cfe/trunk/test/SemaCXX/pr36536.cpp


Index: cfe/trunk/test/SemaCXX/pr36536.cpp
===================================================================
--- cfe/trunk/test/SemaCXX/pr36536.cpp
+++ cfe/trunk/test/SemaCXX/pr36536.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -std=c++11 %s -verify -fno-spell-checking
+
+// These test cases are constructed to make clang call ActOnStartOfFunctionDef
+// with nullptr.
+
+struct ImplicitDefaultCtor1 {};
+struct Foo {
+  typedef int NameInClass;
+  void f();
+};
+namespace bar {
+// FIXME: Improved our recovery to make this a redeclaration of Foo::f,
+// even though this is in the wrong namespace. That will allow name lookup to
+// find NameInClass below. Users are likely to hit this when they forget to
+// close namespaces.
+// expected-error@+1 {{cannot define or redeclare 'f' here}}
+void Foo::f() {
+  switch (0) { case 0: ImplicitDefaultCtor1 o; }
+  // expected-error@+1 {{unknown type name 'NameInClass'}}
+  NameInClass var;
+}
+} // namespace bar
+
+struct ImplicitDefaultCtor2 {};
+template <typename T> class TFoo { void f(); };
+// expected-error@+1 {{nested name specifier 'decltype(TFoo<T>())::'}}
+template <typename T> void decltype(TFoo<T>())::f() {
+  switch (0) { case 0: ImplicitDefaultCtor1 o; }
+}
+
+namespace tpl2 {
+struct ImplicitDefaultCtor3 {};
+template <class T1> class A {
+  template <class T2> class B {
+    void mf2();
+  };
+};
+template <class Y>
+template <>
+// expected-error@+1 {{nested name specifier 'A<Y>::B<double>::'}}
+void A<Y>::B<double>::mf2() {
+  switch (0) { case 0: ImplicitDefaultCtor3 o; }
+}
+}
Index: cfe/trunk/lib/Sema/SemaDecl.cpp
===================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp
+++ cfe/trunk/lib/Sema/SemaDecl.cpp
@@ -12406,8 +12406,13 @@
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
                                     SkipBodyInfo *SkipBody) {
-  if (!D)
+  if (!D) {
+    // Parsing the function declaration failed in some way. Push on a fake 
scope
+    // anyway so we can try to parse the function body.
+    PushFunctionScope();
     return D;
+  }
+
   FunctionDecl *FD = nullptr;
 
   if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
@@ -12816,6 +12821,9 @@
       getCurFunction()->ObjCWarnForNoInitDelegation = false;
     }
   } else {
+    // Parsing the function declaration failed in some way. Pop the fake scope
+    // we pushed on.
+    PopFunctionScopeInfo(ActivePolicy, dcl);
     return nullptr;
   }
 


Index: cfe/trunk/test/SemaCXX/pr36536.cpp
===================================================================
--- cfe/trunk/test/SemaCXX/pr36536.cpp
+++ cfe/trunk/test/SemaCXX/pr36536.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -std=c++11 %s -verify -fno-spell-checking
+
+// These test cases are constructed to make clang call ActOnStartOfFunctionDef
+// with nullptr.
+
+struct ImplicitDefaultCtor1 {};
+struct Foo {
+  typedef int NameInClass;
+  void f();
+};
+namespace bar {
+// FIXME: Improved our recovery to make this a redeclaration of Foo::f,
+// even though this is in the wrong namespace. That will allow name lookup to
+// find NameInClass below. Users are likely to hit this when they forget to
+// close namespaces.
+// expected-error@+1 {{cannot define or redeclare 'f' here}}
+void Foo::f() {
+  switch (0) { case 0: ImplicitDefaultCtor1 o; }
+  // expected-error@+1 {{unknown type name 'NameInClass'}}
+  NameInClass var;
+}
+} // namespace bar
+
+struct ImplicitDefaultCtor2 {};
+template <typename T> class TFoo { void f(); };
+// expected-error@+1 {{nested name specifier 'decltype(TFoo<T>())::'}}
+template <typename T> void decltype(TFoo<T>())::f() {
+  switch (0) { case 0: ImplicitDefaultCtor1 o; }
+}
+
+namespace tpl2 {
+struct ImplicitDefaultCtor3 {};
+template <class T1> class A {
+  template <class T2> class B {
+    void mf2();
+  };
+};
+template <class Y>
+template <>
+// expected-error@+1 {{nested name specifier 'A<Y>::B<double>::'}}
+void A<Y>::B<double>::mf2() {
+  switch (0) { case 0: ImplicitDefaultCtor3 o; }
+}
+}
Index: cfe/trunk/lib/Sema/SemaDecl.cpp
===================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp
+++ cfe/trunk/lib/Sema/SemaDecl.cpp
@@ -12406,8 +12406,13 @@
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
                                     SkipBodyInfo *SkipBody) {
-  if (!D)
+  if (!D) {
+    // Parsing the function declaration failed in some way. Push on a fake scope
+    // anyway so we can try to parse the function body.
+    PushFunctionScope();
     return D;
+  }
+
   FunctionDecl *FD = nullptr;
 
   if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
@@ -12816,6 +12821,9 @@
       getCurFunction()->ObjCWarnForNoInitDelegation = false;
     }
   } else {
+    // Parsing the function declaration failed in some way. Pop the fake scope
+    // we pushed on.
+    PopFunctionScopeInfo(ActivePolicy, dcl);
     return nullptr;
   }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to