diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2014-10-02 18:05:55 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2014-10-02 18:05:55 +0000 |
commit | 04bbdb1d08070dcc305d9de9e4d457fdee1116a5 (patch) | |
tree | 46375b3a304b70039984cb2f5164e74f2b071655 /gcc | |
parent | a3ac63c46fd51fd3a531ae08e9f457e89e5744f9 (diff) | |
download | gcc-04bbdb1d08070dcc305d9de9e4d457fdee1116a5.zip gcc-04bbdb1d08070dcc305d9de9e4d457fdee1116a5.tar.gz gcc-04bbdb1d08070dcc305d9de9e4d457fdee1116a5.tar.bz2 |
re PR c++/53025 ([C++11] noexcept operator depends on copy-elision)
/cp
2014-10-02 Paolo Carlini <paolo.carlini@oracle.com>
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 <paolo.carlini@oracle.com>
PR c++/53025
* g++.dg/cpp0x/noexcept23.C: New.
* g++.dg/cpp0x/noexcept24.C: Likewise.
From-SVN: r215813
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/call.c | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 5 | ||||
-rw-r--r-- | gcc/cp/parser.c | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/noexcept23.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/noexcept24.C | 22 |
8 files changed, 65 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a3cfa05..b5b3f59 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2014-10-02 Paolo Carlini <paolo.carlini@oracle.com> + + 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 <jason@redhat.com> PR c++/63362 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 3c8b338..347070c 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 14ec837..fe1651e 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 01b2fad..63ed1c0 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 f03e74c..d1dddff 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 760471c..d9aa1e5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-10-02 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/53025 + * g++.dg/cpp0x/noexcept23.C: New. + * g++.dg/cpp0x/noexcept24.C: Likewise. + 2014-10-02 Marek Polacek <polacek@redhat.com> * 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 0000000..5a01df4 --- /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 0000000..c17ddfa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept24.C @@ -0,0 +1,22 @@ +// PR c++/53025 +// { dg-do compile { target c++11 } } + +template<typename T> +struct A { + A() noexcept {} + A(const A&) noexcept(false) {} +}; + +template<typename T> +void a(A<T>) noexcept {} + +template<typename T> +void f() +{ + static_assert(!noexcept(a(A<T>{})), ""); +} + +void g() +{ + f<int>(); +} |