aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2013-01-25 23:57:05 +0000
committerFariborz Jahanian <fjahanian@apple.com>2013-01-25 23:57:05 +0000
commit3ac83d69c61238cd0d38e90fcdd03390530ab2fb (patch)
treee74bebe83a7491346eb921eb84bbb312b15eab96 /lib/CodeGen
parentb2274d64ecb67f6c8bff2e66361844bebbcc3dab (diff)
patch for PR9027 and // rdar://11861085
Title: [PR9027] volatile struct bug: member is not loaded at -O; This is caused by last flag passed to @llvm.memcpy being false, not honoring that aggregate has at least one 'volatile' data member (even though aggregate itself has not been qualified as 'volatile'. As a result, optimization optimizes away the memcpy altogether. Patch review by John MaCall (I still need to fix up a test though). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173535 91177308-0d34-0410-b5e6-96231b3b80d8
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.