This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
reject `f<typename T>' without crashing
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 08 Dec 2004 07:25:57 -0200
- Subject: reject `f<typename T>' without crashing
- Organization: Red Hat Global Engineering Services Compiler Team
This patch is for PR 18757. The problem is two-fold. First,
tsubst_template_args () returns error_mark_node if any of the substed
args is error_mark_node. In the reported testcase, this turns a
vector containing an error_mark_node into an error_mark_node in
tsubst_baselink(), so we create a TEMPLATE_ID_EXPR with that as the
explicit template argument list.
Later on, in build_new_method_call(), when we call
add_template_candidate(), we end up getting to coerce_template_args()
with args == error_mark_node, at which point we ICE if checking is
enabled, or dereference an invalid pointer otherwise, as described in
the bug report.
The following patch seems to be enough to fix the problem. It ensures
that we don't silently accept a template id with parse errors in its
explicit arguments as if it had parsed successfully (otherwise we end
up silently compiling code with syntax errors, if a template
containing the ill-formed template id turns out to never be
instantiated).
It might also be reasonable to modify coerce_template_args() to test
for an error_mark_node in args and return an error_mark_node
immediately, but I couldn't convince myself this wouldn't fail to
issue error messages in case of errors in template argument
substitution.
I've also attached the testcase I intend to install in the testsuite,
after annotating it properly. I'm not entirely happy with the
multiple errors I get for each syntax error, but I don't see how to do
any better, since we end up attempting to parse the ill-formed
template argument as a type cast.
BZ141300s3.cc: In member function ‘void A::bar(T)’:
BZ141300s3.cc:4: error: expected nested-name-specifier before ‘T’
BZ141300s3.cc:4: error: expected `(' before ‘>’ token
BZ141300s3.cc: In member function ‘void A::bad(T)’:
BZ141300s3.cc:5: error: expected nested-name-specifier before ‘T’
BZ141300s3.cc:5: error: expected `(' before ‘>’ token
BZ141300s3.cc: In member function ‘void B<T>::bar(T)’:
BZ141300s3.cc:11: error: expected nested-name-specifier before ‘T’
BZ141300s3.cc:11: error: expected `(' before ‘>’ token
BZ141300s3.cc: In member function ‘void B<T>::bad(T)’:
BZ141300s3.cc:12: error: template argument 1 is invalid
BZ141300s3.cc:12: error: template argument 1 is invalid
BZ141300s3.cc:12: error: ‘B<T>’ is not a template
Comments? Ok to install if it passes regression testing, currently
ongoing on x86_64-linux-gnu?
Index: gcc/cp/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
PR c++/18757
* parser.c (cp_parser_template_id): Don't create a CPP_TEMPLATE_ID
if parsing failed.
Index: gcc/cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.289
diff -u -p -r1.289 parser.c
--- gcc/cp/parser.c 3 Dec 2004 09:51:35 -0000 1.289
+++ gcc/cp/parser.c 8 Dec 2004 08:58:46 -0000
@@ -8416,8 +8416,9 @@ cp_parser_template_id (cp_parser *parser
should we re-parse the token stream, we will not have to repeat
the effort required to do the parse, nor will we issue duplicate
error messages about problems during instantiation of the
- template. */
- if (start_of_id)
+ template. Do so only if parsing succeeded, otherwise we may
+ silently accept template arguments with syntax errors. */
+ if (start_of_id && !cp_parser_error_occurred (parser))
{
cp_token *token = cp_lexer_token_at (parser->lexer, start_of_id);
struct A
{
template<typename> void foo(int);
template<typename T> void bar(T t) { this->foo<typename T>(t); }
template<typename T> void bad(T t) { foo<typename T>(t); }
};
template <typename T>
struct B
{
void bar(T t) { A().bar<typename T>(t); }
void bad(T t) { B<typename T>::bar(t); }
};
void baz()
{
A().bar(0);
A().bad(0);
B<int>().bar(0);
}
--
Alexandre Oliva http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}