[llvm-bugs] [Bug 52440] New: miscompilation of for loop with a condition scope and continue statement
via llvm-bugs
llvm-bugs at lists.llvm.org
Mon Nov 8 11:28:48 PST 2021
https://bugs.llvm.org/show_bug.cgi?id=52440
Bug ID: 52440
Summary: miscompilation of for loop with a condition scope and
continue statement
Product: clang
Version: unspecified
Hardware: All
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: C++
Assignee: unassignedclangbugs at nondot.org
Reporter: shevitz at lanl.gov
CC: blitzrakete at gmail.com, dgregor at apple.com,
erik.pilkington at gmail.com, llvm-bugs at lists.llvm.org,
richard-llvm at metafoo.co.uk
I believe there is a very obscure miscompilation in clang when compiling a
`for` statement with both a condition scope and a continue statement. I am
including a minimal reproducer along with a .pdf file of the CFG that
demonstrates the problem.
The essence of the problem is that when there is a condition scope variable, a
continue statement branches to the wrong basic block. Referring to labels
visible in the CFG of the minimal_bug.pdf file, the continue statement in the
for body sets `%cleanup.dest.slot` to `4` which goes to the `%cleanup` basic
block. The `%cleanup` block does cleanups, then the code branches to the
`%for.inc` which sets `%cleanup.dest.slot% to 0 then branches back to
`%cleanup` and performs cleanups a second time. In short the destructor of a
non trivial condition scope variable is called twice because of the cycle in
the CFG between `%cleanup` and `%for.inc`.
While calling a destructor twice on the same object doesn't seem to inherently
cause a problem, a double free causes a core dump. The minimal_bug example is
constructed to cause a double free of a non-trivial condition scope variable so
the executable core dumps.
The solution to the miscompilation is to have the continue statement branch to
`%for.inc` rather than `%cleanup`. That way the cleanups are only done once.
The bug is obvious at optimization level 0, but I believe is there at all
optimization levels.
I am uploading a .pdf of the CFG generated by the minimal reproducer
demonstrating the bug. I seem to be able to only include one attachment, so I
will include the source inline:
//////////////////////////////////////////////////////////////////////
// minimal_bug.cpp
// This is a reproducer for the double free core dump in "for" codegen
struct S2 {
int x;
};
struct S {
S(int x=0):x(x) {s2=new S2;}
~S() {delete s2;}
int x;
S2* s2;
operator bool() {return x<5;}
};
int main () {
for (int i = 4; S s{i}; ++i) continue;
return 0;
}
//////////////////////////////////////////////////////////////////////
compile with (The executable will core dump):
clang++ -fno-exceptions -O0 minimal_bug.cpp
To generate the IR:
clang++ -fno-exceptions -O0 -S -emit-llvm minimal_bug.cpp
To generate the CFG:
opt -dot-cfg minimal_bug.ll
dot -Tpdf -o minimal_bug.pdf .main.dot -Gsize=8,10.5\!
Regards,
Danny
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20211108/cef69d77/attachment-0001.html>
More information about the llvm-bugs
mailing list