-
Notifications
You must be signed in to change notification settings - Fork 12.2k
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
Single-element initializer_list invokes wrong constructor #24186
Comments
Clang is correct here per DR1467 (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467), which we implemented recently. I'll take your example to the C++ committee and see if they want to reconsider that change. |
Looking at it further I think you might actually be right w.r.t. the original test case. My original example was oversimplified, though - here's something closer to what we have:
We also see a change in behavior here (one invocation of the Container constructor in recent clang, two elsewhere). (for background: in our code As I read it, 13.3.3.1.5 applies here, but the new paragraph shouldn't kick in: "If the parameter type is a class X and the initializer list has a single element of type cv U, where U is X or a class derived from X, ...". In the original example the parameter type was |
The thing that changes behavior is:
... which now calls the |
Ah, I see. Definitely seems like an unintended result of DR1467 then :/ |
Since it seems like the committee is revisiting this (I'm told that Mike Miller is opening a new CWG issue, though it hasn't appeared on http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html yet), and the current behavior is dangerous in how it changes existing code, would the right thing for Clang to do be to revert DR1467 until the committee decides on a better fix? |
This is a simpler case I ran into. I think it is related. If it is not I can file a different bug. The following code produces different results on GCC and on Clang. On all versions of GCC up to master, The initializer list constructor is called and this prints "1". On clang, this calls the copy constructor, and this prints "10". I am not sure by the spec what should be the right behavior here.
|
Update on the standards committee. There is now an open issue for this behavior, but I haven't seen any updates on when it might be discussed and resolved: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2137 The clang behavior is technically correct as defined by the prior issue resolution, but might need to change again if the committee revises it. Meanwhile developers with existing code which worked before DR1467 are in a tricky situation where code can silently break on a compiler upgrade, and behaves differently in GCC vs clang. |
At now for code int comment 6 MSVC update 2 print 10 and use "move" constructor for code in comment 1. |
This post (https://stackoverflow.com/questions/51665368/c-constructor-taking-an-stdinitializer-list-of-size-one) on Stackoverflow suggests that the defect report 2137 (https://wg21.link/CWG2137) (raised by Richard Smith and based on this bug report) was released into the standard. That being said the behavior of Clang has not been updated accordingly since then, is there any reason for that? |
No reason beyond the fact that no-one has done it yet. We'd be happy to take a patch. |
There is an approved patch that appears to address this: https://reviews.llvm.org/D156032 |
It looks like @cor3ntin wanted conformance review, if you think the PR looks good, we should land it. |
@llvm/issue-subscribers-clang-frontend Author: None (llvmbot)
| | |
| --- | --- |
| Bugzilla Link | [23812](https://llvm.org/bz23812) |
| Version | trunk |
| OS | All |
| Reporter | LLVM Bugzilla Contributor |
| CC | @DougGregor,@dushistov,@itollefsen,@zygoloid,@timsong-cpp,@jwakely |
Extended DescriptionTest case:
This is really bad for us, as it silently changes the meaning of code in a subtle way (manifests as making our JSON library elide single-element array literals). :( |
I hope this PR could be landed soon. Some HIP users are affected by this issue too. |
…same type) (#77768) Closes #77638, #24186 Rebased from <https://reviews.llvm.org/D156032>, see there for more information. Implements wording change in [CWG2137](https://wg21.link/CWG2137) in the first commit. This also implements an approach to [CWG2311](https://wg21.link/CWG2311) in the second commit, because too much code that relies on `T{ T_prvalue}` being an elision would break. Because that issue is still open and the CWG issue doesn't provide wording to fix the issue, there may be different behaviours on other compilers.
FYI, this was reverted by 6e4930c , and the author seems to not be currently contributing actively to clang |
Extended Description
Test case:
Q { Q() }
should invoke theinitializer_list
constructor, but recent Clang (trunk as of today, r239482) treats it as a move instead. For comparison, clang 3.6 and older, gcc 4.9, 5.1, and MSVC2015 all select theinitializer_list
constructor.This is really bad for us, as it silently changes the meaning of code in a subtle way (manifests as making our JSON library elide single-element array literals). :(
The text was updated successfully, but these errors were encountered: