diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-10-30 01:15:28 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-10-30 01:15:28 +0000 |
commit | ee1ea80a9091050c6d0a21be9d06a5f97d3ea715 (patch) | |
tree | 6d65f1bac238b0abb2b2059131056bc0e377d6a9 | |
parent | 848bc3a5db57fb267e2b2541cb55e71dba4bf228 (diff) |
Don't crash on bad atomic operations. PR14176.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166992 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 20 | ||||
-rw-r--r-- | test/CodeGen/atomic-ops.c | 9 |
2 files changed, 22 insertions, 7 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index a26a0aa28a..fa0449ec57 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -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; diff --git a/test/CodeGen/atomic-ops.c b/test/CodeGen/atomic-ops.c index 1a9ed36ee2..d79f405223 100644 --- a/test/CodeGen/atomic-ops.c +++ b/test/CodeGen/atomic-ops.c @@ -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 |