From: Daniel Dunbar Date: Tue, 27 Oct 2009 19:21:30 +0000 (+0000) Subject: Fix crash when synthesizing property setters when the property type and ivar X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=45e8423d7dcea657c14c55347e8a30ac904d7501;p=clang Fix crash when synthesizing property setters when the property type and ivar type have mismatched Objective-C types. - [irgen] crash in synthesized property construction git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85275 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index cadba328bf..2fe3f5b1b4 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -280,17 +280,29 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args), SetPropertyFn, Args); } else { + // FIXME: Find a clean way to avoid AST node creation. SourceLocation Loc = PD->getLocation(); ValueDecl *Self = OMD->getSelfDecl(); ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); DeclRefExpr Base(Self, Self->getType(), Loc); ParmVarDecl *ArgDecl = *OMD->param_begin(); DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc); - ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, - true, true); - BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign, - Ivar->getType(), Loc); - EmitStmt(&Assign); + ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, true, true); + + // The property type can differ from the ivar type in some situations with + // Objective-C pointer types, we can always bit cast the RHS in these cases. + if (getContext().getCanonicalType(Ivar->getType()) != + getContext().getCanonicalType(ArgDecl->getType())) { + ImplicitCastExpr ArgCasted(Ivar->getType(), CastExpr::CK_BitCast, &Arg, + false); + BinaryOperator Assign(&IvarRef, &ArgCasted, BinaryOperator::Assign, + Ivar->getType(), Loc); + EmitStmt(&Assign); + } else { + BinaryOperator Assign(&IvarRef, &Arg, BinaryOperator::Assign, + Ivar->getType(), Loc); + EmitStmt(&Assign); + } } FinishFunction(); diff --git a/test/CodeGenObjC/synthesize_ivar.m b/test/CodeGenObjC/synthesize_ivar.m index 7646f707bf..e1746f1da1 100644 --- a/test/CodeGenObjC/synthesize_ivar.m +++ b/test/CodeGenObjC/synthesize_ivar.m @@ -1,8 +1,6 @@ // RUN: clang-cc -triple x86_64-apple-darwin10 -emit-llvm -o %t %s @interface I -{ -} @property int IP; @end @@ -25,3 +23,16 @@ @implementation OrganizerViolatorView @synthesize bindingInfo; @end + +// [irgen] crash in synthesized property construction + +@interface I0 @end +@protocol P0 @end +@interface I1 { + I0 *iv0; +} +@property (assign, readwrite) id p0; +@end +@implementation I1 +@synthesize p0 = iv0; +@end diff --git a/test/Coverage/objc-language-features.inc b/test/Coverage/objc-language-features.inc index dd57dfbedd..dbbf205fcd 100644 --- a/test/Coverage/objc-language-features.inc +++ b/test/Coverage/objc-language-features.inc @@ -14,6 +14,7 @@ @interface A : Root { int iv0; B *iv1; + B *iv2; } @property(readonly) int p0; @@ -21,11 +22,16 @@ @property(copy) id p2; @property(retain) id p3; @property(assign, getter=getme, setter=setme:) id p4; +@property(assign, readwrite) id p5; @end @implementation A @dynamic p0; @synthesize p1 = iv0; + +// Property type can differ from ivar type. +@synthesize p5 = iv2; + +(void) fm0 { [super fm0]; }