Commit bbee94aa by Jason Merrill Committed by Jason Merrill

PR c++/89571 - ICE with ill-formed noexcept on constructor.

Earlier changes to defer instantiating a defaulted noexcept-specifier that
depends on yet-unparsed default member initializers broke this testcase,
where instantiation fails for another reason.  In this case there's no
reason to defer and try again later, so let's not.

	* pt.c (maybe_instantiate_noexcept): Only return false if defaulted.
	(regenerate_decl_from_template): Use it for noexcept-specs.

From-SVN: r269746
parent ad0a3085
2019-03-17 Jason Merrill <jason@redhat.com>
PR c++/89571 - ICE with ill-formed noexcept on constructor.
* pt.c (maybe_instantiate_noexcept): Only return false if defaulted.
(regenerate_decl_from_template): Use it for noexcept-specs.
2019-03-14 Jason Merrill <jason@redhat.com> 2019-03-14 Jason Merrill <jason@redhat.com>
* parser.c (cp_parser_decl_specifier_seq): Support C++20 * parser.c (cp_parser_decl_specifier_seq): Support C++20
......
...@@ -23991,12 +23991,18 @@ regenerate_decl_from_template (tree decl, tree tmpl, tree args) ...@@ -23991,12 +23991,18 @@ regenerate_decl_from_template (tree decl, tree tmpl, tree args)
if (args_depth > parms_depth) if (args_depth > parms_depth)
args = get_innermost_template_args (args, parms_depth); args = get_innermost_template_args (args, parms_depth);
specs = tsubst_exception_specification (TREE_TYPE (code_pattern), /* Instantiate a dynamic exception-specification. noexcept will be
args, tf_error, NULL_TREE, handled below. */
/*defer_ok*/false); if (tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (code_pattern)))
if (specs && specs != error_mark_node) if (TREE_VALUE (raises))
TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), {
specs); specs = tsubst_exception_specification (TREE_TYPE (code_pattern),
args, tf_error, NULL_TREE,
/*defer_ok*/false);
if (specs && specs != error_mark_node)
TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl),
specs);
}
/* Merge parameter declarations. */ /* Merge parameter declarations. */
decl_parm = skip_artificial_parms_for (decl, decl_parm = skip_artificial_parms_for (decl,
...@@ -24062,6 +24068,8 @@ regenerate_decl_from_template (tree decl, tree tmpl, tree args) ...@@ -24062,6 +24068,8 @@ regenerate_decl_from_template (tree decl, tree tmpl, tree args)
if (DECL_DECLARED_INLINE_P (code_pattern) if (DECL_DECLARED_INLINE_P (code_pattern)
&& !DECL_DECLARED_INLINE_P (decl)) && !DECL_DECLARED_INLINE_P (decl))
DECL_DECLARED_INLINE_P (decl) = 1; DECL_DECLARED_INLINE_P (decl) = 1;
maybe_instantiate_noexcept (decl, tf_error);
} }
else if (VAR_P (decl)) else if (VAR_P (decl))
{ {
...@@ -24187,7 +24195,13 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) ...@@ -24187,7 +24195,13 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
static hash_set<tree>* fns = new hash_set<tree>; static hash_set<tree>* fns = new hash_set<tree>;
bool added = false; bool added = false;
if (DEFERRED_NOEXCEPT_PATTERN (noex) == NULL_TREE) if (DEFERRED_NOEXCEPT_PATTERN (noex) == NULL_TREE)
spec = get_defaulted_eh_spec (fn, complain); {
spec = get_defaulted_eh_spec (fn, complain);
if (spec == error_mark_node)
/* This might have failed because of an unparsed DMI, so
let's try again later. */
return false;
}
else if (!(added = !fns->add (fn))) else if (!(added = !fns->add (fn)))
{ {
/* If hash_set::add returns true, the element was already there. */ /* If hash_set::add returns true, the element was already there. */
...@@ -24247,7 +24261,11 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) ...@@ -24247,7 +24261,11 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
fns->remove (fn); fns->remove (fn);
if (spec == error_mark_node) if (spec == error_mark_node)
return false; {
/* This failed with a hard error, so let's go with false. */
gcc_assert (seen_error ());
spec = noexcept_false_spec;
}
TREE_TYPE (fn) = build_exception_variant (fntype, spec); TREE_TYPE (fn) = build_exception_variant (fntype, spec);
} }
......
// PR c++/89571
// { dg-do compile { target c++11 } }
struct z8 {
constexpr static int qq /* = 0 */; // { dg-error "initializer" }
};
template<typename T>
struct kf {
kf (const kf &) noexcept (T::qq); // { dg-error "constant" }
};
struct lk {
kf<z8> e1;
};
template<typename T>
T &sc ();
struct b6 {
decltype (lk (sc<lk> ())) zz;
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment