r288267 - [Sema] Teach -Wcast-align to look at the aligned attribute of the
Akira Hatanaka via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 30 11:42:03 PST 2016
Author: ahatanak
Date: Wed Nov 30 13:42:03 2016
New Revision: 288267
URL: http://llvm.org/viewvc/llvm-project?rev=288267&view=rev
Log:
[Sema] Teach -Wcast-align to look at the aligned attribute of the
declared variables.
Teach Sema to check the aligned attribute attached to variable
declarations so that it doesn't issue spurious warnings.
rdar://problem/26517471
Differential revision: https://reviews.llvm.org/D21099
Modified:
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/Sema/warn-cast-align.c
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=288267&r1=288266&r2=288267&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Wed Nov 30 13:42:03 2016
@@ -10264,6 +10264,19 @@ bool Sema::CheckParmsForFunctionDef(Arra
return HasInvalidParm;
}
+/// A helper function to get the alignment of a Decl referred to by DeclRefExpr
+/// or MemberExpr.
+static CharUnits getDeclAlign(Expr *E, CharUnits TypeAlign,
+ ASTContext &Context) {
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
+ return Context.getDeclAlign(DRE->getDecl());
+
+ if (const auto *ME = dyn_cast<MemberExpr>(E))
+ return Context.getDeclAlign(ME->getMemberDecl());
+
+ return TypeAlign;
+}
+
/// CheckCastAlign - Implements -Wcast-align, which warns when a
/// pointer cast increases the alignment requirements.
void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
@@ -10298,6 +10311,15 @@ void Sema::CheckCastAlign(Expr *Op, Qual
if (SrcPointee->isIncompleteType()) return;
CharUnits SrcAlign = Context.getTypeAlignInChars(SrcPointee);
+
+ if (auto *CE = dyn_cast<CastExpr>(Op)) {
+ if (CE->getCastKind() == CK_ArrayToPointerDecay)
+ SrcAlign = getDeclAlign(CE->getSubExpr(), SrcAlign, Context);
+ } else if (auto *UO = dyn_cast<UnaryOperator>(Op)) {
+ if (UO->getOpcode() == UO_AddrOf)
+ SrcAlign = getDeclAlign(UO->getSubExpr(), SrcAlign, Context);
+ }
+
if (SrcAlign >= DestAlign) return;
Diag(TRange.getBegin(), diag::warn_cast_align)
Modified: cfe/trunk/test/Sema/warn-cast-align.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-cast-align.c?rev=288267&r1=288266&r2=288267&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-cast-align.c (original)
+++ cfe/trunk/test/Sema/warn-cast-align.c Wed Nov 30 13:42:03 2016
@@ -39,3 +39,23 @@ void test2(char *P) {
void test3(char *P) {
struct B *b = (struct B*) P;
}
+
+// Do not issue a warning. The aligned attribute changes the alignment of the
+// variables and fields.
+char __attribute__((aligned(4))) a[16];
+
+struct S0 {
+ char a[16];
+};
+
+struct S {
+ char __attribute__((aligned(4))) a[16];
+ struct S0 __attribute__((aligned(4))) s0;
+};
+
+void test4() {
+ struct S s;
+ int *i = (int *)s.a;
+ i = (int *)&s.s0;
+ i = (int *)a;
+}
More information about the cfe-commits
mailing list