]> granicus.if.org Git - clang/commitdiff
[Sema] Fix incorrect packed aligned structure layout
authorMomchil Velikov <momchil.velikov@arm.com>
Mon, 21 May 2018 14:28:43 +0000 (14:28 +0000)
committerMomchil Velikov <momchil.velikov@arm.com>
Mon, 21 May 2018 14:28:43 +0000 (14:28 +0000)
Handle attributes before checking the record layout (e.g. underalignment check
during `alignas` processing), as layout may be cached without taking into
account attributes that may affect it.

Differential Revision: https://reviews.llvm.org/D46439

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@332843 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
test/Layout/itanium-pack-and-align.cpp [new file with mode: 0644]

index 9a1ab4a3c587743b583e4f922e3231f0435b8532..e8e3faf7578552dcd7b306714b91d136f05f999b 100644 (file)
@@ -15594,6 +15594,10 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
     if (!Completed)
       Record->completeDefinition();
 
+    // Handle attributes before checking the layout.
+    if (Attr)
+      ProcessDeclAttributeList(S, Record, Attr);
+
     // We may have deferred checking for a deleted destructor. Check now.
     if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record)) {
       auto *Dtor = CXXRecord->getDestructor();
@@ -15724,9 +15728,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
       CDecl->setIvarRBraceLoc(RBrac);
     }
   }
-
-  if (Attr)
-    ProcessDeclAttributeList(S, Record, Attr);
 }
 
 /// Determine whether the given integral value is representable within
diff --git a/test/Layout/itanium-pack-and-align.cpp b/test/Layout/itanium-pack-and-align.cpp
new file mode 100644 (file)
index 0000000..6456916
--- /dev/null
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only -fdump-record-layouts %s \
+// RUN:            | FileCheck %s
+
+struct S {
+  char x;
+  int y;
+} __attribute__((packed, aligned(8)));
+
+struct alignas(8) T {
+  char x;
+  int y;
+} __attribute__((packed));
+
+S s;
+T t;
+// CHECK:          0 | struct T
+// CHECK-NEXT:          0 |   char x
+// CHECK-NEXT:          1 |   int y
+// CHECK-NEXT:            | [sizeof=8, dsize=8, align=8,
+// CHECK-NEXT:            |  nvsize=8, nvalign=8]
+
+// CHECK:          0 | struct S
+// CHECK-NEXT:          0 |   char x
+// CHECK-NEXT:          1 |   int y
+// CHECK-NEXT:            | [sizeof=8, dsize=8, align=8,
+// CHECK-NETX:            |  nvsize=8, nvalign=8]