PR c++/77369 - wrong noexcept handling in C++14 and below
authorJason Merrill <jason@redhat.com>
Mon, 23 Oct 2017 19:06:37 +0000 (15:06 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 23 Oct 2017 19:06:37 +0000 (15:06 -0400)
* tree.c (strip_typedefs): Canonicalize TYPE_RAISES_EXCEPTIONS.

From-SVN: r254022

gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/g++.dg/cpp0x/noexcept31.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/noexcept-type13.C

index ed89364a16ebfb50b8aa89e679f40385527506f5..9514e9c1c27892b9a9051564891f7181237d01b5 100644 (file)
@@ -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
index 366f46f150656a882fdabfddebd2fcd7b25e129c..48d40945af397de533d039474d325a8152a6ead3 100644 (file)
@@ -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 (file)
index 0000000..c4c0e7d
--- /dev/null
@@ -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)), "" );
index 8eb3be0bd610203ba1a68af646ebf04a10fa7050..b51d7af2b11ffaba0c0baebd217d6fde1d8937f9 100644 (file)
@@ -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)) ();