re PR c++/85363 (Throwing exception from member constructor (brace initializer vs...
authorMarek Polacek <polacek@redhat.com>
Wed, 16 May 2018 20:37:45 +0000 (20:37 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 16 May 2018 20:37:45 +0000 (20:37 +0000)
PR c++/85363
* call.c (set_flags_from_callee): Handle AGGR_INIT_EXPRs too.
* tree.c (bot_manip): Call set_flags_from_callee for
AGGR_INIT_EXPRs too.

* g++.dg/cpp0x/initlist-throw1.C: New test.
* g++.dg/cpp0x/initlist-throw2.C: New test.

From-SVN: r260300

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/initlist-throw1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/initlist-throw2.C [new file with mode: 0644]

index 3ccaebef47fb80b0849d0489a77bbc8b7f92b9a1..7d3f0c20ea77e033318f004fad8a5b2f3f0e2444 100644 (file)
@@ -1,3 +1,10 @@
+2018-05-16  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/85363
+       * call.c (set_flags_from_callee): Handle AGGR_INIT_EXPRs too.
+       * tree.c (bot_manip): Call set_flags_from_callee for
+       AGGR_INIT_EXPRs too.
+
 2018-05-15  Jason Merrill  <jason@redhat.com>
 
        * cp-tree.h (cp_expr): Remove copy constructor.
index 09a3618b0074dfcf0cdfc722a40f74f289104261..4d04785f2b9d373b625f48c1ab124e91a7566f91 100644 (file)
@@ -319,15 +319,17 @@ build_call_n (tree function, int n, ...)
 void
 set_flags_from_callee (tree call)
 {
-  bool nothrow;
-  tree decl = get_callee_fndecl (call);
+  /* Handle both CALL_EXPRs and AGGR_INIT_EXPRs.  */
+  tree decl = cp_get_callee_fndecl_nofold (call);
 
   /* We check both the decl and the type; a function may be known not to
      throw without being declared throw().  */
-  nothrow = decl && TREE_NOTHROW (decl);
-  if (CALL_EXPR_FN (call))
-    nothrow |= TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (call))));
-  else if (internal_fn_flags (CALL_EXPR_IFN (call)) & ECF_NOTHROW)
+  bool nothrow = decl && TREE_NOTHROW (decl);
+  tree callee = cp_get_callee (call);
+  if (callee)
+    nothrow |= TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (callee)));
+  else if (TREE_CODE (call) == CALL_EXPR
+          && internal_fn_flags (CALL_EXPR_IFN (call)) & ECF_NOTHROW)
     nothrow = true;
 
   if (!nothrow && at_function_scope_p () && cfun && cp_function_chain)
index ecb88df23b91563a6529f759e835395d5da88a21..db81da91676de35356c0973ca144dd7100a5e5f5 100644 (file)
@@ -2987,7 +2987,7 @@ bot_manip (tree* tp, int* walk_subtrees, void* data_)
 
   /* Make a copy of this node.  */
   t = copy_tree_r (tp, walk_subtrees, NULL);
-  if (TREE_CODE (*tp) == CALL_EXPR)
+  if (TREE_CODE (*tp) == CALL_EXPR || TREE_CODE (*tp) == AGGR_INIT_EXPR)
     set_flags_from_callee (*tp);
   if (data.clear_location && EXPR_HAS_LOCATION (*tp))
     SET_EXPR_LOCATION (*tp, input_location);
index 186fece0d327cfef2b741c15c09e13746577b63c..9eab3adfa40fc93ffc41b181acba0c677d30b90a 100644 (file)
@@ -1,4 +1,11 @@
+2018-05-16  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/85363
+       * g++.dg/cpp0x/initlist-throw1.C: New test.
+       * g++.dg/cpp0x/initlist-throw2.C: New test.
+
 2018-05-16 Carl Love  <cel@us.ibm.com>
+
        * gcc.target/powerpc/vsx-vector-6-be.c: Remove file.
        * gcc.target/powerpc/vsx-vector-6-be.p7.c: New test file.
        * gcc.target/powerpc/vsx-vector-6-be.p8.c: New test file.
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-throw1.C b/gcc/testsuite/g++.dg/cpp0x/initlist-throw1.C
new file mode 100644 (file)
index 0000000..264c6c7
--- /dev/null
@@ -0,0 +1,29 @@
+// PR c++/85363
+// { dg-do run { target c++11 } }
+
+int
+init (int f)
+{
+  throw f;
+}
+
+struct X {
+  X (int f) : n {init (f)} {}
+  int n;
+};
+
+struct P {
+  X x{20};
+};
+
+int
+main ()
+{
+  try {
+    P p {};
+  }
+  catch (int n) {
+    return 0;
+  }
+  return 1;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-throw2.C b/gcc/testsuite/g++.dg/cpp0x/initlist-throw2.C
new file mode 100644 (file)
index 0000000..2bb0583
--- /dev/null
@@ -0,0 +1,33 @@
+// PR c++/85363
+// { dg-do run { target c++11 } }
+
+int
+init (int f)
+{
+  throw f;
+}
+
+struct X {
+  X () : n {init (42)} {}
+  int n;
+};
+
+struct P {
+  struct R {
+    struct Q {
+      X x = {};
+    } q;
+  } r;
+};
+
+int
+main ()
+{
+  try {
+    P p {};
+  }
+  catch (int n) {
+    return 0;
+  }
+  return 1;
+}