diff options
author | John McCall <rjmccall@apple.com> | 2011-12-06 02:56:18 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-12-06 02:56:18 +0000 |
commit | e5e1b88bbcf4288d671da42c2c9bfc113d843e1f (patch) | |
tree | bfaa89d90281a197b20710dcde2f5daf92569fab /clang | |
parent | c1610bede171d7cd813e6ab0432c97be2df8c218 (diff) | |
download | bcm5719-llvm-e5e1b88bbcf4288d671da42c2c9bfc113d843e1f.tar.gz bcm5719-llvm-e5e1b88bbcf4288d671da42c2c9bfc113d843e1f.zip |
Fix an extremely stupid bug causing terrible miscompilations
of &= on pseudo-objects.
llvm-svn: 145904
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/AST/Expr.h | 4 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/property.m | 43 |
2 files changed, 45 insertions, 2 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 33447f77167..ac4ffe0b438 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -2756,8 +2756,8 @@ public: } static Opcode getOpForCompoundAssignment(Opcode Opc) { assert(isCompoundAssignmentOp(Opc)); - if (Opc >= BO_XorAssign) - return Opcode(unsigned(Opc) - BO_XorAssign + BO_Xor); + if (Opc >= BO_AndAssign) + return Opcode(unsigned(Opc) - BO_AndAssign + BO_And); else return Opcode(unsigned(Opc) - BO_MulAssign + BO_Mul); } diff --git a/clang/test/CodeGenObjC/property.m b/clang/test/CodeGenObjC/property.m index 30f68e5b27f..16881d608bf 100644 --- a/clang/test/CodeGenObjC/property.m +++ b/clang/test/CodeGenObjC/property.m @@ -123,3 +123,46 @@ void test6(Test6 *a) { a.prop = test6_func; } +// rdar://problem/10507455 +@interface Test7 +@property unsigned char x; +@end +void test7(Test7 *t) { + t.x &= 2; + t.x |= 5; + t.x ^= 8; +} +// CHECK: define void @test7([[TEST7:%.*]]* +// CHECK: [[T:%.*]] = alloca [[TEST7]]*, +// CHECK-NEXT: store +// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]** [[T]], align +// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES +// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8* +// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast +// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32 +// CHECK-NEXT: [[T4:%.*]] = and i32 [[T3]], 2 +// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8 +// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES +// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8* +// CHECK-NEXT: call void bitcast +// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]** [[T]], align +// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES +// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8* +// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast +// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32 +// CHECK-NEXT: [[T4:%.*]] = or i32 [[T3]], 5 +// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8 +// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES +// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8* +// CHECK-NEXT: call void bitcast +// CHECK-NEXT: [[T0:%.*]] = load [[TEST7]]** [[T]], align +// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES +// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST7]]* [[T0]] to i8* +// CHECK-NEXT: [[T2:%.*]] = call zeroext i8 bitcast +// CHECK-NEXT: [[T3:%.*]] = zext i8 [[T2]] to i32 +// CHECK-NEXT: [[T4:%.*]] = xor i32 [[T3]], 8 +// CHECK-NEXT: [[T5:%.*]] = trunc i32 [[T4]] to i8 +// CHECK-NEXT: load i8** @"\01L_OBJC_SELECTOR_REFERENCES +// CHECK-NEXT: [[T6:%.*]] = bitcast [[TEST7]]* [[T0]] to i8* +// CHECK-NEXT: call void bitcast +// CHECK-NEXT: ret void |