[Bug optimization/10823] [3.3/3.4 regression] wrong code after first cse pass
bangerth at dealii dot org
gcc-bugzilla@gcc.gnu.org
Thu Jul 17 23:44:00 GMT 2003
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10823
------- Additional Comments From bangerth at dealii dot org 2003-07-17 23:44 -------
I got this mail from the submitter of the PR:
>>>>> "bangerth" == bangerth at dealii dot org <gcc-bugzilla@gcc.gnu.org> writes:
bangerth> bangerth at dealii dot org changed:
bangerth> What |Removed |Added
bangerth>
----------------------------------------------------------------------------
bangerth> Status|NEW |RESOLVED Resolution| |INVALID
Sorry for the late reaction. Our institute's file server has crashed,
I'd got to spent some time to put him back on its legs...
bangerth> Your code is faulty: in this function
bangerth> LV get() const { return op(*static_cast<const ITP&>(*this),
*second); }
bangerth> the first operand to op.operator() is constructed by calling
bangerth> Uop::result_type Uev::operator* () const { return op(*p); }
bangerth> with result_type being of type RV. Thus, it's
bangerth> returned object is a temporary. However,
bangerth> op.Bop::operator() takes a reference and passes it
bangerth> on. This doesn't work.
I think, your analysis is not entirely correct. The first operand of
op.operator() is indeed a temporary, but it is guaranteed to stay
alive up to the next sequence point, that is, end of the return
statement. The Bop::operator() passes the reference to this temporary
RV to the constructor of LV, which makes a copy of it and stores it in
the new object, being finally returned from get() (or possibly copied
one more time if the return value optimization doesn't work.) At any
rate, when the sequence point is reached, the temporary RV is not used
any more.
And, after all, even if this code had been an example of wrong usage
of references (of that kind I'm seeing regularly by our students), it
had to lead to a program crash when accessing an invalid reference. The
(miscompiled) code of the LV constructor reads instead the wrong field in RV
(s2._size instead of s2._start) when copying from the temporary into
the new LV object.
Your solution with a static variable is not applicable here, since the
result of get() must depend on the actual contents of the Bev object,
and the latter is by no means a solitary object. The test case is just
VERY simplified compared to the original program.
I hope, you revisit this case and eventually revert the RESOLUTION, so
that the two days I've spent reading the assembler output and RTL
dumps were not in vain :-).
Another evidence of this problem being a gcc bug is the fact that when
I simplify the case a little bit further, namely throw away the
inheritance Seq : Gen, the problem disappears and the code becomes correct!
But the class Gen is absolutely empty, and should not affect the alias
analisys in any way?!
Thank you in advance for your attention and patience!
Ewgenij Gawrilow
PS:
By the way, what is this mysterious strict aliasing exactly?
Is it described formally anywhere? Is it merely the list in [3.10] (15) of
ANSI C++ or something more elaborated?
More information about the Gcc-bugs
mailing list