[cfe-commits] r113154 - in /cfe/trunk: lib/CodeGen/CGObjCMac.cpp test/CodeGenObjC/ivars.m
Argyrios Kyrtzidis
akyrtzi at gmail.com
Mon Sep 6 05:00:10 PDT 2010
Author: akirtzidis
Date: Mon Sep 6 07:00:10 2010
New Revision: 113154
URL: http://llvm.org/viewvc/llvm-project?rev=113154&view=rev
Log:
LastFieldBitfield in CGObjCCommonMac::BuildAggrIvarLayout keeps bitfields or unnamed fields but later the code
assumes that it's always a bitfield. This can lead to a crash (reported at rdar://8368320).
Modified:
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
cfe/trunk/test/CodeGenObjC/ivars.m
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=113154&r1=113153&r2=113154&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Mon Sep 6 07:00:10 2010
@@ -3586,10 +3586,10 @@
uint64_t MaxSkippedUnionIvarSize = 0;
FieldDecl *MaxField = 0;
FieldDecl *MaxSkippedField = 0;
- FieldDecl *LastFieldBitfield = 0;
+ FieldDecl *LastFieldBitfieldOrUnnamed = 0;
uint64_t MaxFieldOffset = 0;
uint64_t MaxSkippedFieldOffset = 0;
- uint64_t LastBitfieldOffset = 0;
+ uint64_t LastBitfieldOrUnnamedOffset = 0;
if (RecFields.empty())
return;
@@ -3609,12 +3609,12 @@
// Skip over unnamed or bitfields
if (!Field->getIdentifier() || Field->isBitField()) {
- LastFieldBitfield = Field;
- LastBitfieldOffset = FieldOffset;
+ LastFieldBitfieldOrUnnamed = Field;
+ LastBitfieldOrUnnamedOffset = FieldOffset;
continue;
}
- LastFieldBitfield = 0;
+ LastFieldBitfieldOrUnnamed = 0;
QualType FQT = Field->getType();
if (FQT->isRecordType() || FQT->isUnionType()) {
if (FQT->isUnionType())
@@ -3703,16 +3703,25 @@
}
}
- if (LastFieldBitfield) {
- // Last field was a bitfield. Must update skip info.
- Expr *BitWidth = LastFieldBitfield->getBitWidth();
- uint64_t BitFieldSize =
- BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
- GC_IVAR skivar;
- skivar.ivar_bytepos = BytePos + LastBitfieldOffset;
- skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
- + ((BitFieldSize % ByteSizeInBits) != 0);
- SkipIvars.push_back(skivar);
+ if (LastFieldBitfieldOrUnnamed) {
+ if (LastFieldBitfieldOrUnnamed->isBitField()) {
+ // Last field was a bitfield. Must update skip info.
+ Expr *BitWidth = LastFieldBitfieldOrUnnamed->getBitWidth();
+ uint64_t BitFieldSize =
+ BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
+ GC_IVAR skivar;
+ skivar.ivar_bytepos = BytePos + LastBitfieldOrUnnamedOffset;
+ skivar.ivar_size = (BitFieldSize / ByteSizeInBits)
+ + ((BitFieldSize % ByteSizeInBits) != 0);
+ SkipIvars.push_back(skivar);
+ } else {
+ assert(!LastFieldBitfieldOrUnnamed->getIdentifier() &&"Expected unnamed");
+ // Last field was unnamed. Must update skip info.
+ unsigned FieldSize
+ = CGM.getContext().getTypeSize(LastFieldBitfieldOrUnnamed->getType());
+ SkipIvars.push_back(GC_IVAR(BytePos + LastBitfieldOrUnnamedOffset,
+ FieldSize / ByteSizeInBits));
+ }
}
if (MaxField)
Modified: cfe/trunk/test/CodeGenObjC/ivars.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/ivars.m?rev=113154&r1=113153&r2=113154&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/ivars.m (original)
+++ cfe/trunk/test/CodeGenObjC/ivars.m Mon Sep 6 07:00:10 2010
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -emit-llvm -o - %s
// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o - %s
+// RUN: %clang_cc1 -fobjc-gc -emit-llvm -o - %s
// rdar://6800926
@interface ITF {
@@ -12,3 +13,17 @@
void foo(ITF *P) {
P->boolfield = 1;
}
+
+// rdar://8368320
+ at interface R {
+ struct {
+ union {
+ int x;
+ char c;
+ };
+ } _union;
+}
+ at end
+
+ at implementation R
+ at end
More information about the cfe-commits
mailing list