From: Mark Mitchell Date: Mon, 15 Mar 2004 16:16:18 +0000 (+0000) Subject: re PR c++/14550 (trouble with pointers in templates) X-Git-Tag: releases/gcc-4.0.0~9397 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=625cbf9318915e406776ab23a21fbb7093889c7a;p=thirdparty%2Fgcc.git re PR c++/14550 (trouble with pointers in templates) PR c++/14550 * parser.c (cp_parser_non_integral_constant_expression): Encode more of the idiom that surrounded calls to this function within the function itself (cp_parser_primary_expression): Adjust accordingly. (cp_parser_postfix_expression): Likewise. (cp_parser_unary_expression): Likewise. (cp_parser_cast_expression): Likewise. (cp_parser_assignment_expression): Likewise. (cp_parser_expression): Likewise. (cp_parser_new_expression): Note that new-expressions are not allowed in integral constant expressions. (cp_parser_delete_expression): Likewise. PR c++/14550 * g++.dg/parse/template14.C: New test. From-SVN: r79498 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fc34864146c8..5dc9e7614846 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +2004-03-13 Mark Mitchell + + PR c++/14550 + * parser.c (cp_parser_non_integral_constant_expression): Encode + more of the idiom that surrounded calls to this function within + the function itself + (cp_parser_primary_expression): Adjust accordingly. + (cp_parser_postfix_expression): Likewise. + (cp_parser_unary_expression): Likewise. + (cp_parser_cast_expression): Likewise. + (cp_parser_assignment_expression): Likewise. + (cp_parser_expression): Likewise. + (cp_parser_new_expression): Note that new-expressions are not + allowed in integral constant expressions. + (cp_parser_delete_expression): Likewise. + 2004-03-12 Matt Austern * decl2.c (maybe_make_one_only): Look at diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0691c96ebc01..20588b0469d2 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1719,8 +1719,8 @@ static void cp_parser_check_for_definition_in_return_type (tree, int); static void cp_parser_check_for_invalid_template_id (cp_parser *, tree); -static tree cp_parser_non_integral_constant_expression - (const char *); +static bool cp_parser_non_integral_constant_expression + (cp_parser *, const char *); static void cp_parser_diagnose_invalid_type_name (cp_parser *, tree, tree); static bool cp_parser_parse_and_diagnose_invalid_type_name @@ -1922,14 +1922,24 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser, } } -/* Issue an error message about the fact that THING appeared in a - constant-expression. Returns ERROR_MARK_NODE. */ +/* If parsing an integral constant-expression, issue an error message + about the fact that THING appeared and return true. Otherwise, + return false, marking the current expression as non-constant. */ -static tree -cp_parser_non_integral_constant_expression (const char *thing) +static bool +cp_parser_non_integral_constant_expression (cp_parser *parser, + const char *thing) { - error ("%s cannot appear in a constant-expression", thing); - return error_mark_node; + if (parser->integral_constant_expression_p) + { + if (!parser->allow_non_integral_constant_expression_p) + { + error ("%s cannot appear in a constant-expression", thing); + return true; + } + parser->non_integral_constant_expression_p = true; + } + return false; } /* Emit a diagnostic for an invalid type name. Consider also if it is @@ -2542,12 +2552,9 @@ cp_parser_primary_expression (cp_parser *parser, return error_mark_node; } /* Pointers cannot appear in constant-expressions. */ - if (parser->integral_constant_expression_p) - { - if (!parser->allow_non_integral_constant_expression_p) - return cp_parser_non_integral_constant_expression ("`this'"); - parser->non_integral_constant_expression_p = true; - } + if (cp_parser_non_integral_constant_expression (parser, + "`this'")) + return error_mark_node; return finish_this_expr (); /* The `operator' keyword can be the beginning of an @@ -2589,12 +2596,9 @@ cp_parser_primary_expression (cp_parser *parser, cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'"); /* Using `va_arg' in a constant-expression is not allowed. */ - if (parser->integral_constant_expression_p) - { - if (!parser->allow_non_integral_constant_expression_p) - return cp_parser_non_integral_constant_expression ("`va_arg'"); - parser->non_integral_constant_expression_p = true; - } + if (cp_parser_non_integral_constant_expression (parser, + "`va_arg'")) + return error_mark_node; return build_x_va_arg (expression, type); } @@ -3518,14 +3522,12 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) && !INTEGRAL_OR_ENUMERATION_TYPE_P (type) /* A cast to pointer or reference type is allowed in the implementation of "offsetof". */ - && !(parser->in_offsetof_p && POINTER_TYPE_P (type))) - { - if (!parser->allow_non_integral_constant_expression_p) - return (cp_parser_non_integral_constant_expression - ("a cast to a type other than an integral or " - "enumeration type")); - parser->non_integral_constant_expression_p = true; - } + && !(parser->in_offsetof_p && POINTER_TYPE_P (type)) + && (cp_parser_non_integral_constant_expression + (parser, + "a cast to a type other than an integral or " + "enumeration type"))) + return error_mark_node; switch (keyword) { @@ -3771,13 +3773,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) idk = CP_ID_KIND_NONE; /* Array references are not permitted in constant-expressions. */ - if (parser->integral_constant_expression_p) - { - if (!parser->allow_non_integral_constant_expression_p) - postfix_expression - = cp_parser_non_integral_constant_expression ("an array reference"); - parser->non_integral_constant_expression_p = true; - } + if (cp_parser_non_integral_constant_expression + (parser, "an array reference")) + postfix_expression = error_mark_node; } break; @@ -3796,15 +3794,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) /* Function calls are not permitted in constant-expressions. */ - if (parser->integral_constant_expression_p) + if (cp_parser_non_integral_constant_expression (parser, + "a function call")) { - if (!parser->allow_non_integral_constant_expression_p) - { - postfix_expression - = cp_parser_non_integral_constant_expression ("a function call"); - break; - } - parser->non_integral_constant_expression_p = true; + postfix_expression = error_mark_node; + break; } koenig_p = false; @@ -3999,18 +3993,14 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) operator. */ parser->context->object_type = NULL_TREE; /* These operators may not appear in constant-expressions. */ - if (parser->integral_constant_expression_p - /* The "->" operator is allowed in the implementation + if (/* The "->" operator is allowed in the implementation of "offsetof". The "." operator may appear in the name of the member. */ - && !parser->in_offsetof_p) - { - if (!parser->allow_non_integral_constant_expression_p) - postfix_expression - = (cp_parser_non_integral_constant_expression - (token_type == CPP_DEREF ? "'->'" : "`.'")); - parser->non_integral_constant_expression_p = true; - } + !parser->in_offsetof_p + && (cp_parser_non_integral_constant_expression + (parser, + token_type == CPP_DEREF ? "'->'" : "`.'"))) + postfix_expression = error_mark_node; } break; @@ -4023,13 +4013,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) = finish_increment_expr (postfix_expression, POSTINCREMENT_EXPR); /* Increments may not appear in constant-expressions. */ - if (parser->integral_constant_expression_p) - { - if (!parser->allow_non_integral_constant_expression_p) - postfix_expression - = cp_parser_non_integral_constant_expression ("an increment"); - parser->non_integral_constant_expression_p = true; - } + if (cp_parser_non_integral_constant_expression (parser, + "an increment")) + postfix_expression = error_mark_node; idk = CP_ID_KIND_NONE; break; @@ -4042,13 +4028,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) = finish_increment_expr (postfix_expression, POSTDECREMENT_EXPR); /* Decrements may not appear in constant-expressions. */ - if (parser->integral_constant_expression_p) - { - if (!parser->allow_non_integral_constant_expression_p) - postfix_expression - = cp_parser_non_integral_constant_expression ("a decrement"); - parser->non_integral_constant_expression_p = true; - } + if (cp_parser_non_integral_constant_expression (parser, + "a decrement")) + postfix_expression = error_mark_node; idk = CP_ID_KIND_NONE; break; @@ -4447,12 +4429,10 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p) abort (); } - if (non_constant_p && parser->integral_constant_expression_p) - { - if (!parser->allow_non_integral_constant_expression_p) - return cp_parser_non_integral_constant_expression (non_constant_p); - parser->non_integral_constant_expression_p = true; - } + if (non_constant_p + && cp_parser_non_integral_constant_expression (parser, + non_constant_p)) + expression = error_mark_node; return expression; } @@ -4553,6 +4533,11 @@ cp_parser_new_expression (cp_parser* parser) else initializer = NULL_TREE; + /* A new-expression may not appear in an integral constant + expression. */ + if (cp_parser_non_integral_constant_expression (parser, "`new'")) + return error_mark_node; + /* Create a representation of the new-expression. */ return build_new (placement, type, initializer, global_scope_p); } @@ -4781,6 +4766,11 @@ cp_parser_delete_expression (cp_parser* parser) /* Parse the cast-expression. */ expression = cp_parser_simple_cast_expression (parser); + /* A delete-expression may not appear in an integral constant + expression. */ + if (cp_parser_non_integral_constant_expression (parser, "`delete'")) + return error_mark_node; + return delete_sanity (expression, NULL_TREE, array_p, global_scope_p); } @@ -4878,14 +4868,13 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p) can be used in constant-expressions. */ if (parser->integral_constant_expression_p && !dependent_type_p (type) - && !INTEGRAL_OR_ENUMERATION_TYPE_P (type)) - { - if (!parser->allow_non_integral_constant_expression_p) - return (cp_parser_non_integral_constant_expression - ("a casts to a type other than an integral or " - "enumeration type")); - parser->non_integral_constant_expression_p = true; - } + && !INTEGRAL_OR_ENUMERATION_TYPE_P (type) + && (cp_parser_non_integral_constant_expression + (parser, + "a cast to a type other than an integral or " + "enumeration type"))) + return error_mark_node; + /* Perform the cast. */ expr = build_c_cast (type, expr); return expr; @@ -5238,12 +5227,9 @@ cp_parser_assignment_expression (cp_parser* parser) rhs = cp_parser_assignment_expression (parser); /* An assignment may not appear in a constant-expression. */ - if (parser->integral_constant_expression_p) - { - if (!parser->allow_non_integral_constant_expression_p) - return cp_parser_non_integral_constant_expression ("an assignment"); - parser->non_integral_constant_expression_p = true; - } + if (cp_parser_non_integral_constant_expression (parser, + "an assignment")) + return error_mark_node; /* Build the assignment expression. */ expr = build_x_modify_expr (expr, assignment_operator, @@ -5381,13 +5367,9 @@ cp_parser_expression (cp_parser* parser) /* Consume the `,'. */ cp_lexer_consume_token (parser->lexer); /* A comma operator cannot appear in a constant-expression. */ - if (parser->integral_constant_expression_p) - { - if (!parser->allow_non_integral_constant_expression_p) - expression - = cp_parser_non_integral_constant_expression ("a comma operator"); - parser->non_integral_constant_expression_p = true; - } + if (cp_parser_non_integral_constant_expression (parser, + "a comma operator")) + expression = error_mark_node; } return expression; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7a113afdc88e..7d1450fb100e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-03-13 Mark Mitchell + + PR c++/14550 + * g++.dg/parse/template14.C: New test. + 2004-03-13 Eric Botcazou * gcc.c-torture/execute/20040313-1.c: New test. diff --git a/gcc/testsuite/g++.dg/parse/template14.C b/gcc/testsuite/g++.dg/parse/template14.C new file mode 100644 index 000000000000..ada875243520 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/template14.C @@ -0,0 +1,17 @@ +// PR c++/14550 + +struct A { + A(); +}; + +template void foo() +{ + A *p = new A; +} + +void bar() +{ + foo<0>(); +} + +