diff options
author | Jason Merrill <jason@redhat.com> | 2019-03-17 16:07:26 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2019-03-17 16:07:26 -0400 |
commit | bbee94aa67b316d188b0938e02a70def626a1dfd (patch) | |
tree | 18afb725972505b6173a0731a28c0470617f1b64 /gcc | |
parent | ad0a3085d740347ec9db7ce15315d426d384110f (diff) | |
download | gcc-bbee94aa67b316d188b0938e02a70def626a1dfd.zip gcc-bbee94aa67b316d188b0938e02a70def626a1dfd.tar.gz gcc-bbee94aa67b316d188b0938e02a70def626a1dfd.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/noexcept36.C | 22 |
3 files changed, 54 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6c96c24..34e9c79 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +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> * parser.c (cp_parser_decl_specifier_seq): Support C++20 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 2ab6e27..dc5c24c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -23991,12 +23991,18 @@ regenerate_decl_from_template (tree decl, tree tmpl, tree args) if (args_depth > parms_depth) args = get_innermost_template_args (args, parms_depth); - 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); + /* Instantiate a dynamic exception-specification. noexcept will be + handled below. */ + if (tree raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (code_pattern))) + if (TREE_VALUE (raises)) + { + 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. */ decl_parm = skip_artificial_parms_for (decl, @@ -24062,6 +24068,8 @@ regenerate_decl_from_template (tree decl, tree tmpl, tree args) if (DECL_DECLARED_INLINE_P (code_pattern) && !DECL_DECLARED_INLINE_P (decl)) DECL_DECLARED_INLINE_P (decl) = 1; + + maybe_instantiate_noexcept (decl, tf_error); } else if (VAR_P (decl)) { @@ -24187,7 +24195,13 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) static hash_set<tree>* fns = new hash_set<tree>; bool added = false; 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))) { /* If hash_set::add returns true, the element was already there. */ @@ -24247,7 +24261,11 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) fns->remove (fn); 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); } diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept36.C b/gcc/testsuite/g++.dg/cpp0x/noexcept36.C new file mode 100644 index 0000000..980a28c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept36.C @@ -0,0 +1,22 @@ +// 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; +}; |