aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AST/ASTContext.cpp6
-rw-r--r--test/Sema/align-x86.c6
2 files changed, 12 insertions, 0 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index c8caeb62b3..202e3370b6 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -563,6 +563,12 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) {
Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
}
+ if (const FieldDecl *FD = dyn_cast<FieldDecl>(VD)) {
+ // In the case of a field in a packed struct, we want the minimum
+ // of the alignment of the field and the alignment of the struct.
+ Align = std::min(Align,
+ getPreferredTypeAlign(FD->getParent()->getTypeForDecl()));
+ }
}
return CharUnits::fromQuantity(Align / Target.getCharWidth());
diff --git a/test/Sema/align-x86.c b/test/Sema/align-x86.c
index f67adecbf5..c9a63989ec 100644
--- a/test/Sema/align-x86.c
+++ b/test/Sema/align-x86.c
@@ -12,3 +12,9 @@ short chk2[__alignof__(long long) == 8 ? 1 : -1];
_Complex double g3;
short chk1[__alignof__(g3) == 8 ? 1 : -1];
short chk2[__alignof__(_Complex double) == 8 ? 1 : -1];
+
+// PR6362
+struct __attribute__((packed)) {unsigned int a} g4;
+short chk1[__alignof__(g4) == 1 ? 1 : -1];
+short chk2[__alignof__(g4.a) == 1 ? 1 : -1];
+