re PR c++/81247 (ICE on invalid C++ code with malformed namespace declaration: in...
authorNathan Sidwell <nathan@acm.org>
Thu, 29 Jun 2017 18:20:13 +0000 (18:20 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 29 Jun 2017 18:20:13 +0000 (18:20 +0000)
PR c++/81247
* parser.c (cp_parser_namespace_definition): Immediately close the
namespace if there's no open-brace.
* name-lookup.c (do_pushdecl): Reset OLD when pushing into new
namespace.

From-SVN: r249804

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/pr81247-a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/pr81247-b.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/pr81247-c.C [new file with mode: 0644]

index 2c29f1e6d16463355c25497ec696c6cc17af43fa..17da1c5868dd607e4c38620f638417fc5637db22 100644 (file)
@@ -1,3 +1,11 @@
+2017-06-29  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/81247
+       * parser.c (cp_parser_namespace_definition): Immediately close the
+       namespace if there's no open-brace.
+       * name-lookup.c (do_pushdecl): Reset OLD when pushing into new
+       namespace.
+
 2017-06-29  Jason Merrill  <jason@redhat.com>
 
        PR c++/81164 - ICE with invalid inherited constructor.
index f15c811695922ed4de9dc4f1695e245ca6db2b10..4beab850612e2dd4fb903ceeaf90d77e6ee70331 100644 (file)
@@ -2422,6 +2422,9 @@ do_pushdecl (tree decl, bool is_friend)
        {
          ns = current_namespace;
          slot = find_namespace_slot (ns, name, true);
+         /* Update OLD to reflect the namespace we're going to be
+            pushing into.  */
+         old = MAYBE_STAT_DECL (*slot);
        }
 
       old = update_binding (level, binding, slot, old, decl, is_friend);
index 31840d6ea6f93b49fb790e2f7749026124c6d16f..375cd0a592d91fcabcdfdf5f9fa07780a10b86cb 100644 (file)
@@ -18397,13 +18397,14 @@ cp_parser_namespace_definition (cp_parser* parser)
   warning  (OPT_Wnamespaces, "namespace %qD entered", current_namespace);
 
   /* Look for the `{' to validate starting the namespace.  */
-  cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE);
-
-  /* Parse the body of the namespace.  */
-  cp_parser_namespace_body (parser);
+  if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
+    {
+      /* Parse the body of the namespace.  */
+      cp_parser_namespace_body (parser);
 
-  /* Look for the final `}'.  */
-  cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+      /* Look for the final `}'.  */
+      cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+    }
 
   if (has_visibility)
     pop_visibility (1);
index 49a84d64e55c01447f68a2d05d2239439d2023cb..d44f1a14862ad04eaef52f8176f521902ffaa554 100644 (file)
@@ -1,3 +1,8 @@
+2017-06-29  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/81247
+       * g++.dg/parse/pr81247-[abc].C: New.
+
 2017-06-29  Carl Love  <cel@us.ibm.com>
 
        * gcc.target/powerpc/builtins-3-runnable.c (test_int_result,
diff --git a/gcc/testsuite/g++.dg/parse/pr81247-a.C b/gcc/testsuite/g++.dg/parse/pr81247-a.C
new file mode 100644 (file)
index 0000000..c5b22ab
--- /dev/null
@@ -0,0 +1,13 @@
+// PR c++/81247 ICE
+
+namespace N  // { dg-message "previous declaration" }
+// { dg-error "expected" "" { target *-*-* } .+1 }
+template < typename T > class A
+{ // { dg-error "redeclared as different" }
+  template < T > friend class N;
+};
+
+void f ()
+{
+  A < int > a1; //  { dg-message "required from here" }
+}
diff --git a/gcc/testsuite/g++.dg/parse/pr81247-b.C b/gcc/testsuite/g++.dg/parse/pr81247-b.C
new file mode 100644 (file)
index 0000000..b2b035b
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/81247 confused error
+
+namespace N { // { dg-message "previous declaration" }
+}
+
+template < typename T > class A
+{ // { dg-error "redeclared as different" }
+  template < T > friend class N;
+};
+
+void f ()
+{
+  A < int > a1;
+}
diff --git a/gcc/testsuite/g++.dg/parse/pr81247-c.C b/gcc/testsuite/g++.dg/parse/pr81247-c.C
new file mode 100644 (file)
index 0000000..32f41f2
--- /dev/null
@@ -0,0 +1,13 @@
+// PR c++/81247 confused error
+
+namespace N { // { dg-message "previous declaration" }
+  template < typename T > class A
+  { // { dg-error "conflicts with a previous" }
+    template < T > friend class N;
+  };
+}
+
+void f ()
+{
+  N::A < int > a1;
+}