Skip to content

Commit 3251cbc

Browse files
committed
Consider explicit conversions before aggregate fallback []
Allow explicit conversion functions when matching the implicit copy constructor during single-argument direct-initialization, preventing premature C++20 aggregate fallback. Extend EDGcpfe24743 to cover explicit conversion functions. Signed-off-by: Yihan Wang <yronglin777@gmail.com>
1 parent f0e30b6 commit 3251cbc

5 files changed

Lines changed: 16 additions & 20 deletions

File tree

‎src/expr.c‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30702,11 +30702,15 @@ parentheses do not themselves correspond to aggregate initialization).
3070230702
an_arg_match_summary arg_match;
3070330703
an_operand opnd;
3070430704
clear_arg_match_summary(&arg_match);
30705+
/* When matching the first reference parameter of a copy constructor
30706+
called with one argument in a direct-initialization context, explicit
30707+
conversion functions are considered ([over.match.copy]). */
3070530708
prep_list_initializer(arg_list, dest_type, /*is_direct_init=*/TRUE,
3070630709
/*check_narrowing=*/FALSE,
3070730710
/*warning_on_narrowing=*/FALSE,
3070830711
CCO_CAST | CCO_FUNC_NOTATION_CAST |
30709-
CCO_EXPLICIT_CAST | CCO_DIRECT_INITIALIZATION,
30712+
CCO_EXPLICIT_CAST | CCO_DIRECT_INITIALIZATION |
30713+
CCO_ALLOW_EXPLICIT_CONV_FUNCTIONS,
3071030714
/*fill_in_dtor=*/TRUE, /*force_temp=*/FALSE,
3071130715
/*make_lvalue_temp=*/FALSE,
3071230716
&opnd, (an_init_state*)NULL, &arg_match);

‎src/overload.c‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27542,7 +27542,9 @@ will be an lvalue instead of the usual prvalue.
2754227542
(a_param_type_ptr)NULL,
2754327543
/*param_type_is_deduced=*/FALSE,
2754427544
try_user_conversions_in_ovl_res,
27545-
/*allow_expl_conv_funcs=*/FALSE,
27545+
/*allow_expl_conv_funcs=*/
27546+
(conv_context &
27547+
CCO_ALLOW_EXPLICIT_CONV_FUNCTIONS) != 0,
2754627548
arg_match);
2754727549
} /* if */
2754827550
} else {

‎tests/tests/changes/EDGcpfe24743.sft.cpp‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,9 @@ struct S { operator D() const; };
1515
void g(S p) {
1616
D d(p); // Previously an error. Now okay.
1717
}
18+
19+
struct ExplicitS { explicit operator D() const; };
20+
D h(ExplicitS p) {
21+
D d(p); // Previously an error in C++20 mode. Now okay.
22+
return D(p); // Likewise.
23+
}

‎tests/tests/imported/clang/cpp/SemaCXX/.cxx2a-explicit-bool.rto/default.2.1.txt‎

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -476,14 +476,6 @@ fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
476476
Y y2 = z; // expected-error {{no viable conversion}}
477477
^
478478

479-
"Test_name.c", line 530: error: too many initializer values
480-
Y y2b(z);
481-
^
482-
483-
"Test_name.c", line 532: error: too many initializer values
484-
Y y4 = Y(z);
485-
^
486-
487479
"Test_name.c", line 540: error: no suitable user-defined conversion from "conversion3::Z<true>" to "const conversion3::Y" exists
488480
const Y& y6 = z; // expected-error {{no viable conversion}}
489481
^
@@ -683,4 +675,4 @@ fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
683675
explicit(ptr) S(long); // expected-error {{conversion from 'const int *' to 'bool' is not allowed in a converted constant expression}}
684676
^
685677

686-
121 errors detected in the compilation of "Test_name.c".
678+
119 errors detected in the compilation of "Test_name.c".

‎tests/tests/imported/clang/cpp/SemaCXX/.explicit.rto/default.2.1.txt‎

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,6 @@ fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
2323
Y y2 = z; // expected-error {{no viable conversion from 'Z' to 'Y'}}
2424
^
2525

26-
"Test_name.c", line 90: error: too many initializer values
27-
Y y2b(z);
28-
^
29-
30-
"Test_name.c", line 92: error: too many initializer values
31-
Y y4 = Y(z);
32-
^
33-
3426
"Test_name.c", line 100: error: no suitable user-defined conversion from "Z" to "const Y" exists
3527
const Y& y6 = z; // expected-error {{no viable conversion from 'Z' to 'const Y'}}
3628
^
@@ -171,4 +163,4 @@ fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
171163
switch(EC){}
172164
^
173165

174-
31 errors detected in the compilation of "Test_name.c".
166+
29 errors detected in the compilation of "Test_name.c".

0 commit comments

Comments
 (0)