summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-12-06 02:56:18 +0000
committerJohn McCall <rjmccall@apple.com>2011-12-06 02:56:18 +0000
commite5e1b88bbcf4288d671da42c2c9bfc113d843e1f (patch)
treebfaa89d90281a197b20710dcde2f5daf92569fab /clang
parentc1610bede171d7cd813e6ab0432c97be2df8c218 (diff)
downloadbcm5719-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.h4
-rw-r--r--clang/test/CodeGenObjC/property.m43
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
OpenPOWER on IntegriCloud