ahatanak created this revision. ahatanak added a subscriber: cfe-commits. Sema::CheckCastAlign currently ignores the aligned attribute attached to the declared variables, which causes clang to issue spurious warnings. This patch fixes the bug.
http://reviews.llvm.org/D21099 Files: lib/Sema/SemaChecking.cpp test/Sema/warn-cast-align.c Index: test/Sema/warn-cast-align.c =================================================================== --- test/Sema/warn-cast-align.c +++ test/Sema/warn-cast-align.c @@ -39,3 +39,23 @@ 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; +} Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -9304,6 +9304,23 @@ if (SrcPointee->isIncompleteType()) return; CharUnits SrcAlign = Context.getTypeAlignInChars(SrcPointee); + Expr *SE = nullptr; + + if (auto *CE = dyn_cast<CastExpr>(Op)) { + if (CE->getCastKind() == CK_ArrayToPointerDecay) + SE = CE->getSubExpr(); + } else if (auto *UO = dyn_cast<UnaryOperator>(Op)) { + if (UO->getOpcode() == UO_AddrOf) + SE = UO->getSubExpr(); + } + + if (SE) { + if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SE)) + SrcAlign = Context.getDeclAlign(DRE->getDecl()); + else if (const MemberExpr *ME = dyn_cast<MemberExpr>(SE)) + SrcAlign = Context.getDeclAlign(ME->getMemberDecl()); + } + if (SrcAlign >= DestAlign) return; Diag(TRange.getBegin(), diag::warn_cast_align)
Index: test/Sema/warn-cast-align.c =================================================================== --- test/Sema/warn-cast-align.c +++ test/Sema/warn-cast-align.c @@ -39,3 +39,23 @@ 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; +} Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -9304,6 +9304,23 @@ if (SrcPointee->isIncompleteType()) return; CharUnits SrcAlign = Context.getTypeAlignInChars(SrcPointee); + Expr *SE = nullptr; + + if (auto *CE = dyn_cast<CastExpr>(Op)) { + if (CE->getCastKind() == CK_ArrayToPointerDecay) + SE = CE->getSubExpr(); + } else if (auto *UO = dyn_cast<UnaryOperator>(Op)) { + if (UO->getOpcode() == UO_AddrOf) + SE = UO->getSubExpr(); + } + + if (SE) { + if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SE)) + SrcAlign = Context.getDeclAlign(DRE->getDecl()); + else if (const MemberExpr *ME = dyn_cast<MemberExpr>(SE)) + SrcAlign = Context.getDeclAlign(ME->getMemberDecl()); + } + if (SrcAlign >= DestAlign) return; Diag(TRange.getBegin(), diag::warn_cast_align)
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits