From: Paolo Carlini Date: Thu, 2 Oct 2014 18:05:55 +0000 (+0000) Subject: re PR c++/53025 ([C++11] noexcept operator depends on copy-elision) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=04bbdb1d08070dcc305d9de9e4d457fdee1116a5;p=gcc.git re PR c++/53025 ([C++11] noexcept operator depends on copy-elision) /cp 2014-10-02 Paolo Carlini PR c++/53025 * cp-tree.h (struct saved_scope): Add noexcept_operand. (cp_noexcept_operand): Define. * call.c (build_over_call): Use it. * parser.c (cp_parser_unary_expression, [RID_NOEXCEPT]): Likewise. * pt.c (tsubst_copy_and_build, [NOEXCEPT_EXPR]): Likewise. /testsuite 2014-10-02 Paolo Carlini PR c++/53025 * g++.dg/cpp0x/noexcept23.C: New. * g++.dg/cpp0x/noexcept24.C: Likewise. From-SVN: r215813 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a3cfa05e23d..b5b3f596bd8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2014-10-02 Paolo Carlini + + PR c++/53025 + * cp-tree.h (struct saved_scope): Add noexcept_operand. + (cp_noexcept_operand): Define. + * call.c (build_over_call): Use it. + * parser.c (cp_parser_unary_expression, [RID_NOEXCEPT]): Likewise. + * pt.c (tsubst_copy_and_build, [NOEXCEPT_EXPR]): Likewise. + 2014-10-01 Jason Merrill PR c++/63362 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 3c8b338382a..347070c9c96 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7251,7 +7251,11 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) /* Do things the hard way. */; else if (cand->num_convs == 1 && (DECL_COPY_CONSTRUCTOR_P (fn) - || DECL_MOVE_CONSTRUCTOR_P (fn))) + || DECL_MOVE_CONSTRUCTOR_P (fn)) + /* It's unsafe to elide the constructor when handling + a noexcept-expression, it may evaluate to the wrong + value (c++/53025). */ + && cp_noexcept_operand == 0) { tree targ; tree arg = argarray[num_artificial_parms_for (fn)]; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 14ec837dc9c..fe1651ef010 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1058,6 +1058,7 @@ struct GTY(()) saved_scope { int unevaluated_operand; int inhibit_evaluation_warnings; + int noexcept_operand; /* If non-zero, implicit "omp declare target" attribute is added into the attribute lists. */ int omp_declare_target_attribute; @@ -1124,6 +1125,10 @@ struct GTY(()) saved_scope { #define local_specializations scope_chain->x_local_specializations +/* Nonzero if we are parsing the operand of a noexcept operator. */ + +#define cp_noexcept_operand scope_chain->noexcept_operand + /* A list of private types mentioned, for deferred access checking. */ extern GTY(()) struct saved_scope *scope_chain; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 01b2fadfe01..63ed1c0dfea 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7156,7 +7156,9 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p, ++cp_unevaluated_operand; ++c_inhibit_evaluation_warnings; + ++cp_noexcept_operand; expr = cp_parser_expression (parser); + --cp_noexcept_operand; --c_inhibit_evaluation_warnings; --cp_unevaluated_operand; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f03e74cd514..d1dddff3ac2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14769,11 +14769,13 @@ tsubst_copy_and_build (tree t, op1 = TREE_OPERAND (t, 0); ++cp_unevaluated_operand; ++c_inhibit_evaluation_warnings; + ++cp_noexcept_operand; op1 = tsubst_copy_and_build (op1, args, complain, in_decl, /*function_p=*/false, /*integral_constant_expression_p=*/false); --cp_unevaluated_operand; --c_inhibit_evaluation_warnings; + --cp_noexcept_operand; RETURN (finish_noexcept_expr (op1, complain)); case MODOP_EXPR: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 760471c450d..d9aa1e5dd21 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-10-02 Paolo Carlini + + PR c++/53025 + * g++.dg/cpp0x/noexcept23.C: New. + * g++.dg/cpp0x/noexcept24.C: Likewise. + 2014-10-02 Marek Polacek * gcc.dg/noncompile/20020130-1.c: Use -std=gnu89. diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept23.C b/gcc/testsuite/g++.dg/cpp0x/noexcept23.C new file mode 100644 index 00000000000..5a01df46c65 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept23.C @@ -0,0 +1,14 @@ +// PR c++/53025 +// { dg-do compile { target c++11 } } + +struct A { + A() noexcept {} + A(const A&) noexcept(false) {} +}; + +void a(A) noexcept {} + +void f() +{ + static_assert(!noexcept(a(A{})), ""); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept24.C b/gcc/testsuite/g++.dg/cpp0x/noexcept24.C new file mode 100644 index 00000000000..c17ddfa52a7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept24.C @@ -0,0 +1,22 @@ +// PR c++/53025 +// { dg-do compile { target c++11 } } + +template +struct A { + A() noexcept {} + A(const A&) noexcept(false) {} +}; + +template +void a(A) noexcept {} + +template +void f() +{ + static_assert(!noexcept(a(A{})), ""); +} + +void g() +{ + f(); +}