From a5ac3982bc53a972881bed634e3cc3dfa2141656 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 15 Dec 2003 16:59:56 +0000 Subject: [PATCH] re PR c++/13243 (Segfault on illegal template construct) PR c++/13243 PR c++/12573 * parser.c (cp_parser_postfix_expression): Tighten handling of integral constant expressions. (cp_parser_unary_expression): Likewise. * pt.c (value_dependent_expression_p): Remove handling for COMPONENT_REFs. PR c++/13243 PR c++/12573 * g++.dg/template/crash14.C: New test. * g++.dg/template/dependent-expr3.C: Add dg-error markers. From-SVN: r74637 --- gcc/cp/ChangeLog | 10 +++ gcc/cp/parser.c | 85 +++++++++++++------ gcc/cp/pt.c | 3 - gcc/testsuite/ChangeLog | 7 ++ gcc/testsuite/g++.dg/template/crash14.C | 3 + .../g++.dg/template/dependent-expr3.C | 4 +- 6 files changed, 82 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/crash14.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 93a37190a0a4..5e4e82433436 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2003-12-15 Mark Mitchell + + PR c++/13243 + PR c++/12573 + * parser.c (cp_parser_postfix_expression): Tighten handling of + integral constant expressions. + (cp_parser_unary_expression): Likewise. + * pt.c (value_dependent_expression_p): Remove handling for + COMPONENT_REFs. + 2003-12-15 Nathan Sidwell * class.c (add_method): Disallow destructor for java classes. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 4709ccbd9a76..a74e33a59e99 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -3637,6 +3637,15 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) postfix_expression = grok_array_decl (postfix_expression, index); idk = CP_ID_KIND_NONE; + /* Array references are not permitted in + constant-expressions. */ + if (parser->constant_expression_p) + { + if (!parser->allow_non_constant_expression_p) + postfix_expression + = cp_parser_non_constant_expression ("an array reference"); + parser->non_constant_expression_p = true; + } } break; @@ -3658,7 +3667,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) if (parser->constant_expression_p) { if (!parser->allow_non_constant_expression_p) - return cp_parser_non_constant_expression ("a function call"); + { + postfix_expression + = cp_parser_non_constant_expression ("a function call"); + break; + } parser->non_constant_expression_p = true; } @@ -3737,6 +3750,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) bool dependent_p; bool template_p; tree scope = NULL_TREE; + enum cpp_ttype token_type = token->type; /* If this is a `->' operator, dereference the pointer. */ if (token->type == CPP_DEREF) @@ -3839,6 +3853,15 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) object on the left-hand side of the `.' or `->' operator. */ parser->context->object_type = NULL_TREE; + /* These operators may not appear in constant-expressions. */ + if (parser->constant_expression_p) + { + if (!parser->allow_non_constant_expression_p) + postfix_expression + = (cp_parser_non_constant_expression + (token_type == CPP_DEREF ? "'->'" : "`.'")); + parser->non_constant_expression_p = true; + } } break; @@ -3846,17 +3869,18 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) /* postfix-expression ++ */ /* Consume the `++' token. */ cp_lexer_consume_token (parser->lexer); + /* Generate a representation for the complete expression. */ + postfix_expression + = finish_increment_expr (postfix_expression, + POSTINCREMENT_EXPR); /* Increments may not appear in constant-expressions. */ if (parser->constant_expression_p) { if (!parser->allow_non_constant_expression_p) - return cp_parser_non_constant_expression ("an increment"); + postfix_expression + = cp_parser_non_constant_expression ("an increment"); parser->non_constant_expression_p = true; } - /* Generate a representation for the complete expression. */ - postfix_expression - = finish_increment_expr (postfix_expression, - POSTINCREMENT_EXPR); idk = CP_ID_KIND_NONE; break; @@ -3864,17 +3888,18 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) /* postfix-expression -- */ /* Consume the `--' token. */ cp_lexer_consume_token (parser->lexer); + /* Generate a representation for the complete expression. */ + postfix_expression + = finish_increment_expr (postfix_expression, + POSTDECREMENT_EXPR); /* Decrements may not appear in constant-expressions. */ if (parser->constant_expression_p) { if (!parser->allow_non_constant_expression_p) - return cp_parser_non_constant_expression ("a decrement"); + postfix_expression + = cp_parser_non_constant_expression ("a decrement"); parser->non_constant_expression_p = true; } - /* Generate a representation for the complete expression. */ - postfix_expression - = finish_increment_expr (postfix_expression, - POSTDECREMENT_EXPR); idk = CP_ID_KIND_NONE; break; @@ -4217,6 +4242,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p) if (unary_operator != ERROR_MARK) { tree cast_expression; + tree expression = error_mark_node; + const char *non_constant_p = NULL; /* Consume the operator token. */ token = cp_lexer_consume_token (parser->lexer); @@ -4227,32 +4254,40 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p) switch (unary_operator) { case INDIRECT_REF: - return build_x_indirect_ref (cast_expression, "unary *"); - + non_constant_p = "`*'"; + expression = build_x_indirect_ref (cast_expression, "unary *"); + break; + case ADDR_EXPR: + non_constant_p = "`&'"; + /* Fall through. */ case BIT_NOT_EXPR: - return build_x_unary_op (unary_operator, cast_expression); - + expression = build_x_unary_op (unary_operator, cast_expression); + break; + case PREINCREMENT_EXPR: case PREDECREMENT_EXPR: - if (parser->constant_expression_p) - { - if (!parser->allow_non_constant_expression_p) - return cp_parser_non_constant_expression (PREINCREMENT_EXPR - ? "an increment" - : "a decrement"); - parser->non_constant_expression_p = true; - } + non_constant_p = (unary_operator == PREINCREMENT_EXPR + ? "`++'" : "`--'"); /* Fall through. */ case CONVERT_EXPR: case NEGATE_EXPR: case TRUTH_NOT_EXPR: - return finish_unary_op_expr (unary_operator, cast_expression); + expression = finish_unary_op_expr (unary_operator, cast_expression); + break; default: abort (); - return error_mark_node; } + + if (non_constant_p && parser->constant_expression_p) + { + if (!parser->allow_non_constant_expression_p) + return cp_parser_non_constant_expression (non_constant_p); + parser->non_constant_expression_p = true; + } + + return expression; } return cp_parser_postfix_expression (parser, address_p); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 2d31c4d1706c..553d4f7d3183 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11714,9 +11714,6 @@ value_dependent_expression_p (tree expression) } if (TREE_CODE (expression) == SCOPE_REF) return dependent_scope_ref_p (expression, value_dependent_expression_p); - if (TREE_CODE (expression) == COMPONENT_REF) - return (value_dependent_expression_p (TREE_OPERAND (expression, 0)) - || value_dependent_expression_p (TREE_OPERAND (expression, 1))); /* A constant expression is value-dependent if any subexpression is value-dependent. */ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression)))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 675122eac52d..dd5e215b1926 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2003-12-15 Mark Mitchell + + PR c++/13243 + PR c++/12573 + * g++.dg/template/crash14.C: New test. + * g++.dg/template/dependent-expr3.C: Add dg-error markers. + 2003-12-15 Nathan Sidwell * g++.dg/other/java1.C: New test. diff --git a/gcc/testsuite/g++.dg/template/crash14.C b/gcc/testsuite/g++.dg/template/crash14.C new file mode 100644 index 000000000000..7b3af045fa9e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/crash14.C @@ -0,0 +1,3 @@ +template class foo { public: foo() { } class Z { };}; +template void dep7(foo *) { } // { dg-error "" } + diff --git a/gcc/testsuite/g++.dg/template/dependent-expr3.C b/gcc/testsuite/g++.dg/template/dependent-expr3.C index 50673c83288a..2e8b805ead80 100644 --- a/gcc/testsuite/g++.dg/template/dependent-expr3.C +++ b/gcc/testsuite/g++.dg/template/dependent-expr3.C @@ -9,6 +9,6 @@ template struct Y : K { }; template struct Z { - S< (bool)(&static_cast *>(0)->x == 0) > - s; + S< (bool)(&static_cast *>(0)->x == 0) > // { dg-error "" } + s; // { dg-error "" } }; -- 2.43.5