[clang] d33c7de - [CodeGenObjC] Fix a crash when attempting to copy a zero-sized bit-field in a non-trivial C struct
Erik Pilkington via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 6 13:04:22 PDT 2020
Author: Erik Pilkington
Date: 2020-04-06T16:04:13-04:00
New Revision: d33c7de8e11f2727ef5e325d931ae94af8619bf9
URL: https://github.com/llvm/llvm-project/commit/d33c7de8e11f2727ef5e325d931ae94af8619bf9
DIFF: https://github.com/llvm/llvm-project/commit/d33c7de8e11f2727ef5e325d931ae94af8619bf9.diff
LOG: [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
Added:
Modified:
clang/include/clang/AST/NonTrivialTypeVisitor.h
clang/lib/CodeGen/CGNonTrivialStruct.cpp
clang/test/CodeGenObjC/strong-in-c-struct.m
Removed:
################################################################################
diff --git a/clang/include/clang/AST/NonTrivialTypeVisitor.h b/clang/include/clang/AST/NonTrivialTypeVisitor.h
index aafcedb9d10b..c95516538ad1 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 91303cea325f..4a2c3b290382 100644
--- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp
+++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp
@@ -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);
diff --git a/clang/test/CodeGenObjC/strong-in-c-struct.m b/clang/test/CodeGenObjC/strong-in-c-struct.m
index ec212c46803d..f0227119279f 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 */
More information about the cfe-commits
mailing list