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:
Jakub Jelinek 2008-12-31 12:46:18 +01:00 committed by Jakub Jelinek
parent a67d93194a
commit cc81fd1828
4 changed files with 67 additions and 9 deletions

View File

@ -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.

View File

@ -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:
{

View File

@ -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.

View 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;