This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] Don't ICE on invalid __decltype (~type) (PR c++/34268, c++/34267; take 2)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]