Possible GCC bug on NetBSD-9.4
Sad Clouds <[email protected]> Tue, 1 Apr 2025 11:59:02 +0100
| Newsgroups | gmane.os.netbsd.ports.sparc64 |
|---|---|
| Message-ID | <[email protected]> |
Hello, I'm observing some weird corruption with GCC on sparc64 running NetBSD-9.4. I've not tried other architectures with this compiler version, so reporting it here for now. This is a very old Sun Ultra 10, which could potentially have hardware issue, so before I open a new bug, can anyone running similar sparc64 release confirm the same behavior? The corruption seems to occur with the following pragmas: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" ... #pragma GCC diagnostic pop This results in u64_ptr pointer corruption, which points to the wrong address and prints the wrong values in both cases: $ gcc test.c && ./a.out data=0xffffffffffffd388, u64_ptr=0xffffffffffffd390, *u64_ptr=1078020256 data=0xffffffffffffd380, u64_ptr=0xffffffffffffd388, *u64_ptr=1122334455 If I comment out GCC pragmas, the code executes correctly. Pointers: data and u64_ptr are the same and the values printed are also correct: $ gcc test.c && ./a.out data=0xffffffffffffd388, u64_ptr=0xffffffffffffd388, *u64_ptr=1122334455 data=0xffffffffffffd380, u64_ptr=0xffffffffffffd380, *u64_ptr=6677889900 GCC documentation does not give any guidance on where such pragmas can be used: before, around or within block statements. However, the same test programs compiles and runs correctly on SPARC Solaris-11.4 with GCC-13.3.
test.c
(text/x-csrc, 732 B)
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
static void fn(const void *data, size_t data_size)
{
const uint64_t *u64_ptr;
/* data must be aligned on 8 byte boundary */
assert((uintptr_t)data % sizeof(uint64_t) == 0);
assert(data_size >= sizeof(uint64_t));
assert(data_size % sizeof(uint64_t) == 0);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
for (
u64_ptr = data;
u64_ptr < (const uint64_t *)((const uint8_t *)data + data_size);
u64_ptr++)
#pragma GCC diagnostic pop
{
printf("data=%p, u64_ptr=%p, *u64_ptr=%ju\n", data, u64_ptr, *u64_ptr);
}
}
int main(void)
{
uint64_t n1 = 1122334455;
uint64_t n2 = 6677889900;
fn(&n1, sizeof(n1));
fn(&n2, sizeof(n2));
}