]> granicus.if.org Git - clang/commitdiff
Don't crash on bad atomic operations. PR14176.
authorEli Friedman <eli.friedman@gmail.com>
Tue, 30 Oct 2012 01:15:28 +0000 (01:15 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Tue, 30 Oct 2012 01:15:28 +0000 (01:15 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166992 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
test/CodeGen/atomic-ops.c

index a26a0aa28af3c3732d02c71f8a8d8114a86ff61e..fa0449ec57f9beca2e8b6f79de0a0cbf24497e86 100644 (file)
@@ -3362,6 +3362,13 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
     return ConvertTempToRValue(*this, E->getType(), Dest);
   }
 
+  bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store ||
+                 E->getOp() == AtomicExpr::AO__atomic_store ||
+                 E->getOp() == AtomicExpr::AO__atomic_store_n;
+  bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load ||
+                E->getOp() == AtomicExpr::AO__atomic_load ||
+                E->getOp() == AtomicExpr::AO__atomic_load_n;
+
   llvm::Type *IPtrTy =
       llvm::IntegerType::get(getLLVMContext(), Size * 8)->getPointerTo();
   llvm::Value *OrigDest = Dest;
@@ -3379,14 +3386,20 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
       break;
     case 1:  // memory_order_consume
     case 2:  // memory_order_acquire
+      if (IsStore)
+        break; // Avoid crashing on code with undefined behavior
       EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
                    llvm::Acquire);
       break;
     case 3:  // memory_order_release
+      if (IsLoad)
+        break; // Avoid crashing on code with undefined behavior
       EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
                    llvm::Release);
       break;
     case 4:  // memory_order_acq_rel
+      if (IsLoad || IsStore)
+        break; // Avoid crashing on code with undefined behavior
       EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
                    llvm::AcquireRelease);
       break;
@@ -3406,13 +3419,6 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
 
   // Long case, when Order isn't obviously constant.
 
-  bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store ||
-                 E->getOp() == AtomicExpr::AO__atomic_store ||
-                 E->getOp() == AtomicExpr::AO__atomic_store_n;
-  bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load ||
-                E->getOp() == AtomicExpr::AO__atomic_load ||
-                E->getOp() == AtomicExpr::AO__atomic_load_n;
-
   // Create all the relevant BB's
   llvm::BasicBlock *MonotonicBB = 0, *AcquireBB = 0, *ReleaseBB = 0,
                    *AcqRelBB = 0, *SeqCstBB = 0;
index 1a9ed36ee23e9755fce0285b27d54010aa809185..d79f4052234424f5d1eebe9ad6f415640cd2421e 100644 (file)
@@ -311,4 +311,13 @@ void atomic_init_foo()
   // CHECK: }
 }
 
+// CHECK: @invalid_atomic
+void invalid_atomic(_Atomic(int) *i) {
+  __c11_atomic_store(i, 1, memory_order_consume);
+  __c11_atomic_store(i, 1, memory_order_acquire);
+  __c11_atomic_store(i, 1, memory_order_acq_rel);
+  __c11_atomic_load(i, memory_order_release);
+  __c11_atomic_load(i, memory_order_acq_rel);
+}
+
 #endif