aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGExprAgg.cpp5
-rw-r--r--lib/CodeGen/CGValue.h4
-rw-r--r--lib/CodeGen/CodeGenFunction.h16
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.