aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2019-03-17 16:07:26 -0400
committerJason Merrill <jason@gcc.gnu.org>2019-03-17 16:07:26 -0400
commitbbee94aa67b316d188b0938e02a70def626a1dfd (patch)
tree18afb725972505b6173a0731a28c0470617f1b64 /gcc
parentad0a3085d740347ec9db7ce15315d426d384110f (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/cp/pt.c34
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept36.C22
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;
+};