diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CGValue.h | 4 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 16 |
3 files changed, 22 insertions, 3 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index a35ef0c931..8c64e8a6e7 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -792,6 +792,11 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) { AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed, needsGC(E->getLHS()->getType()), AggValueSlot::IsAliased); + // A non-volatile aggregate destination might have volatile member. + if (!LHSSlot.isVolatile() && + CGF.hasVolatileMember(E->getLHS()->getType())) + LHSSlot.setVolatile(true); + CGF.EmitAggExpr(E->getRHS(), LHSSlot); // Copy into the destination if the assignment isn't ignored. diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index 7a2b8e30b1..01dee1f628 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -412,6 +412,10 @@ public: return Quals.hasVolatile(); } + void setVolatile(bool flag) { + Quals.setVolatile(flag); + } + Qualifiers::ObjCLifetime getObjCLifetime() const { return Quals.getObjCLifetime(); } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index afe99381ae..bfcc77a3fd 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1665,14 +1665,24 @@ public: void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit); + /// hasVolatileMember - returns true if aggregate type has a volatile + /// member. + bool hasVolatileMember(QualType T) { + if (const RecordType *RT = T->getAs<RecordType>()) { + const RecordDecl *RD = cast<RecordDecl>(RT->getDecl()); + return RD->hasVolatileMember(); + } + return false; + } /// EmitAggregateCopy - Emit an aggrate assignment. /// /// The difference to EmitAggregateCopy is that tail padding is not copied. /// This is required for correctness when assigning non-POD structures in C++. void EmitAggregateAssign(llvm::Value *DestPtr, llvm::Value *SrcPtr, - QualType EltTy, bool isVolatile=false, - CharUnits Alignment = CharUnits::Zero()) { - EmitAggregateCopy(DestPtr, SrcPtr, EltTy, isVolatile, Alignment, true); + QualType EltTy) { + bool IsVolatile = hasVolatileMember(EltTy); + EmitAggregateCopy(DestPtr, SrcPtr, EltTy, IsVolatile, CharUnits::Zero(), + true); } /// EmitAggregateCopy - Emit an aggrate copy. |