[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cfe-commits
Subject:    [PATCH] D21099: [Sema] Teach -Wcast-align to look at the aligned attribute of the declared variables
From:       Akira Hatanaka via Phabricator via cfe-commits <cfe-commits () lists ! llvm ! org>
Date:       2016-11-30 19:52:12
Message-ID: 0ce72cc58ac38fcae39ed88763aa6563 () localhost ! localdomain
[Download RAW message or body]

This revision was automatically updated to reflect the committed changes.
Closed by commit rL288267: [Sema] Teach -Wcast-align to look at the aligned attribute \
of the (authored by ahatanak).

Changed prior to commit:
  https://reviews.llvm.org/D21099?vs=78594&id=79792#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D21099

Files:
  cfe/trunk/lib/Sema/SemaChecking.cpp
  cfe/trunk/test/Sema/warn-cast-align.c


Index: cfe/trunk/test/Sema/warn-cast-align.c
===================================================================
--- cfe/trunk/test/Sema/warn-cast-align.c
+++ cfe/trunk/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: cfe/trunk/lib/Sema/SemaChecking.cpp
===================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp
+++ cfe/trunk/lib/Sema/SemaChecking.cpp
@@ -10264,6 +10264,19 @@
   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 @@
   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)


["D21099.79792.patch" (text/x-patch)]

Index: cfe/trunk/test/Sema/warn-cast-align.c
===================================================================
--- cfe/trunk/test/Sema/warn-cast-align.c
+++ cfe/trunk/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: cfe/trunk/lib/Sema/SemaChecking.cpp
===================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp
+++ cfe/trunk/lib/Sema/SemaChecking.cpp
@@ -10264,6 +10264,19 @@
   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 @@
   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)

[Attachment #4 (text/plain)]

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic