diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-03-15 16:16:18 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-03-15 16:16:18 +0000 |
commit | 625cbf9318915e406776ab23a21fbb7093889c7a (patch) | |
tree | 6ca3ec63bda60cceb911971973b8af475954de44 | |
parent | 983e64842fe8236e78dc11f6d0f569a224f0767f (diff) | |
download | gcc-625cbf9318915e406776ab23a21fbb7093889c7a.zip gcc-625cbf9318915e406776ab23a21fbb7093889c7a.tar.gz gcc-625cbf9318915e406776ab23a21fbb7093889c7a.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/cp/parser.c | 170 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/template14.C | 17 |
4 files changed, 114 insertions, 94 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fc34864..5dc9e76 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,19 @@ +2004-03-13 Mark Mitchell <mark@codesourcery.com> + + 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 <austern@apple.com> * decl2.c (maybe_make_one_only): Look at diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0691c96..20588b0 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 7a113af..7d1450f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-03-13 Mark Mitchell <mark@codesourcery.com> + + PR c++/14550 + * g++.dg/parse/template14.C: New test. + 2004-03-13 Eric Botcazou <ebotcazou@libertysurf.fr> * 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 0000000..ada8752 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/template14.C @@ -0,0 +1,17 @@ +// PR c++/14550 + +struct A { + A(); +}; + +template <int> void foo() +{ + A *p = new A; +} + +void bar() +{ + foo<0>(); +} + + |