except.c (expr_noexcept_p): Split out from finish_noexcept_expr.
authorJason Merrill <jason@redhat.com>
Sun, 25 Sep 2011 02:26:21 +0000 (22:26 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 25 Sep 2011 02:26:21 +0000 (22:26 -0400)
* except.c (expr_noexcept_p): Split out from finish_noexcept_expr.
* cp-tree.h: Declare it.
* method.c (walk_field_subobs): Use it.

From-SVN: r179158

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/except.c
gcc/cp/method.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/nsdmi-eh1.C [new file with mode: 0644]

index fc5436a..8c25746 100644 (file)
@@ -1,5 +1,9 @@
 2011-09-24  Jason Merrill  <jason@redhat.com>
 
+       * except.c (expr_noexcept_p): Split out from finish_noexcept_expr.
+       * cp-tree.h: Declare it.
+       * method.c (walk_field_subobs): Use it.
+
        * init.c (perform_member_init): Instantiate NSDMI here.
        * pt.c (tsubst_decl) [FIELD_DECL]: Not here.
 
index 2f93bba..0f7deb6 100644 (file)
@@ -5047,6 +5047,7 @@ extern tree build_throw                           (tree);
 extern int nothrow_libfn_p                     (const_tree);
 extern void check_handlers                     (tree);
 extern tree finish_noexcept_expr               (tree, tsubst_flags_t);
+extern bool expr_noexcept_p                    (tree, tsubst_flags_t);
 extern void perform_deferred_noexcept_checks   (void);
 extern bool nothrow_spec_p                     (const_tree);
 extern bool type_noexcept_p                    (const_tree);
index bfc520d..ceec858 100644 (file)
@@ -1125,14 +1125,27 @@ perform_deferred_noexcept_checks (void)
 tree
 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);
 
+  return (expr_noexcept_p (expr, complain)
+         ? boolean_true_node : boolean_false_node);
+}
+
+/* Returns whether EXPR is noexcept, possibly warning if allowed by
+   COMPLAIN.  */
+
+bool
+expr_noexcept_p (tree expr, tsubst_flags_t complain)
+{
+  tree fn;
+
+  if (expr == error_mark_node)
+    return false;
+
   fn = cp_walk_tree_without_duplicates (&expr, check_noexcept_r, 0);
   if (fn)
     {
@@ -1151,10 +1164,10 @@ finish_noexcept_expr (tree expr, tsubst_flags_t complain)
          else
            maybe_noexcept_warning (fn);
        }
-      return boolean_false_node;
+      return false;
     }
   else
-    return boolean_true_node;
+    return true;
 }
 
 /* Return true iff SPEC is throw() or noexcept(true).  */
index 734c23b..1316dfb 100644 (file)
@@ -1042,6 +1042,12 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
                inform (0, "initializer for %q+#D is invalid", field);
              if (trivial_p)
                *trivial_p = false;
+             /* Core 1351: If the field has an NSDMI that could throw, the
+                default constructor is noexcept(false).  FIXME this is
+                broken by deferred parsing and 1360 saying we can't
+                lazily declare a non-trivial default constructor.  */
+             if (spec_p && !expr_noexcept_p (DECL_INITIAL (field), complain))
+               *spec_p = noexcept_false_spec;
 
              /* Don't do the normal processing.  */
              continue;
index a8b10cd..5b73414 100644 (file)
@@ -1,5 +1,7 @@
 2011-09-24  Jason Merrill  <jason@redhat.com>
 
+       * g++.dg/cpp0x/nsdmi-eh1.C: New.
+
        * g++.dg/cpp0x/nsdmi-defer3.C: New.
 
        * g++.dg/cpp0x/nsdmi-defer1.C: New.
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-eh1.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-eh1.C
new file mode 100644 (file)
index 0000000..09c92d2
--- /dev/null
@@ -0,0 +1,18 @@
+// Core issue 1351
+// { dg-do run { xfail *-*-* } }
+// { dg-options -std=c++0x }
+
+bool fail;
+struct A
+{
+  int i = fail ? throw "noooooooo" : 42;
+};
+
+int main()
+{
+  A a1;
+  if (a1.i != 42) return 1;
+  fail = true;
+  try { A a2; }
+  catch (...) { }
+}