When I compile these two sources, one with -O3 -march=pentium3 and the other with -Os, the linker warns about nonmatching alignments and the program crashes because of misaligned SSE accesses.
/usr/bin/ld: Warning: alignment 4 of symbol `array' in commonalign2.o is smaller than 32 in commonalign1.o
/usr/bin/ld: Warning: alignment 4 of symbol `array2' in commonalign2.o is smaller than 32 in commonalign1.o
The reson is that gcc aligns arrays in common section to 32 bytes and expects that they will be aligned so. This expectation is wrong, the common entries may be resolved pointing to data section in another module that doesn't meet the alignment (it may be compiled with different compiler or with the same compiler with different flags (-Os)).
For extern arrays, gcc correctly assumes that they are aligned to their ABI standard (4 bytes) and generates appropriate SSE code; for common arrays it should expect 4-byte alignment too.
Created attachment 18653 [details]
the first file
The first file of a two-file program. Compile with gcc -c -O3 -march=pentium3.
Created attachment 18654 [details]
the second file
The second file. Compile with gcc -c -Os. Then, link both object files together and run it.
BTW. this bug is in both gcc 4.3 and 4.4
Isn't this a linker issue in that it doesn't use the biggest alignment?
(In reply to comment #4)
> Isn't this a linker issue in that it doesn't use the biggest alignment?
Linker can't change alignment on non-common symbols. I think it is wrong
to give a different alignment for the same symbol in different files.
The bug is about common symbols.
Richard Guenther: the bug caused by common symbol (in file commonalign1.o) with the same name as data section symbol (in file commonalign2.o). In this case, the linker redirects the common symbol to the symbol in the data section. But the linker cannot change the content of the data section, so it cannot make both symbols array and array2 aligned. Linker is innocent in this and giving a warning is the best thing it can do.
This code is undefined I think (and really it is not valid C90/C99 code).
The common linker definitions were made to exactly to make code like this work and share the array between two object.
So if you think it is undefined, don't support it (make -fno-common default and remove -fcommon at all). Or, if you want to support it, support it correctly.