This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/47144 (accepts-invalid with type definition in template argument)
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 11 Mar 2011 17:54:41 -0500
- Subject: C++ PATCH for c++/47144 (accepts-invalid with type definition in template argument)
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
type_definition_forbidden_message.
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;