Port-sparc64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Possible GCC bug on NetBSD-9.4



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.
#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));
}


Home | Main Index | Thread Index | Old Index