From: Erik Pilkington Date: Mon, 6 Apr 2020 14:17:30 +0000 (-0400) Subject: [CodeGenObjC] Fix a crash when attempting to copy a zero-sized bit-field in a non... X-Git-Tag: llvmorg-12-init~9887 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d33c7de8e11f2727ef5e325d931ae94af8619bf9;p=platform%2Fupstream%2Fllvm.git [CodeGenObjC] Fix a crash when attempting to copy a zero-sized bit-field in a non-trivial C struct 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 --- diff --git a/clang/include/clang/AST/NonTrivialTypeVisitor.h b/clang/include/clang/AST/NonTrivialTypeVisitor.h index aafcedb..c955165 100644 --- a/clang/include/clang/AST/NonTrivialTypeVisitor.h +++ b/clang/include/clang/AST/NonTrivialTypeVisitor.h @@ -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. diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp index 91303ce..4a2c3b2 100644 --- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp +++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp @@ -254,6 +254,10 @@ struct GenBinaryFuncName : CopyStructVisitor, 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, std::array 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); diff --git a/clang/test/CodeGenObjC/strong-in-c-struct.m b/clang/test/CodeGenObjC/strong-in-c-struct.m index ec212c4..f022711 100644 --- a/clang/test/CodeGenObjC/strong-in-c-struct.m +++ b/clang/test/CodeGenObjC/strong-in-c-struct.m @@ -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 */