[llvm-branch-commits] [clang] 104dfd2 - Initial implementation of corrected fix
Zarko Todorovski via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jan 26 19:17:32 PST 2022
Author: Zarko Todorovski
Date: 2022-01-26T22:16:52-05:00
New Revision: 104dfd2b26361f1caf2ad116cbc709c49355da75
URL: https://github.com/llvm/llvm-project/commit/104dfd2b26361f1caf2ad116cbc709c49355da75
DIFF: https://github.com/llvm/llvm-project/commit/104dfd2b26361f1caf2ad116cbc709c49355da75.diff
LOG: Initial implementation of corrected fix
Added:
Modified:
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/Sema/aix-attr-align.c
Removed:
################################################################################
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4b609f4b1477c..c5ed62943e320 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -12691,7 +12691,7 @@ class Sema final {
const FunctionProtoType *Proto, SourceLocation Loc);
void CheckArgAlignment(SourceLocation Loc, NamedDecl *FDecl,
- StringRef ParamName, QualType ArgTy, QualType ParamTy);
+ StringRef ParamName, QualType ArgTy, QualType ParamTy, const Expr* Arg = nullptr);
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
const Expr *ThisArg, ArrayRef<const Expr *> Args,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index c8fb36b8311a4..fc78d9071fbb5 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5207,7 +5207,37 @@ static void CheckNonNullArguments(Sema &S,
/// calling functions defined in terms of the original type.
void Sema::CheckArgAlignment(SourceLocation Loc, NamedDecl *FDecl,
StringRef ParamName, QualType ArgTy,
- QualType ParamTy) {
+ QualType ParamTy, const Expr* Arg) {
+
+ // 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 passed to function.
+ if (Context.getTargetInfo().getTriple().isOSAIX()) {
+ if (Arg->IgnoreParens()) {
+ // Using AArg so as to not modify Arg for the rest of the function.
+ const Expr *AArg = Arg->IgnoreParens();
+ if (AArg->getStmtClass() == Stmt::ImplicitCastExprClass) {
+ const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(AArg);
+ AArg = ICE->getSubExpr();
+ if (AArg->getStmtClass() == Stmt::MemberExprClass) {
+ const auto *ME = dyn_cast<MemberExpr>(AArg);
+ ValueDecl *MD = ME->getMemberDecl();
+ auto *FD = dyn_cast<FieldDecl>(MD);
+ if (FD) {
+ if (FD->hasAttr<AlignedAttr>()) {
+ auto *AA = FD->getAttr<AlignedAttr>();
+ unsigned Aligned = AA->getAlignment(Context);
+ // Divide by 8 to get the bytes instead of using bits.
+ if (Aligned / 8 >= 16)
+ Diag(Loc, diag::warn_not_xl_compatible) << FD;
+ }
+ }
+ }
+ }
+ }
+ }
// If a function accepts a pointer or reference type
if (!ParamTy->isPointerType() && !ParamTy->isReferenceType())
@@ -5314,7 +5344,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
QualType ParamTy = Proto->getParamType(ArgIdx);
QualType ArgTy = Arg->getType();
CheckArgAlignment(Arg->getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
- ArgTy, ParamTy);
+ ArgTy, ParamTy, Arg);
}
}
}
@@ -5352,7 +5382,7 @@ void Sema::CheckConstructorCall(FunctionDecl *FDecl, QualType ThisType,
auto *Ctor = cast<CXXConstructorDecl>(FDecl);
CheckArgAlignment(Loc, FDecl, "'this'", Context.getPointerType(ThisType),
- Context.getPointerType(Ctor->getThisObjectType()));
+ Context.getPointerType(Ctor->getThisObjectType()), nullptr);
checkCall(FDecl, Proto, /*ThisArg=*/nullptr, Args, /*IsMemberFunction=*/true,
Loc, SourceRange(), CallType);
@@ -5396,7 +5426,7 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
Context.getPointerType(cast<CXXMethodDecl>(FDecl)->getThisObjectType());
CheckArgAlignment(TheCall->getRParenLoc(), FDecl, "'this'", ThisType,
- ThisTypeFromDecl);
+ ThisTypeFromDecl, nullptr);
}
checkCall(FDecl, Proto, ImplicitThis, llvm::makeArrayRef(Args, NumArgs),
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 955f477760429..61c30a0f34216 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -4320,13 +4320,6 @@ void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
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<FieldDecl>(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/Sema/aix-attr-align.c b/clang/test/Sema/aix-attr-align.c
index 0fd6af4ee4c13..5da8ab7890946 100644
--- a/clang/test/Sema/aix-attr-align.c
+++ b/clang/test/Sema/aix-attr-align.c
@@ -6,17 +6,31 @@
// 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))); // no-warning
+ int c[2] __attribute__((aligned(32))); // no-warning
};
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 *);
+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 {{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}}
+ baz(s.c); // 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}}
+
+ baz(a); // no-warning
+ baz(b); // no-warning
+ baz(c); // no-warning
+}
More information about the llvm-branch-commits
mailing list