diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -913,6 +913,9 @@ InGroup; def err_pragma_options_align_mac68k_target_unsupported : Error< "mac68k alignment pragma is not supported on this target">; +def warn_pragma_align_not_xl_compatible : Warning< + "#pragma align(packed) may not be compatible with objects generated with AIX XL C/C++">, + InGroup; def warn_pragma_pack_invalid_alignment : Warning< "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">, InGroup; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -16573,6 +16573,23 @@ // Notify the consumer that we've defined a tag. if (!Tag->isInvalidDecl()) Consumer.HandleTagDeclDefinition(Tag); + + // Clangs implementation of #pragma align(packed) differs in bitfield layout + // from XLs and instead matches the XL #pragma pack(1) behavior. + if (Context.getTargetInfo().getTriple().isOSAIX() && + AlignPackStack.hasValue()) { + AlignPackInfo APInfo = AlignPackStack.CurrentValue; + // Only diagnose #pragma align(packed). + if (!APInfo.IsAlignAttr() || APInfo.getAlignMode() != AlignPackInfo::Packed) + return; + const RecordDecl *RD = dyn_cast(Tag); + if (!RD) + return; + // Only warn if there is at least 1 bitfield member. + if (llvm::any_of(RD->fields(), + [](const FieldDecl *FD) { return FD->isBitField(); })) + Diag(BraceRange.getBegin(), diag::warn_pragma_align_not_xl_compatible); + } } void Sema::ActOnObjCContainerFinishDefinition() { diff --git a/clang/test/Sema/aix-pragma-align-packed-warn.c b/clang/test/Sema/aix-pragma-align-packed-warn.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/aix-pragma-align-packed-warn.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -fxl-pragma-pack -verify -fsyntax-only %s +// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -fxl-pragma-pack -verify -fsyntax-only %s + +#pragma align(packed) +struct A { // expected-warning {{#pragma align(packed) may not be compatible with objects generated with AIX XL C/C++}} + short s1; + int : 0; + short s2; +}; + +struct B { // expected-warning {{#pragma align(packed) may not be compatible with objects generated with AIX XL C/C++}} + short a : 8; + short b : 8; + int c; +}; + +struct C { + int x, y, z; +}; +#pragma align(reset)