This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Don't ICE on invalid decltype uses (PR c++/34271)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>, Mark Mitchell <mark at codesourcery dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 4 Dec 2007 14:24:51 -0500
- Subject: [C++ PATCH] Don't ICE on invalid decltype uses (PR c++/34271)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
As shown on the first testcase (and second as well if the parser.c
hunk isn't applied), non-dependent SCOPE_REFs can make it into
finish_decltype_type, which will ICE on them. On decltype9.C
the SCOPE_REF is created from VAR_DECL in finish_id_expression:
if (processing_template_decl && TYPE_P (scope))
r = build_qualified_name (TREE_TYPE (r),
scope, decl,
template_p);
The patch below cures this by deferring even non-dependent SCOPE_REFs
till instantiation, at which point either diagnostics will be issued
or they will materialize to something else, but other option is just handle
SCOPE_REF in finish_decltype_type by issuing an error on it like we do for
types already.
2007-12-04 Jakub Jelinek <jakub@redhat.com>
PR c++/34271
* semantics.c (finish_decltype_type): For SCOPE_REF also always
create DECLTYPE_TYPE.
* parser.c (cp_parser_decltype): If closing paren is not found,
return error_mark_node.
* g++.dg/cpp0x/decltype9.C: New test.
* g++.dg/cpp0x/decltype10.C: New test.
--- gcc/cp/semantics.c.jj 2007-11-29 19:38:34.000000000 +0100
+++ gcc/cp/semantics.c 2007-12-04 18:25:05.000000000 +0100
@@ -4075,7 +4075,7 @@ finish_decltype_type (tree expr, bool id
return error_mark_node;
}
- if (type_dependent_expression_p (expr))
+ if (type_dependent_expression_p (expr) || TREE_CODE (expr) == SCOPE_REF)
{
type = make_aggr_type (DECLTYPE_TYPE);
DECLTYPE_TYPE_EXPR (type) = expr;
--- gcc/cp/parser.c.jj 2007-11-29 19:38:34.000000000 +0100
+++ gcc/cp/parser.c 2007-12-04 19:09:00.000000000 +0100
@@ -8602,8 +8602,11 @@ cp_parser_decltype (cp_parser *parser)
/* Parse to the closing `)'. */
if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'"))
- cp_parser_skip_to_closing_parenthesis (parser, true, false,
- /*consume_paren=*/true);
+ {
+ cp_parser_skip_to_closing_parenthesis (parser, true, false,
+ /*consume_paren=*/true);
+ return error_mark_node;
+ }
return finish_decltype_type (expr, id_expression_or_member_access_p);
}
--- gcc/testsuite/g++.dg/cpp0x/decltype9.C.jj 2007-12-04 20:11:24.000000000 +0100
+++ gcc/testsuite/g++.dg/cpp0x/decltype9.C 2007-12-04 20:10:36.000000000 +0100
@@ -0,0 +1,10 @@
+// PR c++/34271
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template<int> struct A
+{
+ static int i;
+};
+
+template<int N> int A<N>::i(decltype (A::i)); // { dg-error "nomember function declared in class" }
--- gcc/testsuite/g++.dg/cpp0x/decltype10.C.jj 2007-12-04 20:12:30.000000000 +0100
+++ gcc/testsuite/g++.dg/cpp0x/decltype10.C 2007-12-04 20:12:19.000000000 +0100
@@ -0,0 +1,10 @@
+// PR c++/34271
+// { dg-do compile }
+// { dg-options "-std=c++0x" }
+
+template<int> struct A
+{
+ static int i;
+};
+
+template<int N> int A<N>::i(decltype (A::i; // { dg-error "expected primary-expression before" }
Jakub