diff options
author | Marek Polacek <polacek@redhat.com> | 2018-05-16 20:37:45 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2018-05-16 20:37:45 +0000 |
commit | 0932d398ef91373c74d8ad08f26f484206bc8fc9 (patch) | |
tree | f07207965ef5224f6862314f5e9d2f16fbee6150 | |
parent | 110fb19f6c6a4a9dfb9cfe00d3295cccf5b00507 (diff) | |
download | gcc-0932d398ef91373c74d8ad08f26f484206bc8fc9.zip gcc-0932d398ef91373c74d8ad08f26f484206bc8fc9.tar.gz gcc-0932d398ef91373c74d8ad08f26f484206bc8fc9.tar.bz2 |
re PR c++/85363 (Throwing exception from member constructor (brace initializer vs initializer list))
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
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/call.c | 14 | ||||
-rw-r--r-- | gcc/cp/tree.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist-throw1.C | 29 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/initlist-throw2.C | 33 |
6 files changed, 85 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3ccaebe..7d3f0c2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 09a3618..4d04785 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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) diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index ecb88df..db81da9 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 186fece..9eab3ad 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..264c6c7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-throw1.C @@ -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 index 0000000..2bb0583 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-throw2.C @@ -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; +} |