This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] &&label is not integral constant-expression (PR c++/33836)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 29 Oct 2007 17:23:15 -0400
- Subject: [C++ PATCH] &&label is not integral constant-expression (PR c++/33836)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
On this testcase we ICE after issuing error about using &&label outside
of function body. For that case &&label is turned into NULL pointer,
but build_enumerator expects if INTEGER_CST was returned it has integral
type (because !parser->allow_non_integral_constant_expression_p enforces
that). &&label is never an integral-constant-expression, so IMHO the
best fix is never allow it as integral constant-expression.
Bootstrapped/regtested on x86_64-linux.
2007-10-29 Jakub Jelinek <jakub@redhat.com>
PR c++/33836
* parser.c (cp_parser_unary_expression): For &&label call
cp_parser_non_integral_constant_expression and return error_mark_node
if it returned true.
* g++.dg/ext/label10.C: New test.
--- gcc/cp/parser.c.jj 2007-10-29 14:29:28.000000000 +0100
+++ gcc/cp/parser.c 2007-10-29 14:29:28.000000000 +0100
@@ -5314,13 +5314,17 @@ cp_parser_unary_expression (cp_parser *p
&& token->type == CPP_AND_AND)
{
tree identifier;
+ tree expression;
/* Consume the '&&' token. */
cp_lexer_consume_token (parser->lexer);
/* Look for the identifier. */
identifier = cp_parser_identifier (parser);
/* Create an expression representing the address. */
- return finish_label_address_expr (identifier);
+ expression = finish_label_address_expr (identifier);
+ if (cp_parser_non_integral_constant_expression (parser, "`&&'"))
+ expression = error_mark_node;
+ return expression;
}
}
if (unary_operator != ERROR_MARK)
--- gcc/testsuite/g++.dg/ext/label10.C.jj 2007-10-29 14:35:45.000000000 +0100
+++ gcc/testsuite/g++.dg/ext/label10.C 2007-10-29 14:34:29.000000000 +0100
@@ -0,0 +1,17 @@
+// PR c++/33836
+// { dg-do compile }
+// { dg-options "-std=gnu++98" }
+
+template<int N> struct A
+{
+ enum { M = && N }; // { dg-error "referenced outside|cannot appear in" }
+};
+
+A<0> a;
+
+void foo ()
+{
+ __label__ P;
+ enum { O = && P }; // { dg-error "cannot appear in" }
+ P:;
+}
Jakub