Repository navigation
Consider explicit conversions before aggregate fallback [GH #222] #222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,20 @@ | ||
| 10/12/26 [GH #281] | ||
| Explicit conversion functions before parenthesized aggregate initialization | ||
|
|
||
| The front end could incorrectly attempt parenthesized aggregate initialization | ||
| instead of considering an explicit conversion function when directly | ||
| initializing an aggregate in C++20 mode. For example: | ||
|
|
||
| struct D { float x, y; }; | ||
| struct S { explicit operator D() const; }; | ||
| D f(S s) { | ||
| D d(s); // Previously an error in C++20 mode. Now okay. | ||
| return D(s); // Likewise. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To keep the Changes example as short as possible, you can just use |
||
| } | ||
|
|
||
| That is now fixed. The rule allowing explicit conversion functions in this | ||
| context comes from Core issue 899 and applies in C++11 and later modes. The | ||
| failure occurred when C++20 parenthesized aggregate initialization was enabled. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The following example is now accepted in C++11 mode: int f(int &&);
int f(int *);
struct A {
explicit operator int() const;
};
int i = f({A{}});Seems to be related to EDGcpfe/21369. g++/clang don't accept this. Needs some more investigation, and should be mentioned in the Changes entry (if we want to keep that behaviour). |
||
| Version 7.1 | ||
|
|
||
| 10/9/26 [GH #27] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27551,7 +27551,9 @@ will be an lvalue instead of the usual prvalue. | |
| (a_param_type_ptr)NULL, | ||
| /*param_type_is_deduced=*/FALSE, | ||
| try_user_conversions_in_ovl_res, | ||
| /*allow_expl_conv_funcs=*/FALSE, | ||
| /*allow_expl_conv_funcs=*/ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That comment line can now be removed, as the expression is now sufficiently clear on its own. |
||
| (conv_context & | ||
| CCO_ALLOW_EXPLICIT_CONV_FUNCTIONS) != 0, | ||
| arg_match); | ||
| } /* if */ | ||
| } else { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| fe_only -DTEST_NUMBER=1 -tused --c++11 Test_name.c |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| fe_only -DTEST_NUMBER=2 -tused --c++11 --gnu_version 160200 Test_name.c |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| fe_only -DTEST_NUMBER=3 -tused --c++11 --clang_version 230100 Test_name.c |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| fe_only -DTEST_NUMBER=4 -tused --c++20 Test_name.c |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| fe_only -DTEST_NUMBER=5 -tused --c++20 --gnu_version 160200 Test_name.c |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| fe_only -DTEST_NUMBER=6 -tused --c++20 --clang_version 230100 Test_name.c |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| fe_only -DTEST_NUMBER=7 -tused --ms_c++20 --microsoft_version 1950 Test_name.c |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| //type:fp | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the |
||
| //options:--c++11:--c++11 --gnu_version 160200:--c++11 --clang_version 230100:--c++20:--c++20 --gnu_version 160200:--c++20 --clang_version 230100:--ms_c++20 --microsoft_version 1950 | ||
| //options_all:-tused | ||
| //remark:Explicit conversion functions before aggregate fallback [GH #281] | ||
| // Core issue 899 permits these conversions in C++11 and later. Previously, | ||
| // C++20 parenthesized aggregate initialization caused spurious errors. | ||
|
|
||
| struct D { float x, y; }; | ||
| struct S { | ||
| float x, y; | ||
| explicit constexpr operator D() const { return D{x, y}; } | ||
| }; | ||
|
|
||
| D f(S s) { | ||
| D d(s); // Previously an error in C++20 mode. Now okay. | ||
| return D(s); // Likewise. | ||
| } | ||
|
|
||
| constexpr S s = {1.0f, 2.0f}; | ||
| static_assert(D(s).x == 1.0f && D(s).y == 2.0f, "functional cast"); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| fe_only -DTEST_NUMBER=1 -tused --c++11 Test_name.c | ||
| "Test_name.c", line 18: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 20: error: no suitable user-defined conversion from "A" to "C" exists | ||
| C c = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| fe_only -DTEST_NUMBER=2 -tused --c++11 --gnu_version 160200 Test_name.c | ||
| "Test_name.c", line 18: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 20: error: no suitable user-defined conversion from "A" to "C" exists | ||
| C c = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| fe_only -DTEST_NUMBER=3 -tused --c++11 --clang_version 230100 Test_name.c | ||
| "Test_name.c", line 18: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 20: error: no suitable user-defined conversion from "A" to "C" exists | ||
| C c = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| fe_only -DTEST_NUMBER=4 -tused --c++20 Test_name.c | ||
| "Test_name.c", line 18: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 20: error: no suitable user-defined conversion from "A" to "C" exists | ||
| C c = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| fe_only -DTEST_NUMBER=5 -tused --c++20 --gnu_version 160200 Test_name.c | ||
| "Test_name.c", line 18: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 20: error: no suitable user-defined conversion from "A" to "C" exists | ||
| C c = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| fe_only -DTEST_NUMBER=6 -tused --c++20 --clang_version 230100 Test_name.c | ||
| "Test_name.c", line 18: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 20: error: no suitable user-defined conversion from "A" to "C" exists | ||
| C c = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| fe_only -DTEST_NUMBER=7 -tused --ms_c++20 --microsoft_version 1950 Test_name.c | ||
| "Test_name.c", line 18: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 20: error: no suitable user-defined conversion from "A" to "C" exists | ||
| C c = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| //type:fn | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please rename to |
||
| //options:--c++11:--c++11 --gnu_version 160200:--c++11 --clang_version 230100:--c++20:--c++20 --gnu_version 160200:--c++20 --clang_version 230100:--ms_c++20 --microsoft_version 1950 | ||
| //options_all:-tused | ||
| //remark:Core issue 899: Explicit conversion functions in direct class initialization | ||
|
|
||
| struct C { }; | ||
| struct A { | ||
| explicit operator int() const; | ||
| explicit operator C() const; | ||
| }; | ||
|
|
||
| struct B { | ||
| int i; | ||
| B(const A& a): i(a) { } // Okay. | ||
| }; | ||
|
|
||
| void f(A a) { | ||
| int i = a; // Error: copy-initialization. | ||
| int j(a); // Okay: direct-initialization. | ||
| C c = a; // Error: copy-initialization. | ||
| C c2(a); // Okay: direct-initialization (Core issue 899). | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes entry should be added after the "Version 7.1" header