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
3251cbc
3fc9bca
63ef192
a6befe6
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,5 +1,21 @@ | ||
| Version 7.1 | ||
|
|
||
| 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 d(S{}); // Previously an error in C++20 mode. Now okay. | ||
|
|
||
| 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).
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. Looks like EDGcpfe/23402 (Core issue 2267: Initialization of temporary for reference binding) is also related here. I think we need to fix these related issues first before we can merge this PR. |
||
|
|
||
| 10/9/26 [GH #27] | ||
| Clearer diagnostic when auto is deduced from an incomplete type | ||
|
|
||
|
|
||
| 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,8 @@ | ||
| //type:fp | ||
|
yronglin marked this conversation as resolved.
|
||
| //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] | ||
|
|
||
| struct D { float x, y; }; | ||
| struct S { explicit operator D() const; }; | ||
| D d(S{}); // Error, now okay. | ||
| 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,10 @@ | ||
| fe_only -DTEST_NUMBER=1 -tused --c++11 Test_name.c | ||
| "Test_name.c", line 13: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 14: 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 13: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 14: 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 13: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 14: 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 13: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 14: 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 13: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 14: 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 13: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 14: 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 13: error: no suitable conversion function from "A" to "int" exists | ||
| int i = a; // Error: copy-initialization. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 14: 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,20 @@ | ||
| //type:fp | ||
| //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 j(a); // Okay: direct-initialization. | ||
| C c2(a); // Okay: direct-initialization (Core issue 899). | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| //type:fn | ||
| //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 copy-initialization | ||
|
|
||
| struct C { }; | ||
| struct A { | ||
| explicit operator int() const; | ||
| explicit operator C() const; | ||
| }; | ||
|
|
||
| void f(A a) { | ||
| int i = a; // Error: copy-initialization. | ||
| C c = a; // Error: copy-initialization. | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| fe_only -DTEST_NUMBER=1 -tused --c++11 Test_name.c | ||
| "Test_name.c", line 15: error: no instance of overloaded function "f" matches the argument list | ||
| argument types are: ({...}) | ||
| int i = f({A{}}); // Error: cannot copy-list-initialize the temporary int. | ||
| ^ | ||
| "Test_name.c", line 7: note: function "f(int *)" does not match because argument #1 does not match parameter | ||
| int f(int*); | ||
| ^ | ||
| "Test_name.c", line 6: note: function "f(int &&)" does not match because argument #1 does not match parameter | ||
| int f(int&&); | ||
| ^ | ||
|
|
||
| "Test_name.c", line 16: error: no instance of overloaded function "g" matches the argument list | ||
| argument types are: ({...}) | ||
| int j = g({A{}}); // Likewise for a const lvalue reference. | ||
| ^ | ||
| "Test_name.c", line 9: note: function "g(int *)" does not match because argument #1 does not match parameter | ||
| int g(int*); | ||
| ^ | ||
| "Test_name.c", line 8: note: function "g(const int &)" does not match because argument #1 does not match parameter | ||
| int g(const int&); | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| fe_only -DTEST_NUMBER=2 -tused --c++11 --gnu_version 160200 Test_name.c | ||
| "Test_name.c", line 15: error: no instance of overloaded function "f" matches the argument list | ||
| argument types are: ({...}) | ||
| int i = f({A{}}); // Error: cannot copy-list-initialize the temporary int. | ||
| ^ | ||
| "Test_name.c", line 7: note: function "f(int *)" does not match because argument #1 does not match parameter | ||
| int f(int*); | ||
| ^ | ||
| "Test_name.c", line 6: note: function "f(int &&)" does not match because argument #1 does not match parameter | ||
| int f(int&&); | ||
| ^ | ||
|
|
||
| "Test_name.c", line 16: error: no instance of overloaded function "g" matches the argument list | ||
| argument types are: ({...}) | ||
| int j = g({A{}}); // Likewise for a const lvalue reference. | ||
| ^ | ||
| "Test_name.c", line 9: note: function "g(int *)" does not match because argument #1 does not match parameter | ||
| int g(int*); | ||
| ^ | ||
| "Test_name.c", line 8: note: function "g(const int &)" does not match because argument #1 does not match parameter | ||
| int g(const int&); | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| fe_only -DTEST_NUMBER=3 -tused --c++11 --clang_version 230100 Test_name.c | ||
| "Test_name.c", line 15: error: no instance of overloaded function "f" matches the argument list | ||
| argument types are: ({...}) | ||
| int i = f({A{}}); // Error: cannot copy-list-initialize the temporary int. | ||
| ^ | ||
| "Test_name.c", line 7: note: function "f(int *)" does not match because argument #1 does not match parameter | ||
| int f(int*); | ||
| ^ | ||
| "Test_name.c", line 6: note: function "f(int &&)" does not match because argument #1 does not match parameter | ||
| int f(int&&); | ||
| ^ | ||
|
|
||
| "Test_name.c", line 16: error: no instance of overloaded function "g" matches the argument list | ||
| argument types are: ({...}) | ||
| int j = g({A{}}); // Likewise for a const lvalue reference. | ||
| ^ | ||
| "Test_name.c", line 9: note: function "g(int *)" does not match because argument #1 does not match parameter | ||
| int g(int*); | ||
| ^ | ||
| "Test_name.c", line 8: note: function "g(const int &)" does not match because argument #1 does not match parameter | ||
| int g(const int&); | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| fe_only -DTEST_NUMBER=4 -tused --c++20 Test_name.c | ||
| "Test_name.c", line 15: error: no instance of overloaded function "f" matches the argument list | ||
| argument types are: ({...}) | ||
| int i = f({A{}}); // Error: cannot copy-list-initialize the temporary int. | ||
| ^ | ||
| "Test_name.c", line 7: note: function "f(int *)" does not match because argument #1 does not match parameter | ||
| int f(int*); | ||
| ^ | ||
| "Test_name.c", line 6: note: function "f(int &&)" does not match because argument #1 does not match parameter | ||
| int f(int&&); | ||
| ^ | ||
|
|
||
| "Test_name.c", line 16: error: no instance of overloaded function "g" matches the argument list | ||
| argument types are: ({...}) | ||
| int j = g({A{}}); // Likewise for a const lvalue reference. | ||
| ^ | ||
| "Test_name.c", line 9: note: function "g(int *)" does not match because argument #1 does not match parameter | ||
| int g(int*); | ||
| ^ | ||
| "Test_name.c", line 8: note: function "g(const int &)" does not match because argument #1 does not match parameter | ||
| int g(const int&); | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| fe_only -DTEST_NUMBER=5 -tused --c++20 --gnu_version 160200 Test_name.c | ||
| "Test_name.c", line 15: error: no instance of overloaded function "f" matches the argument list | ||
| argument types are: ({...}) | ||
| int i = f({A{}}); // Error: cannot copy-list-initialize the temporary int. | ||
| ^ | ||
| "Test_name.c", line 7: note: function "f(int *)" does not match because argument #1 does not match parameter | ||
| int f(int*); | ||
| ^ | ||
| "Test_name.c", line 6: note: function "f(int &&)" does not match because argument #1 does not match parameter | ||
| int f(int&&); | ||
| ^ | ||
|
|
||
| "Test_name.c", line 16: error: no instance of overloaded function "g" matches the argument list | ||
| argument types are: ({...}) | ||
| int j = g({A{}}); // Likewise for a const lvalue reference. | ||
| ^ | ||
| "Test_name.c", line 9: note: function "g(int *)" does not match because argument #1 does not match parameter | ||
| int g(int*); | ||
| ^ | ||
| "Test_name.c", line 8: note: function "g(const int &)" does not match because argument #1 does not match parameter | ||
| int g(const int&); | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
Uh oh!
There was an error while loading. Please reload this page.