diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2497,8 +2497,10 @@ const RecordDecl *RD = RT->getDecl(); // When used as part of a typedef, or together with a 'packed' attribute, - // the 'aligned' attribute can be used to decrease alignment. - if ((TI.isAlignRequired() && T->getAs() != nullptr) || + // the 'aligned' attribute can be used to decrease alignment. Note that the + // 'packed' case is already taken into consideration when computing the + // alignment, we only need to handle the typedef case here. + if (TI.AlignRequirement == AlignRequirementKind::RequiredByTypedef || RD->isInvalidDecl()) return ABIAlign; diff --git a/clang/test/Layout/aix-power-alignment-typedef-2.cpp b/clang/test/Layout/aix-power-alignment-typedef-2.cpp --- a/clang/test/Layout/aix-power-alignment-typedef-2.cpp +++ b/clang/test/Layout/aix-power-alignment-typedef-2.cpp @@ -4,12 +4,26 @@ // RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ < %s | \ // RUN: FileCheck %s -struct C { +namespace test1 { +struct S { double x; }; -typedef struct C __attribute__((__aligned__(2))) CC; +typedef struct S __attribute__((__aligned__(2))) SS; -CC cc; +SS ss; -// CHECK: @cc = global %struct.C zeroinitializer, align 2 +// CHECK: @{{.*}}test1{{.*}}ss{{.*}} = global %"struct.test1::S" zeroinitializer, align 2 +} // namespace test1 + +namespace test2 { +struct __attribute__((__aligned__(2))) S { + double x; +}; + +typedef struct S SS; + +SS ss; + +// CHECK: @{{.*}}test2{{.*}}ss{{.*}} = global %"struct.test2::S" zeroinitializer, align 8 +} // namespace test2