This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/80053] Label with address taken should prevent duplication of containing basic block
- From: "amonakov at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Thu, 16 Mar 2017 18:00:46 +0000
- Subject: [Bug middle-end/80053] Label with address taken should prevent duplication of containing basic block
- Auto-submitted: auto-generated
- References: <bug-80053-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80053
--- Comment #2 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #1)
> The question is whether the transform at hand is valid if the label is
> duplicated
> but all referers still refer to the original one (so if the label is dropped
> at duplication time).
Well, you still need to initialize 'lp' somehow, so I don't follow.
> The current handling for cloning is certainly too conservative.
How so? I find that it's not conservative enough: it's possible to break it
even without resorting to inline asm! The following testcase is miscompiled at
-O3, because thanks to function cloning the .constprop clone will try to jump
to the general implementation. Their epilogues are incompatible, so it
manifests with a crash.
#include <stdio.h>
__attribute__((noinline, noclone))
static int noop(char *c)
{
return 1;
}
__attribute__((noinline))
static int cloneme(int p, void **target)
{
if (p == -1)
*target = &&L1;
if (p == -2)
*target = &&L2;
if (p < 0)
return 0;
char *tmp = 0;
if (p) {
puts("p != 0");
tmp = __builtin_alloca(p);
} else
puts("p == 0");
goto **target;
L1:
return 0;
L2:
return noop(tmp);
}
int main(int argc, char *argv[])
{
void *target1, *target2;
cloneme(-1, &target1);
cloneme(-2, &target2);
for (int i=0; i<10; i++)
cloneme(0, &target1);
cloneme(argc, &target2);
}