summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGValue.h
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-04-05 20:52:58 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-04-05 20:52:58 +0000
commite78fac5126cfab4c9bf35d3a478239b38825b17b (patch)
tree38f6360237fd9031ed0bbdae18629979e7774f5a /clang/lib/CodeGen/CGValue.h
parentc233ae8004dfa6aa2c420fe16d15bc3f28ed4ac1 (diff)
downloadbcm5719-llvm-e78fac5126cfab4c9bf35d3a478239b38825b17b.tar.gz
bcm5719-llvm-e78fac5126cfab4c9bf35d3a478239b38825b17b.zip
PR36992: do not store beyond the dsize of a class object unless we know
the tail padding is not reused. We track on the AggValueSlot (and through a couple of other initialization actions) whether we're dealing with an object that might share its tail padding with some other object, so that we can avoid emitting stores into the tail padding if that's the case. We still widen stores into tail padding when we can do so. Differential Revision: https://reviews.llvm.org/D45306 llvm-svn: 329342
Diffstat (limited to 'clang/lib/CodeGen/CGValue.h')
-rw-r--r--clang/lib/CodeGen/CGValue.h29
1 files changed, 26 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGValue.h b/clang/lib/CodeGen/CGValue.h
index a32be194968..ea997c18d66 100644
--- a/clang/lib/CodeGen/CGValue.h
+++ b/clang/lib/CodeGen/CGValue.h
@@ -472,17 +472,25 @@ class AggValueSlot {
/// evaluating an expression which constructs such an object.
bool AliasedFlag : 1;
+ /// This is set to true if the tail padding of this slot might overlap
+ /// another object that may have already been initialized (and whose
+ /// value must be preserved by this initialization). If so, we may only
+ /// store up to the dsize of the type. Otherwise we can widen stores to
+ /// the size of the type.
+ bool OverlapFlag : 1;
+
public:
enum IsAliased_t { IsNotAliased, IsAliased };
enum IsDestructed_t { IsNotDestructed, IsDestructed };
enum IsZeroed_t { IsNotZeroed, IsZeroed };
+ enum Overlap_t { DoesNotOverlap, MayOverlap };
enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers };
/// ignored - Returns an aggregate value slot indicating that the
/// aggregate value is being ignored.
static AggValueSlot ignored() {
return forAddr(Address::invalid(), Qualifiers(), IsNotDestructed,
- DoesNotNeedGCBarriers, IsNotAliased);
+ DoesNotNeedGCBarriers, IsNotAliased, DoesNotOverlap);
}
/// forAddr - Make a slot for an aggregate value.
@@ -500,6 +508,7 @@ public:
IsDestructed_t isDestructed,
NeedsGCBarriers_t needsGC,
IsAliased_t isAliased,
+ Overlap_t mayOverlap,
IsZeroed_t isZeroed = IsNotZeroed) {
AggValueSlot AV;
if (addr.isValid()) {
@@ -514,6 +523,7 @@ public:
AV.ObjCGCFlag = needsGC;
AV.ZeroedFlag = isZeroed;
AV.AliasedFlag = isAliased;
+ AV.OverlapFlag = mayOverlap;
return AV;
}
@@ -521,9 +531,10 @@ public:
IsDestructed_t isDestructed,
NeedsGCBarriers_t needsGC,
IsAliased_t isAliased,
+ Overlap_t mayOverlap,
IsZeroed_t isZeroed = IsNotZeroed) {
- return forAddr(LV.getAddress(),
- LV.getQuals(), isDestructed, needsGC, isAliased, isZeroed);
+ return forAddr(LV.getAddress(), LV.getQuals(), isDestructed, needsGC,
+ isAliased, mayOverlap, isZeroed);
}
IsDestructed_t isExternallyDestructed() const {
@@ -571,6 +582,10 @@ public:
return IsAliased_t(AliasedFlag);
}
+ Overlap_t mayOverlap() const {
+ return Overlap_t(OverlapFlag);
+ }
+
RValue asRValue() const {
if (isIgnored()) {
return RValue::getIgnored();
@@ -583,6 +598,14 @@ public:
IsZeroed_t isZeroed() const {
return IsZeroed_t(ZeroedFlag);
}
+
+ /// Get the preferred size to use when storing a value to this slot. This
+ /// is the type size unless that might overlap another object, in which
+ /// case it's the dsize.
+ CharUnits getPreferredSize(ASTContext &Ctx, QualType Type) const {
+ return mayOverlap() ? Ctx.getTypeInfoDataSizeInChars(Type).first
+ : Ctx.getTypeSizeInChars(Type);
+ }
};
} // end namespace CodeGen
OpenPOWER on IntegriCloud