aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2016-11-30 19:42:03 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2016-11-30 19:42:03 +0000
commit21e5fdd89e8a906f9c4e4bf00151691a0ccbb2f3 (patch)
tree45915070cf62eb1ee59788361a0a2437f024221e /clang/lib/Sema/SemaChecking.cpp
parent5c289b77fa94d13f565d23a64a75b18140d36021 (diff)
downloadllvm-21e5fdd89e8a906f9c4e4bf00151691a0ccbb2f3.zip
llvm-21e5fdd89e8a906f9c4e4bf00151691a0ccbb2f3.tar.gz
llvm-21e5fdd89e8a906f9c4e4bf00151691a0ccbb2f3.tar.bz2
[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 llvm-svn: 288267
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4fe3053..9e16554 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -10264,6 +10264,19 @@ bool Sema::CheckParmsForFunctionDef(ArrayRef<ParmVarDecl *> Parameters,
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, QualType T, SourceRange TRange) {
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)