diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-04-05 20:52:58 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-04-05 20:52:58 +0000 |
commit | e78fac5126cfab4c9bf35d3a478239b38825b17b (patch) | |
tree | 38f6360237fd9031ed0bbdae18629979e7774f5a /clang/lib/CodeGen/CGValue.h | |
parent | c233ae8004dfa6aa2c420fe16d15bc3f28ed4ac1 (diff) | |
download | bcm5719-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.h | 29 |
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 |