<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Mapping a struct onto an aligned byte array produces incorrect output when compiled with -O2"
   href="https://bugs.llvm.org/show_bug.cgi?id=38860">38860</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Mapping a struct onto an aligned byte array produces incorrect output when compiled with -O2
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Macintosh
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>MacOS X
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>adrianwjw@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Version: Apple LLVM version 9.1.0 (clang-902.0.39.2)

Reduced test case. Expected value of sum is 553757185, but under -O2 the first
four bytes of the target buffer are empty, resulting in an incorrect sum value
of 64000:

#include "stdint.h"
#include "stdio.h"
#include "stdlib.h"

typedef struct some_struct {
    unsigned short fst;
    unsigned short snd;
} some_struct;

void test(void *source_buf, uint32_t source_buf_size) {
    void *target_buf;
    target_buf = calloc(source_buf_size, 1);

    unsigned short fst = 0;
    unsigned short snd = 0;

    uint32_t num_structs = source_buf_size / sizeof(some_struct);
    printf("num_structs = %d\n", num_structs);

    for(int i = 0; i < num_structs; i++) {
        fst = ((some_struct *) source_buf)[i].fst;
        snd = ((some_struct *) source_buf)[i].snd;

        ((some_struct *) target_buf)[i].fst = fst;
        ((some_struct *) target_buf)[i].snd = snd;
    }

    uint32_t sum = 0;
    uint32_t num_uint32s = source_buf_size / sizeof(uint32_t);
    printf("num_uint32s = %d\n", num_uint32s);

    for(int i = 0; i < num_uint32s; i++) {
        sum += ((uint32_t *) target_buf)[i];
        printf("%d: *buffer = 0x%08x sum = %d\n", i, ((uint32_t *)
target_buf)[i], sum);
    }
    printf("sum = %d\n", sum);

    free(target_buf);
}

// Apple LLVM version 9.1.0 (clang-902.0.39.2)

// clang -Wall -Wcast-align -O2 subset.c -o subset
//     num_structs = 2
//     num_uint32s = 2
//     0: *buffer = 0x00000000 sum = 0
//     1: *buffer = 0x0000fa00 sum = 64000
//     sum = 64000

// clang -Wall -Wcast-align -O1 subset.c -o subset
//     num_structs = 2
//     num_uint32s = 2
//     0: *buffer = 0x2100b001 sum = 553693185
//     1: *buffer = 0x0000fa00 sum = 553757185
//     sum = 553757185
int main() {
    unsigned char source_buf[8] = {0x01,0xb0,0x00,0x21,0x00,0xfa,0x00,0x00};

    test(source_buf, 8);

    return 0;
}

Or am I writing some highly illegal C code here?


Thanks,
Adrian</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>