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; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits