C++ PATCH for c++/47144 (accepts-invalid with type definition in template argument)

Message ID 4D7AA831.1060801@redhat.com
State New
Headers show

Commit Message

Jason Merrill March 11, 2011, 10:54 p.m.
G++ was oddly accepting this testcase even though it uses a name which 
is not defined anywhere.  This turns out to be because when we see the 
struct B { } we commit to all tentative parses.  We happened to be in 
the middle of testing whether A<...>::SomeNonSense is a constructor 
declarator, so when we decide that in fact it isn't, we try to abort the 
tentative parse, but we've already committed to it, so the effect is to 
just skip over those tokens and ignore them.  I'll add a sanity check to 
cp_parser_abort_tentative_parse in 4.7, but not 4.6.  In any case, 
prohibiting the type definition avoids this issue.

Tested x86_64-pc-linux-gnu, applied to trunk.
commit a338090ba7d290167871e4fb070bb69870498305
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Mar 11 17:27:43 2011 -0500

    	PR c++/47144
    	* parser.c (cp_parser_template_type_arg): Set


diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7e9b286..4260f6d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -15685,7 +15685,13 @@  static tree cp_parser_type_id (cp_parser *parser)
 static tree cp_parser_template_type_arg (cp_parser *parser)
-  return cp_parser_type_id_1 (parser, true, false);
+  tree r;
+  const char *saved_message = parser->type_definition_forbidden_message;
+  parser->type_definition_forbidden_message
+    = G_("types may not be defined in template arguments");
+  r = cp_parser_type_id_1 (parser, true, false);
+  parser->type_definition_forbidden_message = saved_message;
+  return r;
 static tree cp_parser_trailing_type_id (cp_parser *parser)
diff --git a/gcc/testsuite/g++.dg/parse/no-type-defn1.C b/gcc/testsuite/g++.dg/parse/no-type-defn1.C
new file mode 100644
index 0000000..9e89957
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/no-type-defn1.C
@@ -0,0 +1,5 @@ 
+// PR c++/47144
+template<typename> struct A { };
+A< struct B { }* >::SomeNonSense // { dg-error "types may not be defined" }
+int y;