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 @@ -3296,9 +3296,9 @@ "alignment assumed">, InGroup>; def warn_not_xl_compatible - : Warning<"requesting an alignment of 16 bytes or greater for struct" - " members is not binary compatible with IBM XL C/C++ for AIX" - " 16.1.0 and older">, + : Warning<" %0 byte requested alignment for a struct member used as an" + " argument is 16 bytes or greater which is not binary" + " compatible with IBM XL C/C++ for AIX 16.1.0 or older">, InGroup; def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning< "%q0 redeclared without %1 attribute: previous %1 ignored">, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -12690,6 +12690,9 @@ ArrayRef Args, const FunctionProtoType *Proto, SourceLocation Loc); + void checkAIXMemberAlignment(SourceLocation Loc, NamedDecl *FDecl, + StringRef ParamName, const Expr *Arg); + void CheckArgAlignment(SourceLocation Loc, NamedDecl *FDecl, StringRef ParamName, QualType ArgTy, QualType ParamTy); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5201,6 +5201,32 @@ } } +// 16 byte ByVal alignment not due to a vector member is not honoured by XL +// on AIX. Emit a warning here that users are generating binary incompatible +// code to be safe. +// Here we try to get information about the alignment of the struct member +// argument being passed to the caller function. +void Sema::checkAIXMemberAlignment(SourceLocation Loc, NamedDecl *FDecl, + StringRef ParamName, const Expr *Arg) { + + if (const auto *ICE = dyn_cast(Arg->IgnoreParens())) { + if (const auto *ME = dyn_cast(ICE->getSubExpr())) { + if (auto *FD = dyn_cast(ME->getMemberDecl())) { + if (const auto *AA = FD->getAttr()) { + CharUnits Alignment = + Context.toCharUnitsFromBits(AA->getAlignment(Context)); + if (Alignment.getQuantity() >= 16) { + Diag(Loc, diag::warn_not_xl_compatible) + << (unsigned)Alignment.getQuantity() << FD; + Diag(FD->getLocation(), diag::note_entity_declared_at) + << FD->getDeclName(); + } + } + } + } + } +} + /// Warn if a pointer or reference argument passed to a function points to an /// object that is less aligned than the parameter. This can happen when /// creating a typedef with a lower alignment than the original type and then @@ -5313,6 +5339,11 @@ QualType ParamTy = Proto->getParamType(ArgIdx); QualType ArgTy = Arg->getType(); + if (Context.getTargetInfo().getTriple().isOSAIX() && Arg && + FDecl->hasLinkage() && FDecl->getFormalLinkage() != InternalLinkage) + checkAIXMemberAlignment((Arg->getExprLoc()), FDecl, + std::to_string(ArgIdx + 1), Arg); + CheckArgAlignment(Arg->getExprLoc(), FDecl, std::to_string(ArgIdx + 1), ArgTy, ParamTy); } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -4321,13 +4321,6 @@ return; uint64_t AlignVal = Alignment.getZExtValue(); - // 16 byte ByVal alignment not due to a vector member is not honoured by XL - // on AIX. Emit a warning here that users are generating binary incompatible - // code to be safe. - if (AlignVal >= 16 && isa(D) && - Context.getTargetInfo().getTriple().isOSAIX()) - Diag(AttrLoc, diag::warn_not_xl_compatible) << E->getSourceRange(); - // C++11 [dcl.align]p2: // -- if the constant expression evaluates to zero, the alignment // specifier shall have no effect diff --git a/clang/test/Analysis/padding_c.c b/clang/test/Analysis/padding_c.c --- a/clang/test/Analysis/padding_c.c +++ b/clang/test/Analysis/padding_c.c @@ -1,10 +1,8 @@ -// FIXME -Wno-aix-compat added temporarily while the diagnostic is being -// refined. -// RUN: %clang_analyze_cc1 -verify -Wno-aix-compat %s \ +// RUN: %clang_analyze_cc1 -verify %s \ // RUN: -analyzer-checker=optin.performance \ // RUN: -analyzer-config optin.performance.Padding:AllowedPad=2 -// RUN: not %clang_analyze_cc1 -verify -Wno-aix-compat %s \ +// RUN: not %clang_analyze_cc1 -verify %s \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=optin.performance.Padding \ // RUN: -analyzer-config optin.performance.Padding:AllowedPad=-10 \ diff --git a/clang/test/Analysis/padding_cpp.cpp b/clang/test/Analysis/padding_cpp.cpp --- a/clang/test/Analysis/padding_cpp.cpp +++ b/clang/test/Analysis/padding_cpp.cpp @@ -1,6 +1,4 @@ -// FIXME -Wno-aix-compat added temporarily while the diagnostic is being -// refined. -// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify -Wno-aix-compat %s +// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s // Make sure that the C cases still work fine, even when compiled as C++. #include "padding_c.c" diff --git a/clang/test/CXX/drs/dr6xx.cpp b/clang/test/CXX/drs/dr6xx.cpp --- a/clang/test/CXX/drs/dr6xx.cpp +++ b/clang/test/CXX/drs/dr6xx.cpp @@ -1,10 +1,8 @@ -// FIXME -Wno-aix-compat added temporarily while the diagnostic is being -// refined. -// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -Wno-aix-compat -// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -Wno-aix-compat -// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -Wno-aix-compat -// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -Wno-aix-compat -// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking -Wno-aix-compat +// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking +// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking +// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking +// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking +// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -fno-spell-checking namespace std { struct type_info {}; diff --git a/clang/test/Sema/aix-attr-align.c b/clang/test/Sema/aix-attr-align.c --- a/clang/test/Sema/aix-attr-align.c +++ b/clang/test/Sema/aix-attr-align.c @@ -6,17 +6,43 @@ // RUN: %clang_cc1 -triple powerpc64le-unknown-linux -verify=off -fsyntax-only %s struct S { - int a[8] __attribute__((aligned(8))); // no-warning + int a[8] __attribute__((aligned(8))); // no-warning + int b[8] __attribute__((aligned(16))); // expected-note {{'b' declared here}} + int c[2] __attribute__((aligned(32))); // expected-note {{'c' declared here}} }; struct T { - int a[4] __attribute__((aligned(16))); // expected-warning {{requesting an alignment of 16 bytes or greater for struct members is not binary compatible with IBM XL C/C++ for AIX 16.1.0 and older}} + int a[4] __attribute__((aligned(16))); // no-warning }; struct U { - int a[2] __attribute__((aligned(32))); // expected-warning {{requesting an alignment of 16 bytes or greater for struct members is not binary compatible with IBM XL C/C++ for AIX 16.1.0 and older}} + int a[2] __attribute__((aligned(32))); // no-warning }; int a[8] __attribute__((aligned(8))); // no-warning int b[4] __attribute__((aligned(16))); // no-warning int c[2] __attribute__((aligned(32))); // no-warning + +void baz(int *); +static void static_baz(int *b) { + b = b + 1; +} + +void foo(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8, + struct S s) { + baz(s.a); // no-warning + baz(s.b); // expected-warning {{16 byte requested alignment for a struct member used as an argument is 16 bytes or greater which is not binary compatible with IBM XL C/C++ for AIX 16.1.0 or older}} + baz(s.c); // expected-warning {{32 byte requested alignment for a struct member used as an argument is 16 bytes or greater which is not binary compatible with IBM XL C/C++ for AIX 16.1.0 or older}} + + baz(a); // no-warning + baz(b); // no-warning + baz(c); // no-warning + + static_baz(s.a); // no-warning + static_baz(s.b); // no-warning + static_baz(s.c); // no-warning + + static_baz(a); // no-warning + static_baz(b); // no-warning + static_baz(c); // no-warning +} diff --git a/clang/test/SemaTemplate/instantiate-attr.cpp b/clang/test/SemaTemplate/instantiate-attr.cpp --- a/clang/test/SemaTemplate/instantiate-attr.cpp +++ b/clang/test/SemaTemplate/instantiate-attr.cpp @@ -1,7 +1,4 @@ -// FIXME -Wno-aix-compat added temporarily while the diagnostic is being -// refined. - -// RUN: %clang_cc1 -fsyntax-only -verify -Wno-aix-compat %s +// RUN: %clang_cc1 -fsyntax-only -verify %s // expected-no-diagnostics template struct A {