Bug 64236 - [c++11] last alignas overrides stricter on a class definition
Summary: [c++11] last alignas overrides stricter on a class definition
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.3
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks: 58601
  Show dependency treegraph
 
Reported: 2014-12-09 12:19 UTC by Wolfgang Roehrl
Modified: 2023-05-22 08:50 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 11.0, 4.8.3, 4.9.3, 5.3.0, 6.0
Last reconfirmed: 2020-12-07 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Wolfgang Roehrl 2014-12-09 12:19:38 UTC
Hi,
I would like to post a bug report for the GNU C/C++ compiler 4.8.3.
We use the compiler to generate code for a PowerPC processor.
Invokation line for the GNU C++ compiler:

ccppc -c -x c++ -std=c++11 -Wall -Werror -g -mcpu=8540 -meabi
      -ftls-model=local-exec -msdata=sysv -fno-common -mspe -mabi=spe
      -mfloat-gprs=double -mbig -mmultiple -mno-string -misel -mstrict-align
      -fverbose-asm -fno-exceptions -fno-rtti -fgcse-sm -fno-section-anchors
      -ftemplate-backtrace-limit=20 -G 8 -O3
      -I<some include paths>
      -D<some #define's>
      X.CPP -oX.O


// file X.CPP

#define SIZE_DATA_CACHE_BLOCK 32u

struct S
{ double d; };

struct alignas(sizeof(S)) S1
{ char d[sizeof(S)]; };

struct alignas(SIZE_DATA_CACHE_BLOCK) alignas(sizeof(S)) S2
{ char d[sizeof(S)]; };


alignas(S) char s1[sizeof(S)];
alignas(SIZE_DATA_CACHE_BLOCK) alignas(S) char s2[sizeof(S)];
S1 s3;
S2 s4;



An inspection of the generated assembler file (see below) shows the following
alignments:
. s1: alignment = 8
. s2: alignment = 32
. s3: alignment = 8
. s4: alignment = 8 ???

I think that s4 should also be aligned on a 32-byte boundary (C++11 standard,
7.6.2/4).


Following is the generated assembler file:

 .globl s4
 .section ".sbss","aw",@nobits
 .align 3    <--- 8-byte alignment ???
s4:
 .zero 8
 .size s4, 8
 .type s4, @object
 .globl s3
 .align 3    <--- 8-byte alignment
s3:
 .zero 8
 .size s3, 8
 .type s3, @object
 .globl s2
 .align 5    <--- 32-byte alignment
s2:
 .zero 8
 .size s2, 8
 .type s2, @object
 .globl s1
 .align 3    <--- 8-byte alignment
s1:
 .zero 8
 .size s1, 8
 .type s1, @object



Kind regards
W. Roehrl
Comment 1 Jonathan Wakely 2014-12-09 14:06:06 UTC
On x86_64 Clang gives 8 32 8 32, but EDG gives 8 32 8 8, the same as GCC.
Comment 2 Martin Sebor 2015-02-25 02:16:50 UTC
I reproduced it with today's trunk configured for powerpc-linux-gnuspe but I don't think it has anything to do with powerpc.  It looks like GCC simply takes the last alignment instead of the strictest one.

$ cat u.cpp && /build/gcc-trunk-ppc/gcc/xgcc -B/build/gcc-trunk-ppc/gcc -c -std=c++11 -xc++ -Wall -S u.cpp && cat u.s
struct alignas (32) alignas (8) A1 { int i; } a1 = { 0 };
struct alignas (8) alignas (32) A2 { int i; } a2 = { 0 };

struct __attribute__ ((aligned (32), aligned (8))) B1 { int i; } b1 = { 0 };
struct __attribute__ ((aligned (8), aligned (32))) B2 { int i; } b2 = { 0 };
	.file	"u.cpp"
	.globl a1
	.section	".sbss","aw",@nobits
	.align 3
a1:
	.zero	8
	.size	a1, 8
	.type	a1, @object
	.globl a2
	.lcomm	a2,32,32
	.type	a2, @object
	.globl b1
	.align 3
b1:
	.zero	8
	.size	b1, 8
	.type	b1, @object
	.globl b2
	.lcomm	b2,32,32
	.type	b2, @object
	.ident	"GCC: (GNU) 5.0.0 20150225 (experimental)"
	.section	.note.GNU-stack,"",@progbits
Comment 3 Jonathan Wakely 2015-04-07 11:25:48 UTC
Reduced:

struct alignas(32) alignas(8) S { char d[8]; };
static_assert(alignof(S) == 32, "");
Comment 4 Martin Sebor 2016-01-23 17:08:52 UTC
Still fails on trunk:
$ cat u.cpp && /home/msebor/build/gcc-trunk-svn/gcc/xgcc -B/home/msebor/build/gcc-trunk-svn/gcc -Wall -Wextra -Wpedantic -std=c++11 -xc++ u.cpp
struct alignas(32) alignas(8) S { char d[8]; };
static_assert(alignof(S) == 32, "");
u.cpp:2:1: error: static assertion failed
 static_assert(alignof(S) == 32, "");
 ^~~~~~~~~~~~~
Comment 5 John Paul Adrian Glaubitz 2017-03-07 21:52:05 UTC
Still reproducible on gcc-7 (r243972).
Comment 6 Jonas Hahnfeld 2020-12-05 09:48:33 UTC
Still there in 10.2.0:

 $ cat alignas-multiple.cpp 
struct alignas(4) alignas(8) A { };
struct alignas(8) alignas(4) B { };

static_assert(alignof(A) == 8, "should have strictest alignment");
static_assert(alignof(B) == 8, "should have strictest alignment");
 $ g++ -c alignas-multiple.cpp 
alignas-multiple.cpp:5:26: error: static assertion failed: should have strictest alignment
    5 | static_assert(alignof(B) == 8, "should have strictest alignment");
      |               ~~~~~~~~~~~^~~~
 $ clang++ -c alignas-multiple.cpp
 $ echo $?
0
Comment 7 Jose Dapena Paz 2023-05-22 08:50:35 UTC
Still present in GCC 12.2.0. It is breaking Chromium build after these changes: https://chromium-review.googlesource.com/c/chromium/src/+/4542940/4/base/allocator/partition_allocator/partition_address_space.h