From 1504e23205cf12c84b656bda136a0078006ec55a Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Thu, 10 Feb 2005 01:10:11 +0000 Subject: [PATCH] re PR c++/19787 (Internal compiler error with ambiguous conversion functions) PR c++/19787 * call.c (initialize_reference): Robustify. PR c++/19762 * parser.c (cp_parser_unqualified_id): Avoid creating destructor names with invalid types. PR c++/19739 * parser.c (cp_parser_attributes_list): Allow empty lists. PR c++/19787 * g++.dg/conversion/ambig1.C: New test. PR c++/19739 * g++.dg/ext/attrib19.C: New test. PR c++/19762 * g++.dg/template/dtor3.C: New test. From-SVN: r94791 --- gcc/cp/ChangeLog | 12 ++++++ gcc/cp/call.c | 2 + gcc/cp/parser.c | 92 ++++++++++++++++++++++------------------- gcc/testsuite/ChangeLog | 11 +++++ 4 files changed, 75 insertions(+), 42 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bfc7d7a3fc79..4aeb82568d9b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,15 @@ +2005-02-09 Mark Mitchell + + PR c++/19787 + * call.c (initialize_reference): Robustify. + + PR c++/19762 + * parser.c (cp_parser_unqualified_id): Avoid creating destructor + names with invalid types. + + PR c++/19739 + * parser.c (cp_parser_attributes_list): Allow empty lists. + 2005-02-08 Mark Mitchell PR c++/19733 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 5114af79f0c1..ee464533bc66 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6190,6 +6190,8 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup) /*fn=*/NULL_TREE, /*argnum=*/0, /*inner=*/-1, /*issue_conversion_warnings=*/true); + if (error_operand_p (expr)) + return error_mark_node; if (!real_lvalue_p (expr)) { tree init; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 867896b444ab..fbd156a05734 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2851,6 +2851,7 @@ cp_parser_unqualified_id (cp_parser* parser, tree qualifying_scope; tree object_scope; tree scope; + bool done; /* Consume the `~' token. */ cp_lexer_consume_token (parser->lexer); @@ -2907,6 +2908,7 @@ cp_parser_unqualified_id (cp_parser* parser, /* If there was an explicit qualification (S::~T), first look in the scope given by the qualification (i.e., S). */ + done = false; if (scope) { cp_parser_parse_tentatively (parser); @@ -2918,10 +2920,10 @@ cp_parser_unqualified_id (cp_parser* parser, /*class_head_p=*/false, declarator_p); if (cp_parser_parse_definitely (parser)) - return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl)); + done = true; } /* In "N::S::~S", look in "N" as well. */ - if (scope && qualifying_scope) + if (!done && scope && qualifying_scope) { cp_parser_parse_tentatively (parser); parser->scope = qualifying_scope; @@ -2936,10 +2938,10 @@ cp_parser_unqualified_id (cp_parser* parser, /*class_head_p=*/false, declarator_p); if (cp_parser_parse_definitely (parser)) - return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl)); + done = true; } /* In "p->S::~T", look in the scope given by "*p" as well. */ - else if (object_scope) + else if (!done && object_scope) { cp_parser_parse_tentatively (parser); parser->scope = object_scope; @@ -2954,20 +2956,23 @@ cp_parser_unqualified_id (cp_parser* parser, /*class_head_p=*/false, declarator_p); if (cp_parser_parse_definitely (parser)) - return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl)); + done = true; } /* Look in the surrounding context. */ - parser->scope = NULL_TREE; - parser->object_scope = NULL_TREE; - parser->qualifying_scope = NULL_TREE; - type_decl - = cp_parser_class_name (parser, - /*typename_keyword_p=*/false, - /*template_keyword_p=*/false, - /*type_p=*/false, - /*check_dependency=*/false, - /*class_head_p=*/false, - declarator_p); + if (!done) + { + parser->scope = NULL_TREE; + parser->object_scope = NULL_TREE; + parser->qualifying_scope = NULL_TREE; + type_decl + = cp_parser_class_name (parser, + /*typename_keyword_p=*/false, + /*template_keyword_p=*/false, + /*type_p=*/false, + /*check_dependency=*/false, + /*class_head_p=*/false, + declarator_p); + } /* If an error occurred, assume that the name of the destructor is the same as the name of the qualifying class. That allows us to keep parsing after running @@ -13535,36 +13540,39 @@ cp_parser_attribute_list (cp_parser* parser) /* Look for the identifier. We also allow keywords here; for example `__attribute__ ((const))' is legal. */ token = cp_lexer_peek_token (parser->lexer); - if (token->type != CPP_NAME - && token->type != CPP_KEYWORD) - return error_mark_node; - /* Consume the token. */ - token = cp_lexer_consume_token (parser->lexer); - - /* Save away the identifier that indicates which attribute this is. */ - identifier = token->value; - attribute = build_tree_list (identifier, NULL_TREE); - - /* Peek at the next token. */ - token = cp_lexer_peek_token (parser->lexer); - /* If it's an `(', then parse the attribute arguments. */ - if (token->type == CPP_OPEN_PAREN) + if (token->type == CPP_NAME + || token->type == CPP_KEYWORD) { - tree arguments; + /* Consume the token. */ + token = cp_lexer_consume_token (parser->lexer); - arguments = (cp_parser_parenthesized_expression_list - (parser, true, /*non_constant_p=*/NULL)); - /* Save the identifier and arguments away. */ - TREE_VALUE (attribute) = arguments; - } + /* Save away the identifier that indicates which attribute + this is. */ + identifier = token->value; + attribute = build_tree_list (identifier, NULL_TREE); + + /* Peek at the next token. */ + token = cp_lexer_peek_token (parser->lexer); + /* If it's an `(', then parse the attribute arguments. */ + if (token->type == CPP_OPEN_PAREN) + { + tree arguments; - /* Add this attribute to the list. */ - TREE_CHAIN (attribute) = attribute_list; - attribute_list = attribute; + arguments = (cp_parser_parenthesized_expression_list + (parser, true, /*non_constant_p=*/NULL)); + /* Save the identifier and arguments away. */ + TREE_VALUE (attribute) = arguments; + } - /* Now, look for more attributes. */ - token = cp_lexer_peek_token (parser->lexer); - /* If the next token isn't a `,', we're done. */ + /* Add this attribute to the list. */ + TREE_CHAIN (attribute) = attribute_list; + attribute_list = attribute; + + /* Now, look for more attributes. */ + token = cp_lexer_peek_token (parser->lexer); + } + /* Now, look for more attributes. If the next token isn't a + `,', we're done. */ if (token->type != CPP_COMMA) break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7557c9e79dc4..d13ae5c69674 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2005-02-09 Mark Mitchell + + PR c++/19787 + * g++.dg/conversion/ambig1.C: New test. + + PR c++/19739 + * g++.dg/ext/attrib19.C: New test. + + PR c++/19762 + * g++.dg/template/dtor3.C: New test. + 2005-02-08 Mark Mitchell PR c++/19733 -- 2.47.2