diff options
author | Marek Polacek <polacek@redhat.com> | 2019-09-10 23:22:37 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2019-09-10 23:22:37 +0000 |
commit | 480c18e16fd69998266850b804024a7559f1bc70 (patch) | |
tree | 04ea0ec010a6b86907503414d1c6839a48d20fbb /gcc/cp | |
parent | d85569f63db86e656ecb79b81c74a906f27bf509 (diff) | |
download | gcc-480c18e16fd69998266850b804024a7559f1bc70.zip gcc-480c18e16fd69998266850b804024a7559f1bc70.tar.gz gcc-480c18e16fd69998266850b804024a7559f1bc70.tar.bz2 |
PR c++/91673 - ICE with noexcept in alias-declaration.
* parser.c (CP_PARSER_FLAGS_DELAY_NOEXCEPT): New parser flag.
(cp_parser_lambda_declarator_opt): Pass CP_PARSER_FLAGS_NONE to
cp_parser_exception_specification_opt.
(cp_parser_direct_declarator): Adjust a call to
cp_parser_exception_specification_opt.
(cp_parser_member_declaration): Pass CP_PARSER_FLAGS_DELAY_NOEXCEPT
to cp_parser_declarator if not processing a friend or typedef
declaration.
(cp_parser_late_noexcept_specifier): Adjust a call to
cp_parser_noexcept_specification_opt.
(cp_parser_noexcept_specification_opt): New parameter for parser flags,
drop the FRIEND_P parameter. Use the new parameter.
(cp_parser_exception_specification_opt): Likewise.
(cp_parser_transaction): Adjust a call to
cp_parser_noexcept_specification_opt.
(cp_parser_transaction_expression): Likewise.
* g++.dg/cpp1z/using7.C: New test.
* g++.dg/cpp1z/using8.C: New test.
From-SVN: r275617
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/cp/parser.c | 60 |
2 files changed, 54 insertions, 26 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 15b1fbf..0c37460 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,25 @@ 2019-09-10 Marek Polacek <polacek@redhat.com> + PR c++/91673 - ICE with noexcept in alias-declaration. + * parser.c (CP_PARSER_FLAGS_DELAY_NOEXCEPT): New parser flag. + (cp_parser_lambda_declarator_opt): Pass CP_PARSER_FLAGS_NONE to + cp_parser_exception_specification_opt. + (cp_parser_direct_declarator): Adjust a call to + cp_parser_exception_specification_opt. + (cp_parser_member_declaration): Pass CP_PARSER_FLAGS_DELAY_NOEXCEPT + to cp_parser_declarator if not processing a friend or typedef + declaration. + (cp_parser_late_noexcept_specifier): Adjust a call to + cp_parser_noexcept_specification_opt. + (cp_parser_noexcept_specification_opt): New parameter for parser flags, + drop the FRIEND_P parameter. Use the new parameter. + (cp_parser_exception_specification_opt): Likewise. + (cp_parser_transaction): Adjust a call to + cp_parser_noexcept_specification_opt. + (cp_parser_transaction_expression): Likewise. + +2019-09-10 Marek Polacek <polacek@redhat.com> + PR c++/91705 - constexpr evaluation rejects ++/-- on floats. * constexpr.c (cxx_eval_increment_expression): Call fold_simple on the offset. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index baa60b8..254a77b 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -247,8 +247,6 @@ static void cp_lexer_stop_debugging static cp_token_cache *cp_token_cache_new (cp_token *, cp_token *); -static tree cp_parser_noexcept_specification_opt - (cp_parser *, bool, bool *, bool, bool); static tree cp_parser_late_noexcept_specifier (cp_parser *, tree); static void noexcept_override_late_checks @@ -1830,7 +1828,9 @@ enum /* When parsing a decl-specifier-seq, only allow mutable or constexpr. */ CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR = 0x10, /* When parsing a decl-specifier-seq, allow missing typename. */ - CP_PARSER_FLAGS_TYPENAME_OPTIONAL = 0x20 + CP_PARSER_FLAGS_TYPENAME_OPTIONAL = 0x20, + /* When parsing of the noexcept-specifier should be delayed. */ + CP_PARSER_FLAGS_DELAY_NOEXCEPT = 0x40 }; /* This type is used for parameters and variables which hold @@ -2380,7 +2380,7 @@ static void cp_parser_explicit_instantiation static void cp_parser_explicit_specialization (cp_parser *); -/* Exception handling [gram.exception] */ +/* Exception handling [gram.except] */ static tree cp_parser_try_block (cp_parser *); @@ -2395,9 +2395,11 @@ static tree cp_parser_exception_declaration static tree cp_parser_throw_expression (cp_parser *); static tree cp_parser_exception_specification_opt - (cp_parser *, bool = false); + (cp_parser *, cp_parser_flags); static tree cp_parser_type_id_list (cp_parser *); +static tree cp_parser_noexcept_specification_opt + (cp_parser *, cp_parser_flags, bool, bool *, bool); /* GNU Extensions */ @@ -10938,7 +10940,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr) tx_qual = cp_parser_tx_qualifier_opt (parser); /* Parse optional exception specification. */ - exception_spec = cp_parser_exception_specification_opt (parser); + exception_spec + = cp_parser_exception_specification_opt (parser, CP_PARSER_FLAGS_NONE); std_attrs = cp_parser_std_attribute_spec_seq (parser); @@ -20877,7 +20880,7 @@ cp_parser_direct_declarator (cp_parser* parser, tree tx_qual = cp_parser_tx_qualifier_opt (parser); /* And the exception-specification. */ exception_specification - = cp_parser_exception_specification_opt (parser, friend_p); + = cp_parser_exception_specification_opt (parser, flags); attrs = cp_parser_std_attribute_spec_seq (parser); @@ -24780,11 +24783,15 @@ cp_parser_member_declaration (cp_parser* parser) tree asm_specification; int ctor_dtor_or_conv_p; bool static_p = (decl_specifiers.storage_class == sc_static); + cp_parser_flags flags = CP_PARSER_FLAGS_TYPENAME_OPTIONAL; + if (!friend_p + && !decl_spec_seq_has_spec_p (&decl_specifiers, ds_typedef)) + flags |= CP_PARSER_FLAGS_DELAY_NOEXCEPT; /* Parse the declarator. */ declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, - CP_PARSER_FLAGS_TYPENAME_OPTIONAL, + flags, &ctor_dtor_or_conv_p, /*parenthesized_p=*/NULL, /*member_p=*/true, @@ -25359,10 +25366,10 @@ cp_parser_late_noexcept_specifier (cp_parser *parser, tree default_arg) /* Parse the cached noexcept-specifier. */ tree parsed_arg = cp_parser_noexcept_specification_opt (parser, + CP_PARSER_FLAGS_NONE, /*require_constexpr=*/true, /*consumed_expr=*/NULL, - /*return_cond=*/false, - /*friend_p=*/false); + /*return_cond=*/false); /* Revert to the main lexer. */ cp_parser_pop_lexer (parser); @@ -25411,15 +25418,15 @@ noexcept_override_late_checks (tree type, tree fndecl) expression if parentheses follow noexcept, or return BOOLEAN_TRUE_NODE if there are no parentheses. CONSUMED_EXPR will be set accordingly. Otherwise, returns a noexcept specification unless RETURN_COND is true, - in which case a boolean condition is returned instead. If FRIEND_P is true, - the function with this noexcept-specification had the `friend' specifier. */ + in which case a boolean condition is returned instead. The parser flags + FLAGS is used to control parsing. */ static tree cp_parser_noexcept_specification_opt (cp_parser* parser, + cp_parser_flags flags, bool require_constexpr, bool* consumed_expr, - bool return_cond, - bool friend_p) + bool return_cond) { cp_token *token; const char *saved_message; @@ -25446,8 +25453,10 @@ cp_parser_noexcept_specification_opt (cp_parser* parser, /* No need to delay parsing for a number literal or true/false. */ && !literal_p && at_class_scope_p () - /* Don't delay parsing for friend member functions. */ - && !friend_p + /* We don't delay parsing for friend member functions, + alias-declarations, and typedefs, even though the standard seems + to require it. */ + && (flags & CP_PARSER_FLAGS_DELAY_NOEXCEPT) && TYPE_BEING_DEFINED (current_class_type) && !LAMBDA_TYPE_P (current_class_type)) return cp_parser_save_noexcept (parser); @@ -25522,11 +25531,11 @@ cp_parser_noexcept_specification_opt (cp_parser* parser, throw ( type-id-list [opt] ) Returns a TREE_LIST representing the exception-specification. The - TREE_VALUE of each node is a type. If FRIEND_P is true, the function - with this noexcept-specification had the `friend' specifier. */ + TREE_VALUE of each node is a type. The parser flags FLAGS is used to + control parsing. */ static tree -cp_parser_exception_specification_opt (cp_parser* parser, bool friend_p) +cp_parser_exception_specification_opt (cp_parser* parser, cp_parser_flags flags) { cp_token *token; tree type_id_list; @@ -25537,11 +25546,10 @@ cp_parser_exception_specification_opt (cp_parser* parser, bool friend_p) /* Is it a noexcept-specification? */ type_id_list - = cp_parser_noexcept_specification_opt (parser, + = cp_parser_noexcept_specification_opt (parser, flags, /*require_constexpr=*/true, /*consumed_expr=*/NULL, - /*return_cond=*/false, - friend_p); + /*return_cond=*/false); if (type_id_list != NULL_TREE) return type_id_list; @@ -41162,10 +41170,10 @@ cp_parser_transaction (cp_parser *parser, cp_token *token) } else noex = cp_parser_noexcept_specification_opt (parser, + CP_PARSER_FLAGS_NONE, /*require_constexpr=*/true, /*consumed_expr=*/NULL, - /*return_cond=*/true, - /*friend_p=*/false); + /*return_cond=*/true); /* Keep track if we're in the lexical scope of an outer transaction. */ new_in = this_in | (old_in & TM_STMT_ATTR_OUTER); @@ -41226,10 +41234,10 @@ cp_parser_transaction_expression (cp_parser *parser, enum rid keyword) /* Parse a noexcept specification. */ noex = cp_parser_noexcept_specification_opt (parser, + CP_PARSER_FLAGS_NONE, /*require_constexpr=*/false, &noex_expr, - /*return_cond=*/true, - /*friend_p=*/false); + /*return_cond=*/true); if (!noex || !noex_expr || cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN) |