Index: cp/call.c =================================================================== --- cp/call.c (revision 215801) +++ cp/call.c (working copy) @@ -7251,7 +7251,11 @@ build_over_call (struct z_candidate *cand, int fla /* 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)]; Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 215801) +++ cp/cp-tree.h (working copy) @@ -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; Index: cp/name-lookup.c =================================================================== --- cp/name-lookup.c (revision 215801) +++ cp/name-lookup.c (working copy) @@ -6139,6 +6139,7 @@ push_to_top_level (void) s->function_decl = current_function_decl; s->unevaluated_operand = cp_unevaluated_operand; s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; + s->noexcept_operand = scope_chain ? cp_noexcept_operand : 0; s->x_stmt_tree.stmts_are_full_exprs_p = true; scope_chain = s; @@ -6182,6 +6183,7 @@ pop_from_top_level_1 (void) current_function_decl = s->function_decl; cp_unevaluated_operand = s->unevaluated_operand; c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings; + cp_noexcept_operand = s->noexcept_operand; } /* Wrapper for pop_from_top_level_1. */ Index: cp/parser.c =================================================================== --- cp/parser.c (revision 215801) +++ cp/parser.c (working copy) @@ -7156,7 +7156,9 @@ cp_parser_unary_expression (cp_parser *parser, boo ++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; Index: cp/pt.c =================================================================== --- cp/pt.c (revision 215801) +++ cp/pt.c (working copy) @@ -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: Index: testsuite/g++.dg/cpp0x/noexcept23.C =================================================================== --- testsuite/g++.dg/cpp0x/noexcept23.C (revision 0) +++ testsuite/g++.dg/cpp0x/noexcept23.C (working copy) @@ -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{})), ""); +} Index: testsuite/g++.dg/cpp0x/noexcept24.C =================================================================== --- testsuite/g++.dg/cpp0x/noexcept24.C (revision 0) +++ testsuite/g++.dg/cpp0x/noexcept24.C (working copy) @@ -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(); +}