summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2017-10-23 19:06:37 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2017-10-23 19:06:37 +0000
commite176a9459c104f84e7a1be70a8c21402e330b4a2 (patch)
treed13759d2a3934d2bd328ea9ef4273a5ac58e9f73
parent0c3d6318825778641d9a3718d9ca77d4ccab097b (diff)
downloadgcc-e176a9459c104f84e7a1be70a8c21402e330b4a2.tar.gz
PR c++/77369 - wrong noexcept handling in C++14 and below
* tree.c (strip_typedefs): Canonicalize TYPE_RAISES_EXCEPTIONS. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254022 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/tree.c11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept31.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/noexcept-type13.C2
4 files changed, 25 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ed89364a16e..9514e9c1c27 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2017-10-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/77369 - wrong noexcept handling in C++14 and below
+ * tree.c (strip_typedefs): Canonicalize TYPE_RAISES_EXCEPTIONS.
+
2017-10-20 Nathan Sidwell <nathan@acm.org>
* class.c (layout_class_type): Cleanup as-base creation, determine
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 366f46f1506..48d40945af3 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1439,7 +1439,11 @@ strip_typedefs (tree t, bool *remove_attributes)
is_variant = true;
type = strip_typedefs (TREE_TYPE (t), remove_attributes);
- changed = type != TREE_TYPE (t) || is_variant;
+ tree canon_spec = (flag_noexcept_type
+ ? canonical_eh_spec (TYPE_RAISES_EXCEPTIONS (t))
+ : NULL_TREE);
+ changed = (type != TREE_TYPE (t) || is_variant
+ || TYPE_RAISES_EXCEPTIONS (t) != canon_spec);
for (arg_node = TYPE_ARG_TYPES (t);
arg_node;
@@ -1498,9 +1502,8 @@ strip_typedefs (tree t, bool *remove_attributes)
type_memfn_rqual (t));
}
- if (TYPE_RAISES_EXCEPTIONS (t))
- result = build_exception_variant (result,
- TYPE_RAISES_EXCEPTIONS (t));
+ if (canon_spec)
+ result = build_exception_variant (result, canon_spec);
if (TYPE_HAS_LATE_RETURN_TYPE (t))
TYPE_HAS_LATE_RETURN_TYPE (result) = 1;
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept31.C b/gcc/testsuite/g++.dg/cpp0x/noexcept31.C
new file mode 100644
index 00000000000..c4c0e7dd466
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/noexcept31.C
@@ -0,0 +1,12 @@
+// PR c++/77369
+// { dg-do compile { target c++11 } }
+
+template<typename F> int caller(F f) noexcept(noexcept(f())) { f(); return 0; }
+
+void func1() noexcept { }
+
+void func2() { throw 1; }
+
+int instantiate_caller_with_func1 = caller(func1);
+
+static_assert( !noexcept(caller(func2)), "" );
diff --git a/gcc/testsuite/g++.dg/cpp1z/noexcept-type13.C b/gcc/testsuite/g++.dg/cpp1z/noexcept-type13.C
index 8eb3be0bd61..b51d7af2b11 100644
--- a/gcc/testsuite/g++.dg/cpp1z/noexcept-type13.C
+++ b/gcc/testsuite/g++.dg/cpp1z/noexcept-type13.C
@@ -5,7 +5,7 @@
void foo () throw () {} // { dg-bogus "mangled name" }
template <class T>
-T bar (T x) { return x; } // { dg-warning "mangled name" "" { target c++14_down } }
+T bar (T x) { return x; }
void baz () { // { dg-bogus "mangled name" }
return (bar (foo)) ();