[CodeGenObjC] Fix a crash when attempting to copy a zero-sized bit-field in a non...
authorErik Pilkington <erik.pilkington@gmail.com>
Mon, 6 Apr 2020 14:17:30 +0000 (10:17 -0400)
committerErik Pilkington <erik.pilkington@gmail.com>
Mon, 6 Apr 2020 20:04:13 +0000 (16:04 -0400)
Zero sized bit-fields aren't included in the CGRecordLayout, so we shouldn't be
calling EmitLValueForField for them. rdar://60695105

Differential revision: https://reviews.llvm.org/D76782

clang/include/clang/AST/NonTrivialTypeVisitor.h
clang/lib/CodeGen/CGNonTrivialStruct.cpp
clang/test/CodeGenObjC/strong-in-c-struct.m

index aafcedb..c955165 100644 (file)
@@ -1,4 +1,4 @@
-//===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types *- C++ --*-===//
+//===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types -*- C++ -*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
index 91303ce..4a2c3b2 100644 (file)
@@ -254,6 +254,10 @@ struct GenBinaryFuncName : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>,
 
   void visitVolatileTrivial(QualType FT, const FieldDecl *FD,
                             CharUnits CurStructOffset) {
+    // Zero-length bit-fields don't need to be copied/assigned.
+    if (FD && FD->isZeroLengthBitField(this->Ctx))
+      return;
+
     // Because volatile fields can be bit-fields and are individually copied,
     // their offset and width are in bits.
     uint64_t OffsetInBits =
@@ -543,6 +547,10 @@ struct GenBinaryFunc : CopyStructVisitor<Derived, IsMove>,
                             std::array<Address, 2> Addrs) {
     LValue DstLV, SrcLV;
     if (FD) {
+      // No need to copy zero-length bit-fields.
+      if (FD->isZeroLengthBitField(this->CGF->getContext()))
+        return;
+
       QualType RT = QualType(FD->getParent()->getTypeForDecl(), 0);
       llvm::PointerType *PtrTy = this->CGF->ConvertType(RT)->getPointerTo();
       Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], Offset);
index ec212c4..f022711 100644 (file)
@@ -887,4 +887,17 @@ void test_volatile_variable_reference(volatile StrongSmall *a) {
   func(0);
 }
 
+struct ZeroBitfield {
+  int : 0;
+  id strong;
+};
+
+
+// CHECK: define linkonce_odr hidden void @__default_constructor_8_sv0
+// CHECK: define linkonce_odr hidden void @__copy_assignment_8_8_sv0
+void test_zero_bitfield() {
+  struct ZeroBitfield volatile a, b;
+  a = b;
+}
+
 #endif /* USESTRUCT */