aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2019-02-19 21:00:29 -0500
committerJason Merrill <jason@gcc.gnu.org>2019-02-19 21:00:29 -0500
commit9d35a27a8353b57ed11fa1cb7d747edf1c4faa01 (patch)
treedd8f6590bbce03b4e8b1c01a6fae5791f01696f6 /gcc
parent8dca1dc386b4b87558ed80b12a3d700908baeac0 (diff)
downloadgcc-9d35a27a8353b57ed11fa1cb7d747edf1c4faa01.zip
gcc-9d35a27a8353b57ed11fa1cb7d747edf1c4faa01.tar.gz
gcc-9d35a27a8353b57ed11fa1cb7d747edf1c4faa01.tar.bz2
PR c++/88368 - wrong 'use of deleted function'
Since my patch for 81359 allowed us to signal failure on return from maybe_instantiate_noexcept, we no longer need to turn an error into noexcept(false). We also need to handle NSDMI instantiation errors under synthesized_method_walk. This change caused some instantiation context notes to be lost in the testsuite, so I added push_tinst_level to get_defaulted_eh_spec to restore that context. * method.c (walk_field_subobs): Remember errors from get_nsdmi. (get_defaulted_eh_spec): Call push_tinst_level. * pt.c (maybe_instantiate_noexcept): Keep error_mark_node. * typeck2.c (merge_exception_specifiers): Handle error_mark_node. From-SVN: r269032
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/method.c10
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/typeck2.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi3.C3
-rw-r--r--gcc/testsuite/g++.dg/ext/is_constructible3.C17
6 files changed, 39 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9c42190..3fe0ced 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2019-02-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/88368 - wrong 'use of deleted function'
+ * method.c (walk_field_subobs): Remember errors from get_nsdmi.
+ (get_defaulted_eh_spec): Call push_tinst_level.
+ * pt.c (maybe_instantiate_noexcept): Keep error_mark_node.
+ * typeck2.c (merge_exception_specifiers): Handle error_mark_node.
+
2019-02-19 Chung-Lin Tang <cltang@codesourcery.com>
PR c/87924
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index a5f2304..6e0df68 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1367,7 +1367,10 @@ walk_field_subobs (tree fields, special_function_kind sfk, tree fnname,
if (spec_p)
{
tree nsdmi = get_nsdmi (field, /*ctor*/false, complain);
- if (!expr_noexcept_p (nsdmi, complain))
+ if (nsdmi == error_mark_node)
+ *spec_p = error_mark_node;
+ else if (*spec_p != error_mark_node
+ && !expr_noexcept_p (nsdmi, complain))
*spec_p = noexcept_false_spec;
}
/* Don't do the normal processing. */
@@ -1753,8 +1756,13 @@ get_defaulted_eh_spec (tree decl, tsubst_flags_t complain)
if (SFK_DTOR_P (sfk) && DECL_VIRTUAL_P (decl))
/* We have to examine virtual bases even if abstract. */
sfk = sfk_virtual_destructor;
+ bool pushed = false;
+ if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
+ pushed = push_tinst_level (decl);
synthesized_method_walk (ctype, sfk, const_p, &spec, NULL, NULL,
NULL, diag, &inh, parms);
+ if (pushed)
+ pop_tinst_level ();
return spec;
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d8be92d..a69a17a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -24199,8 +24199,6 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
pop_deferring_access_checks ();
pop_access_scope (fn);
pop_tinst_level ();
- if (spec == error_mark_node)
- spec = noexcept_false_spec;
}
else
spec = noexcept_false_spec;
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index ac2c253..4e4b1f0 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -2363,6 +2363,9 @@ merge_exception_specifiers (tree list, tree add)
{
tree noex, orig_list;
+ if (list == error_mark_node || add == error_mark_node)
+ return error_mark_node;
+
/* No exception-specifier or noexcept(false) are less strict than
anything else. Prefer the newer variant (LIST). */
if (!list || list == noexcept_false_spec)
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C
index d2e7439..8276eab 100644
--- a/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi3.C
@@ -13,6 +13,7 @@ struct B
A a3 = { 3 }; // { dg-error "explicit" }
};
-constexpr B b; // { dg-error "B::B" }
+constexpr B b;
+// { dg-prune-output "B::B. is not usable" }
// { dg-prune-output "B::a1" }
diff --git a/gcc/testsuite/g++.dg/ext/is_constructible3.C b/gcc/testsuite/g++.dg/ext/is_constructible3.C
new file mode 100644
index 0000000..c7c5874
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_constructible3.C
@@ -0,0 +1,17 @@
+// PR c++/88368
+// { dg-do compile { target c++11 } }
+
+struct A {
+
+ struct B {
+ int I = 1;
+ B() = default;
+ };
+
+ static constexpr bool v = __is_constructible (B);
+
+};
+
+void print() {
+ A::B BB;
+}