]> granicus.if.org Git - clang/commitdiff
Fix an extremely stupid bug causing terrible miscompilations
authorJohn McCall <rjmccall@apple.com>
Tue, 6 Dec 2011 02:56:18 +0000 (02:56 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 6 Dec 2011 02:56:18 +0000 (02:56 +0000)
of &= on pseudo-objects.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145904 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
test/CodeGenObjC/property.m

index 33447f771673523c8bb75a5f983d6ab000f1ccba..ac4ffe0b438431f837137988909d2f1daa7bf83e 100644 (file)
@@ -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);
   }
index 30f68e5b27f1bdad15a4883d55fa7cbb14bc6471..16881d608bf2e786ecc88a4bd339aaf890309288 100644 (file)
@@ -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