[llvm-bugs] [Bug 32416] Compiler crash

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Apr 4 04:52:19 PDT 2017


https://bugs.llvm.org/show_bug.cgi?id=32416

rbultje at twoorioles.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|INVALID                     |---
             Status|RESOLVED                    |REOPENED

--- Comment #11 from rbultje at twoorioles.com ---
(In reply to Vedant Kumar from comment #6)
> 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

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 qualified 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);

-- 
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/20170404/2ac1708b/attachment-0001.html>


More information about the llvm-bugs mailing list