<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><span class="vcard"><a class="email" href="mailto:rbultje@twoorioles.com" title="rbultje@twoorioles.com">rbultje@twoorioles.com</a>
</span> changed
<a class="bz_bug_link
bz_status_REOPENED "
title="REOPENED - Compiler crash"
href="https://bugs.llvm.org/show_bug.cgi?id=32416">bug 32416</a>
<br>
<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>What</th>
<th>Removed</th>
<th>Added</th>
</tr>
<tr>
<td style="text-align:right;">Resolution</td>
<td>INVALID
</td>
<td>---
</td>
</tr>
<tr>
<td style="text-align:right;">Status</td>
<td>RESOLVED
</td>
<td>REOPENED
</td>
</tr></table>
<p>
<div>
<b><a class="bz_bug_link
bz_status_REOPENED "
title="REOPENED - Compiler crash"
href="https://bugs.llvm.org/show_bug.cgi?id=32416#c11">Comment # 11</a>
on <a class="bz_bug_link
bz_status_REOPENED "
title="REOPENED - Compiler crash"
href="https://bugs.llvm.org/show_bug.cgi?id=32416">bug 32416</a>
from <span class="vcard"><a class="email" href="mailto:rbultje@twoorioles.com" title="rbultje@twoorioles.com">rbultje@twoorioles.com</a>
</span></b>
<pre>(In reply to Vedant Kumar from <a href="show_bug.cgi?id=32416#c6">comment #6</a>)
<span class="quote">> There doesn't seem to be a compiler bug here: this code violates C's
> aliasing rules. A load from a i8* isn't allowed to alias a load from a
> struct.typeB</span >
I looked this up, and the standard (c99) makes a specific exception for
(unsigned) char, doesn't it? See quoted text below.
"An object shall have its stored value accessed only by an lvalue expression
that has one of the following types:
* a type compatible with the effective type of the object,
* a qualiï¬ed version of a type compatible with the effective type of the
object,
* a type that is the signed or unsigned type corresponding to the effective
type of the object,
* a type that is the signed or unsigned type corresponding to a qualified
version of the effective type of the object,
* an aggregate or union type that includes one of the aforementioned types
among its members (including, recursively, a member of a subaggregate or
contained union), or
* a character type."
struct.typeB is "a type compatible with the effective type of the object", and
uint8_t (i8) is a "character type". Can you help me explain the spec violation
of my code?
Regardless, let's assume you're right just for the sake of argument. The
standard recommended workaround for strict aliasing violations (type punning)
is to use unions. If I remove all (2) casts in my code and replace them with
unions, the assert still triggers. Therefore, I believe your analysis is
incorrect and there is a compiler bug here.
$ cat /tmp/y.c
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct typeA { int placeholder; } typeA;
typedef struct typeB { int placeholder; typeA *a; } typeB;
typedef struct typeC { typeB *b; } typeC;
typedef struct typeD { int placeholder; typeC z[2]; } typeD;
typedef struct typeE { typeB *b; typeA *a; } typeE;
static void init2(typeE *const s, typeB *const b) { b->a = s->a; }
#define NUM_BYTES (sizeof(typeB) * 2 * 2)
static void init1(typeD *const t, uint8_t *const mem_in, const ptrdiff_t sz)
{
uint8_t *mem = mem_in;
typeE s;
uint8_t *ptrs[2];
ptrs[0] = mem; mem += NUM_BYTES;
s.b = (union { typeB *b; uint8_t *u; }) { .u = ptrs[0] }.b;
ptrs[1] = mem;
s.a = NULL;
int b, e;
for (b = 0; b < 2; b++) {
t->z[b].b = s.b;
for (e = 0; e < 2; e++)
init2(&s, &t->z[b].b[e]);
s.b += 2;
}
printf("assert(%p == %p);\n", ptrs[1], s.b);
assert(ptrs[1] == (union { typeB *b; uint8_t *u; }) { .b = s.b }.u);
}
int main(void) {
const ptrdiff_t sz = NUM_BYTES;
typeD *d = malloc(sizeof(typeD));
uint8_t *const mem = malloc(sz);
init1(d, mem, sz);
return 0;
}
$ clang-mp-4.0 --version
clang version 4.0.0 (branches/release_40 292772)
Target: x86_64-apple-darwin16.4.0
Thread model: posix
InstalledDir: /opt/local/libexec/llvm-4.0/bin
$ gcc-mp-4.8 --version
gcc-mp-4.8 (MacPorts gcc48 4.8.5_0) 4.8.5
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ clang-mp-4.0 -o /tmp/y /tmp/y.c -O3 -Wall && /tmp/y
assert(0x7fd63e4028a0 == 0x7fd63e4028a0);
Assertion failed: (ptrs[1] == (union { typeB *b; uint8_t *u; }) { .b = s.b
}.u), function init1, file /tmp/y.c, line 34.
Abort trap: 6
$ clang-mp-4.0 -o /tmp/y /tmp/y.c -O1 -Wall && /tmp/y
assert(0x7fd8be4028c0 == 0x7fd8be4028c0);
$ gcc-mp-4.8 -o /tmp/y /tmp/y.c -O3 -Wall && /tmp/y
assert(0x7ff1224028a0 == 0x7ff1224028a0);</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>