===================================================================
@@ -7249,9 +7249,14 @@ build_over_call (struct z_candidate *cand, int fla
if (! flag_elide_constructors)
/* Do things the hard way. */;
- else if (cand->num_convs == 1
- && (DECL_COPY_CONSTRUCTOR_P (fn)
- || DECL_MOVE_CONSTRUCTOR_P (fn)))
+ else if ((cand->num_convs == 1
+ && (DECL_COPY_CONSTRUCTOR_P (fn)
+ || DECL_MOVE_CONSTRUCTOR_P (fn)))
+ && (flag_elide_constructors == 1
+ || (flag_elide_constructors == 2
+ && (!DEFERRED_NOEXCEPT_SPEC_P
+ (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
+ && type_noexcept_p (TREE_TYPE (fn))))))
{
tree targ;
tree arg = argarray[num_artificial_parms_for (fn)];
===================================================================
@@ -7136,10 +7136,15 @@ cp_parser_unary_expression (cp_parser *parser, boo
bool saved_integral_constant_expression_p;
bool saved_non_integral_constant_expression_p;
bool saved_greater_than_is_operator_p;
+ int saved_flag_elide_constructors;
cp_lexer_consume_token (parser->lexer);
cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+ saved_flag_elide_constructors = flag_elide_constructors;
+ if (flag_elide_constructors == 1)
+ flag_elide_constructors = 2;
+
saved_message = parser->type_definition_forbidden_message;
parser->type_definition_forbidden_message
= G_("types may not be defined in %<noexcept%> expressions");
@@ -7170,6 +7175,8 @@ cp_parser_unary_expression (cp_parser *parser, boo
parser->type_definition_forbidden_message = saved_message;
+ flag_elide_constructors = saved_flag_elide_constructors;
+
cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
return finish_noexcept_expr (expr, tf_warning_or_error);
}
===================================================================
@@ -14766,15 +14766,22 @@ tsubst_copy_and_build (tree t,
}
case NOEXCEPT_EXPR:
- op1 = TREE_OPERAND (t, 0);
- ++cp_unevaluated_operand;
- ++c_inhibit_evaluation_warnings;
- 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;
- RETURN (finish_noexcept_expr (op1, complain));
+ {
+ int saved_flag_elide_constructors;
+ op1 = TREE_OPERAND (t, 0);
+ ++cp_unevaluated_operand;
+ ++c_inhibit_evaluation_warnings;
+ saved_flag_elide_constructors = flag_elide_constructors;
+ if (flag_elide_constructors == 1)
+ flag_elide_constructors = 2;
+ op1 = tsubst_copy_and_build (op1, args, complain, in_decl,
+ /*function_p=*/false,
+ /*integral_constant_expression_p=*/false);
+ flag_elide_constructors = saved_flag_elide_constructors;
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
+ RETURN (finish_noexcept_expr (op1, complain));
+ }
case MODOP_EXPR:
{
===================================================================
@@ -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{})), "");
+}
===================================================================
@@ -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>();
+}