aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2019-09-10 23:22:37 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2019-09-10 23:22:37 +0000
commit480c18e16fd69998266850b804024a7559f1bc70 (patch)
tree04ea0ec010a6b86907503414d1c6839a48d20fbb /gcc/cp
parentd85569f63db86e656ecb79b81c74a906f27bf509 (diff)
downloadgcc-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/ChangeLog20
-rw-r--r--gcc/cp/parser.c60
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)