aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2008-12-31 12:46:18 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2008-12-31 12:46:18 +0100
commitcc81fd182879509b81a950dd586f8269c970502f (patch)
treec51d8d1cc8c676c3d17bb9a2e900b434bb415c18
parenta67d93194a23a00de6c09821fe8fd6c31ac2fd9e (diff)
downloadgcc-cc81fd182879509b81a950dd586f8269c970502f.zip
gcc-cc81fd182879509b81a950dd586f8269c970502f.tar.gz
gcc-cc81fd182879509b81a950dd586f8269c970502f.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/parser.c41
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/template/function1.C27
4 files changed, 67 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 6f34380..e6cb289 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e21aa8e..545d3dd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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:
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6b66b92..9a8aaa1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/g++.dg/template/function1.C b/gcc/testsuite/g++.dg/template/function1.C
new file mode 100644
index 0000000..1097c5b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/function1.C
@@ -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;