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
This commit is contained in:
parent
d85569f63d
commit
480c18e16f
5 changed files with 105 additions and 26 deletions
|
@ -1,3 +1,23 @@
|
|||
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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2019-09-10 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/91673 - ICE with noexcept in alias-declaration.
|
||||
* g++.dg/cpp1z/using7.C: New test.
|
||||
* g++.dg/cpp1z/using8.C: New test.
|
||||
|
||||
2019-09-10 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/91705 - constexpr evaluation rejects ++/-- on floats.
|
||||
|
|
33
gcc/testsuite/g++.dg/cpp1z/using7.C
Normal file
33
gcc/testsuite/g++.dg/cpp1z/using7.C
Normal file
|
@ -0,0 +1,33 @@
|
|||
// PR c++/91673 - ICE with noexcept in alias-declaration.
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
template<typename T, bool B>
|
||||
using U1 = T() noexcept(B);
|
||||
|
||||
template<bool B>
|
||||
struct S {
|
||||
int I;
|
||||
static constexpr bool b = true;
|
||||
|
||||
template<typename T>
|
||||
using U2 = T() noexcept(B);
|
||||
|
||||
template<typename T>
|
||||
using U8 = T() noexcept(b);
|
||||
|
||||
template<typename T>
|
||||
using U10 = T(int p) noexcept(noexcept(p));
|
||||
|
||||
template<typename T, bool B2>
|
||||
using U11 = T() noexcept(B2);
|
||||
|
||||
using U3 = void() noexcept(B);
|
||||
using U9 = void() noexcept(b);
|
||||
using U4 = void() noexcept(noexcept (I));
|
||||
using U5 = void(int p) noexcept(noexcept(p));
|
||||
|
||||
typedef void(*T1)() noexcept(B);
|
||||
typedef void(*T2)(int p) noexcept(noexcept(p));
|
||||
};
|
||||
|
||||
S<true> s;
|
12
gcc/testsuite/g++.dg/cpp1z/using8.C
Normal file
12
gcc/testsuite/g++.dg/cpp1z/using8.C
Normal file
|
@ -0,0 +1,12 @@
|
|||
// PR c++/91673 - ICE with noexcept in alias-declaration.
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
template<typename Sig>
|
||||
struct overload;
|
||||
|
||||
template<typename Ret, typename... Args, bool NoExcept>
|
||||
struct overload<Ret(Args...) noexcept(NoExcept)> {
|
||||
using signature_t = Ret(Args...) noexcept(NoExcept);
|
||||
};
|
||||
|
||||
overload<void()> x;
|
Loading…
Add table
Reference in a new issue