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 (~type) (PR c++/34268, c++/34267; take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Mark Mitchell <mark at codesourcery dot com>, Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 29 Nov 2007 08:01:44 -0500
- Subject: [C++ PATCH] Don't ICE on invalid __decltype (~type) (PR c++/34268, c++/34267; take 2)
- References: <20071129111553.GG16835@devserv.devel.redhat.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Thu, Nov 29, 2007 at 06:15:53AM -0500, Jakub Jelinek wrote:
> ~type is a valid id-expression, but
> 1) finish_id_expression doesn't expect to be called with it
> 2) finish_decltype_type assertion catches it anyway
> The following patch handles BIT_NOT_EXPR with TYPE_P argument gracefully.
Actually, looking at PR c++/34267 where type_dependent_expression_p called
from finish_decltype_type is called with a TYPE_DECL (valid id-expression),
I think it is better to reject these before calling
type_dependent_expression_p. type_dependent_expression_p won't then ICE
on TYPE_DECLs, and (some) invalid __decltype arguments will be already
reported during parsing of the template, rather than at instantiation time
(and so reported even for templates which aren't ever instantiated).
n2115.pdf says in 2.3 quite clearly that type argument is not accepted.
2007-11-29 Jakub Jelinek <jakub@redhat.com>
PR c++/34267
PR c++/34268
* parser.c (cp_parser_decltype): Don't call finish_id_expression
on ~type.
* semantics.c (finish_decltype_type): Issue error on types, TYPE_DECLs
and ~type early.
* g++.dg/cpp0x/decltype7.C: New test.
--- gcc/cp/parser.c.jj 2007-11-20 14:51:47.000000000 +0100
+++ gcc/cp/parser.c 2007-11-29 12:01:33.000000000 +0100
@@ -8512,10 +8512,12 @@ cp_parser_decltype (cp_parser *parser)
/*check_dependency=*/true,
/*ambiguous_decls=*/NULL);
- if (expr
+ if (expr
&& expr != error_mark_node
&& TREE_CODE (expr) != TEMPLATE_ID_EXPR
&& TREE_CODE (expr) != TYPE_DECL
+ && (TREE_CODE (expr) != BIT_NOT_EXPR
+ || !TYPE_P (TREE_OPERAND (expr, 0)))
&& cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
{
/* Complete lookup of the id-expression. */
--- gcc/cp/semantics.c.jj 2007-11-18 22:56:11.000000000 +0100
+++ gcc/cp/semantics.c 2007-11-29 13:50:41.000000000 +0100
@@ -4066,6 +4066,15 @@ finish_decltype_type (tree expr, bool id
if (!expr || error_operand_p (expr))
return error_mark_node;
+ if (TYPE_P (expr)
+ || TREE_CODE (expr) == TYPE_DECL
+ || (TREE_CODE (expr) == BIT_NOT_EXPR
+ && TYPE_P (TREE_OPERAND (expr, 0))))
+ {
+ error ("argument to decltype must be an expression");
+ return error_mark_node;
+ }
+
if (type_dependent_expression_p (expr))
{
type = make_aggr_type (DECLTYPE_TYPE);
--- gcc/testsuite/g++.dg/cpp0x/decltype7.C.jj 2007-11-29 12:09:54.000000000 +0100
+++ gcc/testsuite/g++.dg/cpp0x/decltype7.C 2007-11-29 12:09:28.000000000 +0100
@@ -0,0 +1,14 @@
+// PR c++/34268
+// { dg-do compile }
+
+struct A
+{
+ __decltype (A); // { dg-error "must be an expression" }
+ __decltype (~A); // { dg-error "must be an expression" }
+};
+
+struct B
+{
+ __typeof__ (B);
+ __typeof__ (~B); // { dg-error "expected primary-expression" }
+};
--- gcc/testsuite/g++.dg/cpp0x/decltype8.C.jj 2007-11-29 13:35:33.000000000 +0100
+++ gcc/testsuite/g++.dg/cpp0x/decltype8.C 2007-11-29 13:37:30.000000000 +0100
@@ -0,0 +1,12 @@
+// PR c++/34267
+// { dg-do compile }
+
+struct A {};
+__decltype (A); // { dg-error "must be an expression" }
+template<int> struct B
+{
+ __decltype (A); // { dg-error "must be an expression" }
+ __decltype (~A); // { dg-error "must be an expression" }
+ __decltype (B); // { dg-error "must be an expression" }
+ __decltype (~B); // { dg-error "must be an expression" }
+};
Jakub