[PATCH] D90630: [CodeGen] Fix Bug 47499: __unaligned extension inconsistent behaviour with C and C++

Jan Ole Hüser via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 2 10:20:35 PST 2020


j0le created this revision.
j0le added reviewers: rogfer01, rnk.
j0le added a project: clang.
Herald added a subscriber: cfe-commits.
j0le requested review of this revision.

Hello everyone,

I think, I have found the reason, why there is a difference between C and C++ for the keyword __unaligned:
For C, the Method getAsCXXREcordDecl() returns nullptr. That guarantees that hasUnaligned() is called.
If the language is C++, it is not guaranteed, that hasUnaligend() is called and evaluated.

I have some questions:

- Does this CXXRecordDecl contain information, whether the keyword  __unaligned is used?
- Does getClassPointerAlignment() has some side effects, that are needed?

Here are some links:

https://bugs.llvm.org/show_bug.cgi?id=47499
Thread on the cfe-dev mailing list: http://lists.llvm.org/pipermail/cfe-dev/2020-September/066783.html
Diff, that introduced the check hasUnaligned() in getNaturalTypeAlignment(): https://reviews.llvm.org/D30166

Kind Regards
Ole

(Jan Ole Hüser)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D90630

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/unaligned-struct-copy.c


Index: clang/test/CodeGen/unaligned-struct-copy.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/unaligned-struct-copy.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -xc   -O2 -triple thumbv7a-unknown-windows-eabi -fms-extensions -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -xc++ -O2 -triple thumbv7a-unknown-windows-eabi -fms-extensions -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -xc   -O2 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -xc++ -O2 -triple x86_64-unknown-linux-gnu -fms-extensions -emit-llvm < %s | FileCheck %s
+
+struct S1 {
+  unsigned long x;
+};
+
+// CHECK: define
+// CHECK-SAME: void
+// CHECK-SAME: test1
+
+void test1(__unaligned struct S1 *out) {
+  // CHECK: store
+  // CHECK-SAME: align 1
+  out->x = 5;
+  // CHECK: ret void
+}
+
+// CHECK: define
+// CHECK-SAME: void
+// CHECK-SAME: test2
+
+void test2(__unaligned struct S1 *out, __unaligned struct S1 *in) {
+  // CHECK: load
+  // CHECK-SAME: align 1
+  // CHECK: store
+  // CHECK-SAME: align 1
+  *out = *in;
+  // CHECK: ret void
+}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -6146,16 +6146,17 @@
     *BaseInfo = LValueBaseInfo(AlignmentSource::Type);
 
   CharUnits Alignment;
+  const CXXRecordDecl *RD;
+  if (T.getQualifiers().hasUnaligned()) {
+    Alignment = CharUnits::One();
+  }
   // For C++ class pointees, we don't know whether we're pointing at a
   // base or a complete object, so we generally need to use the
   // non-virtual alignment.
-  const CXXRecordDecl *RD;
-  if (forPointeeType && !AlignForArray && (RD = T->getAsCXXRecordDecl())) {
+  else if (forPointeeType && !AlignForArray && (RD = T->getAsCXXRecordDecl())) {
     Alignment = getClassPointerAlignment(RD);
   } else {
     Alignment = getContext().getTypeAlignInChars(T);
-    if (T.getQualifiers().hasUnaligned())
-      Alignment = CharUnits::One();
   }
 
   // Cap to the global maximum type alignment unless the alignment


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D90630.302316.patch
Type: text/x-patch
Size: 2169 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20201102/0617dc61/attachment-0001.bin>


More information about the cfe-commits mailing list