[clang] fix: compatible C++ empty record with align UB with gcc (PR #72197)

via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 13 18:50:28 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: None (hstk30-hw)

<details>
<summary>Changes</summary>

About https://github.com/llvm/llvm-project/issues/69872 ,  just for compatible C++ empty record with align UB with gcc

https://godbolt.org/z/qsze8fqra 

---
Full diff: https://github.com/llvm/llvm-project/pull/72197.diff


2 Files Affected:

- (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+7-1) 
- (modified) clang/test/CodeGen/aarch64-args.cpp (+6) 


``````````diff
diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp
index 2b20d5a13346d34..bc8ac937be37399 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.cpp
+++ b/clang/lib/CodeGen/ABIInfoImpl.cpp
@@ -296,10 +296,16 @@ bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
     return false;
 
   // If this is a C++ record, check the bases first.
-  if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+  if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
     for (const auto &I : CXXRD->bases())
       if (!isEmptyRecord(Context, I.getType(), true, AsIfNoUniqueAddr))
         return false;
+    // C++ object size >= 1 byte, empty struct is 1 byte.
+    // FIXME: an alignment on a empty record is a UB, may just warning it,
+    // this code just want to compatible gcc.
+    if (Context.getTypeSize(T) > 8)
+      return false;
+  }
 
   for (const auto *I : RD->fields())
     if (!isEmptyField(Context, I, AllowArrays, AsIfNoUniqueAddr))
diff --git a/clang/test/CodeGen/aarch64-args.cpp b/clang/test/CodeGen/aarch64-args.cpp
index fe1298cc683a404..4794f0ae7c903dc 100644
--- a/clang/test/CodeGen/aarch64-args.cpp
+++ b/clang/test/CodeGen/aarch64-args.cpp
@@ -65,3 +65,9 @@ EXTERNC struct SortOfEmpty sort_of_empty_ret(void) {
   struct SortOfEmpty e;
   return e;
 }
+
+// CHECK-GNU-CXX: define{{.*}} i32 @empty_align_arg(i128 %a.coerce, i32 noundef %b)
+struct EmptyAlign { long long int __attribute__((aligned)) : 0; };
+EXTERNC int empty_align_arg(struct EmptyAlign a, int b) {
+  return b;
+}
\ No newline at end of file

``````````

</details>


https://github.com/llvm/llvm-project/pull/72197


More information about the cfe-commits mailing list