public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/110912] New: False assumption that constructors cannot alias any of their parameters
@ 2023-08-05 10:04 janschultke at googlemail dot com
2023-08-08 2:13 ` [Bug c++/110912] " de34 at live dot cn
2023-08-08 8:47 ` janschultke at googlemail dot com
0 siblings, 2 replies; 3+ messages in thread
From: janschultke at googlemail dot com @ 2023-08-05 10:04 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110912
Bug ID: 110912
Summary: False assumption that constructors cannot alias any of
their parameters
Product: gcc
Version: 14.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: janschultke at googlemail dot com
Target Milestone: ---
It looks like GCC thinks that no aliasing can take place betweeen `this` and
any constructor parameters.
You get the same output if you use `__restrict` for any pointers passed into
constructors, or if you add `noalias` to LLVM IR.
There is no wording in the standard that disallows aliasing in constructors
completely, and this may cause more serious issues in real code See
https://github.com/cplusplus/CWG/issues/206.
This bug stems from an over-interpretation of [class.cdtor] p2
(https://eel.is/c++draft/class.cdtor#2), which states that an unspecified value
is obtained when not accessing subobjects through the `this` pointer. However,
it DOES NOT say that side effects will result in unspecified values, and it
DOES NOT say that any undefined behavior is involved, which is the prerequisite
to treat this as `noalias`.
It seems to have been introduced here, and there is a related LLVM issue:
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82899
- https://bugs.llvm.org/show_bug.cgi?id=37329
For reference, [class.cdtor] p2:
> During the construction of an object,
> if the value of the object or any of its subobjects is accessed
> through a glvalue that is not obtained,
> directly or indirectly, from the constructor's this pointer,
> the value of the object or subobject thus obtained is unspecified.
THIS WORDING IS NOT STRONG ENOUGH FOR `noalias`! This is an old paragraph which
originally applied to const objects only, and has some problems with breaking
legitimate code for polymorphic classes. I am not entirely sure about the
intention behind it myself, but it would have been very easy for the committee
to make access through such a pointer (not obtained from `this`) undefined
behavior. That would actually allow `noalias`, NOT the current wording.
I have talked to other knowledgeable members of the community, and so far no
one believes that the wording is strong enough, or intended to disallow
aliasing entirely.
Related discussions:
- https://lists.isocpp.org/std-discussion/2023/08/2324.php
- https://lists.isocpp.org/std-discussion/2022/12/1952.php
## Code to Reproduce (https://godbolt.org/z/K4nTPYK3r)
void foo();
struct A {
int i = 0;
[[gnu::used]] A(int &x) {
x = 5;
if (i == 0) {
foo();
}
}
};
## Actual Output (gcc trunk -O3)
A::A(int&) [base object constructor]:
mov DWORD PTR [rdi], 0
mov DWORD PTR [rsi], 5
jmp foo()
## Expected Output (clang trunk -O3)
A::A(int&) [base object constructor]:
mov dword ptr [rdi], 0
mov dword ptr [rsi], 5
cmp dword ptr [rdi], 0
je foo()@PLT
ret
## Suggested Resolution
Do not assume `noalias` for all parameters in a constructor.
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Bug c++/110912] False assumption that constructors cannot alias any of their parameters
2023-08-05 10:04 [Bug c++/110912] New: False assumption that constructors cannot alias any of their parameters janschultke at googlemail dot com
@ 2023-08-08 2:13 ` de34 at live dot cn
2023-08-08 8:47 ` janschultke at googlemail dot com
1 sibling, 0 replies; 3+ messages in thread
From: de34 at live dot cn @ 2023-08-08 2:13 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110912
Jiang An <de34 at live dot cn> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |de34 at live dot cn
--- Comment #1 from Jiang An <de34 at live dot cn> ---
The restriction agains aliasing was intended, see
https://cplusplus.github.io/CWG/issues/2271.html.
The status quo seems to be that in the body of `A::A(int &x)`, compilers can
assume that the value of `x` won't be changed by a modification on `*this`, but
not the other way around.
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Bug c++/110912] False assumption that constructors cannot alias any of their parameters
2023-08-05 10:04 [Bug c++/110912] New: False assumption that constructors cannot alias any of their parameters janschultke at googlemail dot com
2023-08-08 2:13 ` [Bug c++/110912] " de34 at live dot cn
@ 2023-08-08 8:47 ` janschultke at googlemail dot com
1 sibling, 0 replies; 3+ messages in thread
From: janschultke at googlemail dot com @ 2023-08-08 8:47 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110912
--- Comment #2 from Jan Schultke <janschultke at googlemail dot com> ---
(In reply to Jiang An from comment #1)
> The restriction agains aliasing was intended, see
> https://cplusplus.github.io/CWG/issues/2271.html.
>
> The status quo seems to be that in the body of `A::A(int &x)`, compilers can
> assume that the value of `x` won't be changed by a modification on `*this`,
> but not the other way around.
Then this status quo is not correctly implemented, because in the example, GCC
assumes that a change of `x` (see `x = 5`) cannot alter `this->i` (see `i == 0`
assumed to be always true).
It is not enough to put `__restrict` on the parameters; a much weaker modifier
must be used for this purpose. At most, a "one-way `__restrict`" must be used,
if such a thing exists.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-08-08 8:47 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-05 10:04 [Bug c++/110912] New: False assumption that constructors cannot alias any of their parameters janschultke at googlemail dot com
2023-08-08 2:13 ` [Bug c++/110912] " de34 at live dot cn
2023-08-08 8:47 ` janschultke at googlemail dot com
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).