From: Giovanni Bajo Date: Thu, 28 Jul 2005 10:22:22 +0000 (+0000) Subject: Backport: X-Git-Tag: releases/gcc-3.4.5~302 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2604fb4f1750aaa4c4a3b7f9665a1effb5a0f258;p=thirdparty%2Fgcc.git Backport: 2004-09-16 Mark Mitchell PR c++/16002 * parser.c (cp_parser_simple_declaration): Commit to tentative parses after seeing a decl-specifier. (cp_parser_simple_declaration): Eliminate spurious message. (cp_parser_init_declarator): Adjust error message. 2005-06-17 Geoffrey Keating PR c++/17413 * pt.c (type_unification_real): Apply template type deduction even to procedure parameters that are not dependent on a template parameter. 2004-11-02 Mark Mitchell PR c++/18124 * parser.c (cp_parser_type_parameter): Robustify. PR c++/18155 * parser.c (cp_parser_single_declaration): Disallow template typedefs. (cp_parser_typedef_p): New function. 2004-12-21 Mark Mitchell PR c++/18378 * call.c (convert_like_real): Do not permit the use of a copy constructor to copy a packed field. Backport: 2004-09-16 Mark Mitchell PR c++/16002 * g++.dg/parse/error18.C: New test. * g++.dg/parse/crash11.C: Adjust error markers. 2005-06-17 Geoffrey Keating PR c++/17413 * g++.dg/template/local5.C: New. 2004-11-02 Mark Mitchell PR c++/18124 * g++.dg/template/crash25.C: New test. PR c++/18155 * g++.dg/template/typedef2.C: New test. * g++.dg/parse/crash13.C: Adjust error markers. 2004-12-21 Mark Mitchell PR c++/18378 * g++.dg/ext/packed8.C: New test. From-SVN: r102477 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 676dbcc2d08d..d10e55cf6238 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,33 @@ +2005-07-28 Giovanni Bajo + + Backport: + + 2004-09-16 Mark Mitchell + PR c++/16002 + * parser.c (cp_parser_simple_declaration): Commit to tentative + parses after seeing a decl-specifier. + (cp_parser_simple_declaration): Eliminate spurious message. + (cp_parser_init_declarator): Adjust error message. + + 2005-06-17 Geoffrey Keating + PR c++/17413 + * pt.c (type_unification_real): Apply template type deduction even + to procedure parameters that are not dependent on a template + parameter. + + 2004-11-02 Mark Mitchell + PR c++/18124 + * parser.c (cp_parser_type_parameter): Robustify. + PR c++/18155 + * parser.c (cp_parser_single_declaration): Disallow template + typedefs. + (cp_parser_typedef_p): New function. + + 2004-12-21 Mark Mitchell + PR c++/18378 + * call.c (convert_like_real): Do not permit the use of a copy + constructor to copy a packed field. + 2005-07-25 Giovanni Bajo PR c++/19208 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index aeed3155df4b..404c2ad12318 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4080,13 +4080,12 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner, if (NEED_TEMPORARY_P (convs) || !lvalue_p (expr)) { tree type = TREE_TYPE (TREE_OPERAND (convs, 0)); + cp_lvalue_kind lvalue = real_lvalue_p (expr); if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type))) { /* If the reference is volatile or non-const, we cannot create a temporary. */ - cp_lvalue_kind lvalue = real_lvalue_p (expr); - if (lvalue & clk_bitfield) error ("cannot bind bitfield `%E' to `%T'", expr, ref_type); @@ -4097,6 +4096,20 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner, error ("cannot bind rvalue `%E' to `%T'", expr, ref_type); return error_mark_node; } + /* If the source is a packed field, and we must use a copy + constructor, then building the target expr will require + binding the field to the reference parameter to the + copy constructor, and we'll end up with an infinite + loop. If we can use a bitwise copy, then we'll be + OK. */ + if ((lvalue & clk_packed) + && CLASS_TYPE_P (type) + && !TYPE_HAS_TRIVIAL_INIT_REF (type)) + { + error ("cannot bind packed field `%E' to `%T'", + expr, ref_type); + return error_mark_node; + } expr = build_target_expr_with_type (expr, type); } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d4ca762aba74..c59d40992b37 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1672,6 +1672,8 @@ static bool cp_parser_declares_only_class_p (cp_parser *); static bool cp_parser_friend_p (tree); +static bool cp_parser_typedef_p + (tree); static cp_token *cp_parser_require (cp_parser *, enum cpp_ttype, const char *); static cp_token *cp_parser_require_keyword @@ -6523,6 +6525,13 @@ cp_parser_simple_declaration (cp_parser* parser, /* Give up. */ goto done; } + + /* If we have seen at least one decl-specifier, and the next token + is not a parenthesis, then we must be looking at a declaration. + (After "int (" we might be looking at a functional cast.) */ + if (decl_specifiers + && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)) + cp_parser_commit_to_tentative_parse (parser); /* Keep going until we hit the `;' at the end of the simple declaration. */ @@ -6576,7 +6585,12 @@ cp_parser_simple_declaration (cp_parser* parser, /* Anything else is an error. */ else { - cp_parser_error (parser, "expected `,' or `;'"); + /* If we have already issued an error message we don't need + to issue another one. */ + if (decl != error_mark_node + || (cp_parser_parsing_tentatively (parser) + && !cp_parser_committed_to_tentative_parse (parser))) + cp_parser_error (parser, "expected `,' or `;'"); /* Skip tokens until we reach the end of the statement. */ cp_parser_skip_to_end_of_statement (parser); /* If the next token is now a `;', consume it. */ @@ -7802,9 +7816,15 @@ cp_parser_type_parameter (cp_parser* parser) if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ) && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER) && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)) - identifier = cp_parser_identifier (parser); + { + identifier = cp_parser_identifier (parser); + /* Treat invalid names as if the parameter were nameless. */ + if (identifier == error_mark_node) + identifier = NULL_TREE; + } else identifier = NULL_TREE; + /* Create the template parameter. */ parameter = finish_template_template_parm (class_type_node, identifier); @@ -7846,15 +7866,13 @@ cp_parser_type_parameter (cp_parser* parser) /* Create the combined representation of the parameter and the default argument. */ - parameter = build_tree_list (default_argument, parameter); + parameter = build_tree_list (default_argument, parameter); } break; default: - /* Anything else is an error. */ - cp_parser_error (parser, - "expected `class', `typename', or `template'"); - parameter = error_mark_node; + abort (); + break; } return parameter; @@ -10069,7 +10087,7 @@ cp_parser_init_declarator (cp_parser* parser, && token->type != CPP_COMMA && token->type != CPP_SEMICOLON) { - cp_parser_error (parser, "expected init-declarator"); + cp_parser_error (parser, "expected initializer"); return error_mark_node; } @@ -14511,6 +14529,12 @@ cp_parser_single_declaration (cp_parser* parser, tree attributes; bool function_definition_p = false; + /* This function is only used when processing a template + declaration. */ + if (innermost_scope_kind () != sk_template_parms + && innermost_scope_kind () != sk_template_spec) + abort (); + /* Defer access checks until we know what is being declared. */ push_deferring_access_checks (dk_deferred); @@ -14523,6 +14547,14 @@ cp_parser_single_declaration (cp_parser* parser, &declares_class_or_enum); if (friend_p) *friend_p = cp_parser_friend_p (decl_specifiers); + + /* There are no template typedefs. */ + if (cp_parser_typedef_p (decl_specifiers)) + { + error ("template declaration of `typedef'"); + decl = error_mark_node; + } + /* Gather up the access checks that occurred the decl-specifier-seq. */ stop_deferring_access_checks (); @@ -14539,8 +14571,6 @@ cp_parser_single_declaration (cp_parser* parser, decl = error_mark_node; } } - else - decl = NULL_TREE; /* If it's not a template class, try for a template function. If the next token is a `;', then this declaration does not declare anything. But, if there were errors in the decl-specifiers, then @@ -14566,7 +14596,8 @@ cp_parser_single_declaration (cp_parser* parser, parser->object_scope = NULL_TREE; /* Look for a trailing `;' after the declaration. */ if (!function_definition_p - && !cp_parser_require (parser, CPP_SEMICOLON, "`;'")) + && (decl == error_mark_node + || !cp_parser_require (parser, CPP_SEMICOLON, "`;'"))) cp_parser_skip_to_end_of_block_or_statement (parser); return decl; @@ -15032,6 +15063,27 @@ cp_parser_friend_p (tree decl_specifiers) return false; } +/* DECL_SPECIFIERS is the representation of a decl-specifier-seq. + Returns TRUE iff `typedef' appears among the DECL_SPECIFIERS. */ + +static bool +cp_parser_typedef_p (tree decl_specifiers) +{ + while (decl_specifiers) + { + /* See if this decl-specifier is `typedef'. */ + if (TREE_CODE (TREE_VALUE (decl_specifiers)) == IDENTIFIER_NODE + && C_RID_CODE (TREE_VALUE (decl_specifiers)) == RID_TYPEDEF) + return true; + + /* Go on to the next decl-specifier. */ + decl_specifiers = TREE_CHAIN (decl_specifiers); + } + + return false; +} + + /* If the next token is of the indicated TYPE, consume it. Otherwise, issue an error message indicating that TOKEN_DESC was expected. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c61b26b4134e..25e512e06088 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9166,17 +9166,12 @@ type_unification_real (tree tparms, else type = arg; - if (strict == DEDUCE_EXACT || strict == DEDUCE_ORDER) - { - if (same_type_p (parm, type)) - continue; - } - else - /* It might work; we shouldn't check now, because we might - get into infinite recursion. Overload resolution will - handle it. */ + if (same_type_p (parm, type)) continue; - + if (strict != DEDUCE_EXACT + && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg)) + continue; + return 1; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f15fe793cb6c..696d97664c39 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,27 @@ +2005-07-28 Giovanni Bajo + + Backport: + + 2004-09-16 Mark Mitchell + PR c++/16002 + * g++.dg/parse/error18.C: New test. + * g++.dg/parse/crash11.C: Adjust error markers. + + 2005-06-17 Geoffrey Keating + PR c++/17413 + * g++.dg/template/local5.C: New. + + 2004-11-02 Mark Mitchell + PR c++/18124 + * g++.dg/template/crash25.C: New test. + PR c++/18155 + * g++.dg/template/typedef2.C: New test. + * g++.dg/parse/crash13.C: Adjust error markers. + + 2004-12-21 Mark Mitchell + PR c++/18378 + * g++.dg/ext/packed8.C: New test. + 2005-07-28 Richard Sandiford PR c/22589 diff --git a/gcc/testsuite/g++.dg/parse/crash11.C b/gcc/testsuite/g++.dg/parse/crash11.C index 4893678d46f2..f988fa8a0bda 100644 --- a/gcc/testsuite/g++.dg/parse/crash11.C +++ b/gcc/testsuite/g++.dg/parse/crash11.C @@ -30,5 +30,5 @@ struct C }; int main() { - typedef B::Template::Type Type; // { dg-error "init-declarator|;" } + typedef B::Template::Type Type; // { dg-error "initializer" } } diff --git a/gcc/testsuite/g++.dg/parse/crash13.C b/gcc/testsuite/g++.dg/parse/crash13.C index d81b6a55e7a6..bd96bd1d6f12 100644 --- a/gcc/testsuite/g++.dg/parse/crash13.C +++ b/gcc/testsuite/g++.dg/parse/crash13.C @@ -13,7 +13,7 @@ struct A template void func(A::B* ) // { dg-error "variable|template|expression" } -{ // { dg-error ";" } +{ } int main() diff --git a/gcc/testsuite/g++.dg/parse/error18.C b/gcc/testsuite/g++.dg/parse/error18.C new file mode 100644 index 000000000000..363aae998798 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/error18.C @@ -0,0 +1,7 @@ +// PR c++/16002 + +void f() +{ + double Q *= 5.0; // { dg-error "initializer" } +} +