re PR c++/48468 ([C++0x][SFINAE] noexcept operator does not handle function templates...
authorJason Merrill <jason@redhat.com>
Thu, 7 Apr 2011 21:48:00 +0000 (17:48 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 7 Apr 2011 21:48:00 +0000 (17:48 -0400)
PR c++/48468
* except.c (build_noexcept_spec): Propagate error_mark_node.
(finish_noexcept_expr): Likewise.

From-SVN: r172148

gcc/cp/ChangeLog
gcc/cp/except.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/noexcept02.C
gcc/testsuite/g++.dg/cpp0x/sfinae11.C [new file with mode: 0644]

index 04b9c402723d14fe32a0fafc3e3bea13e69053fb..d20cf5165a3905ba94a09c20725c17fea07cb720 100644 (file)
@@ -1,5 +1,9 @@
 2011-04-07  Jason Merrill  <jason@redhat.com>
 
+       PR c++/48468
+       * except.c (build_noexcept_spec): Propagate error_mark_node.
+       (finish_noexcept_expr): Likewise.
+
        PR c++/48452
        * typeck.c (build_x_compound_expr_from_list): Return error_mark_node
        in SFINAE context.
index a814d67865853ca04803eb996d2bf36c74ec7545..874f11150443a730d676d791e784aeae9143dce5 100644 (file)
@@ -1125,6 +1125,9 @@ finish_noexcept_expr (tree expr, tsubst_flags_t complain)
 {
   tree fn;
 
+  if (expr == error_mark_node)
+    return error_mark_node;
+
   if (processing_template_decl)
     return build_min (NOEXCEPT_EXPR, boolean_type_node, expr);
 
@@ -1212,6 +1215,8 @@ build_noexcept_spec (tree expr, int complain)
     return noexcept_true_spec;
   else if (expr == boolean_false_node)
     return noexcept_false_spec;
+  else if (expr == error_mark_node)
+    return error_mark_node;
   else
     {
       gcc_assert (processing_template_decl || expr == error_mark_node);
index 38f097208e53686a16898602a95e12108af4200a..dc446df8a0b87d6177b832b1c31af84a9ca6a16d 100644 (file)
@@ -1,5 +1,8 @@
 2011-04-07  Jason Merrill  <jason@redhat.com>
 
+       * g++.dg/cpp0x/sfinae11.C: New.
+       * g++.dg/cpp0x/noexcept02.C: Fix.
+
        * g++.dg/cpp0x/sfinae10.C: New.
 
        * g++.dg/cpp0x/sfinae9.C: New.
index be6fa00dd09127a24c98c9fb997becc7da5cd34d..60015e756681f4214e72fec206a262fb4c3fe4e0 100644 (file)
@@ -46,7 +46,9 @@ SA(!noexcept(f3(A())));
 template <class T1, class T2>
 void f (T1, T2) noexcept(noexcept(T1(), T2()));
 
-SA(noexcept(f3(1,1)));
+struct B { };
+
+SA(noexcept(f3(1,B())));
 SA(!noexcept(f3(1,A())));
 SA(!noexcept(f3(A(),1)));
 SA(!noexcept(f3(A(),A())));
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae11.C b/gcc/testsuite/g++.dg/cpp0x/sfinae11.C
new file mode 100644 (file)
index 0000000..a3ffc34
--- /dev/null
@@ -0,0 +1,56 @@
+// PR c++/48468
+// { dg-options -std=c++0x }
+// { dg-prune-output "note" }
+
+template<class T>
+T&& declval() noexcept;
+
+template< class T >
+inline void f1( T& x ) noexcept( noexcept( declval<T&>().foo() ) )
+{
+  x.foo();
+}
+
+template< class T,
+  bool Noexcept = noexcept( declval<T&>().foo() )
+>
+inline void f2( T& x ) noexcept( Noexcept )
+{
+  x.foo();
+}
+
+// a common and trivial mistake
+template< class T >
+inline void f3( T& x ) noexcept( declval<T&>().foo() )
+{
+  x.foo();
+}
+
+struct X
+{
+  void foo();
+};
+
+struct Y
+{
+  void foo() noexcept;
+};
+
+struct Z {};
+
+int main()
+{
+  X x; Y y; Z z;
+
+  static_assert( !noexcept( f1(x) ), "OK." );
+  static_assert( !noexcept( f2(x) ), "OK." );
+  // static_assert( !noexcept( f3(x) ), "shall be ill-formed(OK)." );
+
+  static_assert(  noexcept( f1(y) ), "OK." );
+  static_assert(  noexcept( f2(y) ), "OK." );
+  // static_assert(  noexcept( f3(y) ), "shall be ill-formed(OK)." );
+
+  static_assert(  noexcept( f1(z) ), "shall be ill-formed." ); // { dg-error "no match" }
+  static_assert(  noexcept( f2(z) ), "shall be ill-formed." ); // { dg-error "no match" }
+  static_assert( !noexcept( f3(z) ), "shall be ill-formed." ); // { dg-error "no match" }
+}