re PR c++/38647 (ICE using __FUNCTION__ as template parameter)
PR c++/38647 * parser.c (cp_parser_primary_expression) <case RID_FUNCTION_NAME>: Return error_mark_node if cp_parser_non_integral_constant_expression returns true. * g++.dg/template/function1.C: New test. From-SVN: r142978
This commit is contained in:
parent
a67d93194a
commit
cc81fd1828
@ -1,5 +1,10 @@
|
||||
2008-12-31 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/38647
|
||||
* parser.c (cp_parser_primary_expression) <case RID_FUNCTION_NAME>:
|
||||
Return error_mark_node if cp_parser_non_integral_constant_expression
|
||||
returns true.
|
||||
|
||||
PR c++/38640
|
||||
* semantics.c (finish_decltype_type): Handle TEMPLATE_PARM_INDEX.
|
||||
|
||||
|
@ -3308,16 +3308,39 @@ cp_parser_primary_expression (cp_parser *parser,
|
||||
case RID_FUNCTION_NAME:
|
||||
case RID_PRETTY_FUNCTION_NAME:
|
||||
case RID_C99_FUNCTION_NAME:
|
||||
/* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and
|
||||
__func__ are the names of variables -- but they are
|
||||
treated specially. Therefore, they are handled here,
|
||||
rather than relying on the generic id-expression logic
|
||||
below. Grammatically, these names are id-expressions.
|
||||
{
|
||||
const char *name;
|
||||
|
||||
Consume the token. */
|
||||
token = cp_lexer_consume_token (parser->lexer);
|
||||
/* Look up the name. */
|
||||
return finish_fname (token->u.value);
|
||||
/* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and
|
||||
__func__ are the names of variables -- but they are
|
||||
treated specially. Therefore, they are handled here,
|
||||
rather than relying on the generic id-expression logic
|
||||
below. Grammatically, these names are id-expressions.
|
||||
|
||||
Consume the token. */
|
||||
token = cp_lexer_consume_token (parser->lexer);
|
||||
|
||||
switch (token->keyword)
|
||||
{
|
||||
case RID_FUNCTION_NAME:
|
||||
name = "%<__FUNCTION__%>";
|
||||
break;
|
||||
case RID_PRETTY_FUNCTION_NAME:
|
||||
name = "%<__PRETTY_FUNCTION__%>";
|
||||
break;
|
||||
case RID_C99_FUNCTION_NAME:
|
||||
name = "%<__func__%>";
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
if (cp_parser_non_integral_constant_expression (parser, name))
|
||||
return error_mark_node;
|
||||
|
||||
/* Look up the name. */
|
||||
return finish_fname (token->u.value);
|
||||
}
|
||||
|
||||
case RID_VA_ARG:
|
||||
{
|
||||
|
@ -1,5 +1,8 @@
|
||||
2008-12-31 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/38647
|
||||
* g++.dg/template/function1.C: New test.
|
||||
|
||||
PR c++/38640
|
||||
* g++.dg/cpp0x/decltype15.C: New test.
|
||||
|
||||
|
27
gcc/testsuite/g++.dg/template/function1.C
Normal file
27
gcc/testsuite/g++.dg/template/function1.C
Normal file
@ -0,0 +1,27 @@
|
||||
// PR c++/38647
|
||||
// { dg-do compile }
|
||||
|
||||
template<const char *, int> struct A {};
|
||||
const char func[] = "abc";
|
||||
template<int N> struct A<func, N> {}; // { dg-error "cannot appear|is invalid" }
|
||||
|
||||
char a1[1];
|
||||
A<a1, 0> a;
|
||||
|
||||
template<const char *, int> struct B {};
|
||||
template<int N> struct B<__FUNCTION__, N> {}; // { dg-error "cannot appear|is invalid" }
|
||||
|
||||
char b1[1];
|
||||
B<b1, 0> b;
|
||||
|
||||
template<const char *, int> struct C {};
|
||||
template<int N> struct C<__PRETTY_FUNCTION__, N> {}; // { dg-error "cannot appear|is invalid" }
|
||||
|
||||
char c1[1];
|
||||
C<c1, 0> c;
|
||||
|
||||
template<const char *, int> struct D {};
|
||||
template<int N> struct D<__func__, N> {}; // { dg-error "cannot appear|is invalid" }
|
||||
|
||||
char d1[1];
|
||||
D<d1, 0> d;
|
Loading…
Reference in New Issue
Block a user