[llvm-bugs] [Bug 28241] New: Wrong optimization of type-punning with two pointers involved
via llvm-bugs
llvm-bugs at lists.llvm.org
Tue Jun 21 08:24:18 PDT 2016
https://llvm.org/bugs/show_bug.cgi?id=28241
Bug ID: 28241
Summary: Wrong optimization of type-punning with two pointers
involved
Product: clang
Version: unspecified
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: -New Bugs
Assignee: unassignedclangbugs at nondot.org
Reporter: ch3root at openwall.com
CC: llvm-bugs at lists.llvm.org
Classification: Unclassified
Source code:
----------------------------------------------------------------------
#include <stdio.h>
union u { int i; long l; };
static int f(union u *p, union u *q)
{
p->i = 1;
q->l = 0;
return p->i;
}
static int g(union u *p, long *q)
{
p->i = 1;
*q = 0;
return p->i;
}
int main()
{
union u u;
printf("%d %d\n", f(&u, &u), g(&u, &u.l));
}
----------------------------------------------------------------------
Results:
----------------------------------------------------------------------
$ clang -std=c11 -Weverything test.c && ./a.out
0 0
$ clang -std=c11 -Weverything -O3 test.c && ./a.out
1 1
----------------------------------------------------------------------
clang version: clang version 3.9.0 (trunk 271312)
For comparison:
----------------------------------------------------------------------
$ gcc -std=c11 -pedantic -Wall -Wextra -O3 test.c && ./a.out
0 0
----------------------------------------------------------------------
gcc version: gcc (GCC) 7.0.0 20160616 (experimental)
When compiled with `clang -O3` the testcase prints `1 1`. This is wrong, the
right result is `0 0`.
The functions `f` and `g` demonstate two variants of the problem. In both cases
only one union is used and the field `l` is written via the pointer `q` while
the field `i` is later read via the pointer `p`. What is written to `l` should
affect what is read via `i`.
Type-punning is described in C11, 6.5.2.3p3 and footnote 95. There are no
restrictions on how the previous value was written into the union so writing
via another pointer is valid. And the read in this testcase is directly via
union. The code should be fine according to C11.
--
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/20160621/201efe8c/attachment-0001.html>
More information about the llvm-bugs
mailing list