diff options
author | John McCall <rjmccall@apple.com> | 2012-03-28 23:30:44 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2012-03-28 23:30:44 +0000 |
commit | 57cd1b89cd91433ce1991a5bff36fe776a263796 (patch) | |
tree | 9d65d25e15649b8487c5a4e9fda2910c1a7dce74 /lib/CodeGen/CGValue.h | |
parent | b684a42154a555206a33ac47a52ad2a306cfa2b4 (diff) |
When we can't prove that the target of an aggregate copy is
a complete object, the memcpy needs to use the data size of
the structure instead of its sizeof() value. Fixes PR12204.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153613 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGValue.h')
-rw-r--r-- | lib/CodeGen/CGValue.h | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h index ac704e7dca..731b6abcff 100644 --- a/lib/CodeGen/CGValue.h +++ b/lib/CodeGen/CGValue.h @@ -318,22 +318,22 @@ class AggValueSlot { // Qualifiers Qualifiers Quals; - unsigned short Alignment; + unsigned Alignment : 16; /// DestructedFlag - This is set to true if some external code is /// responsible for setting up a destructor for the slot. Otherwise /// the code which constructs it should push the appropriate cleanup. - bool DestructedFlag : 1; + unsigned DestructedFlag : 1; /// ObjCGCFlag - This is set to true if writing to the memory in the /// slot might require calling an appropriate Objective-C GC /// barrier. The exact interaction here is unnecessarily mysterious. - bool ObjCGCFlag : 1; + unsigned ObjCGCFlag : 1; /// ZeroedFlag - This is set to true if the memory in the slot is /// known to be zero before the assignment into it. This means that /// zero fields don't need to be set. - bool ZeroedFlag : 1; + unsigned ZeroedFlag : 1; /// AliasedFlag - This is set to true if the slot might be aliased /// and it's not undefined behavior to access it through such an @@ -347,19 +347,32 @@ class AggValueSlot { /// over. Since it's invalid in general to memcpy a non-POD C++ /// object, it's important that this flag never be set when /// evaluating an expression which constructs such an object. - bool AliasedFlag : 1; + unsigned AliasedFlag : 1; + + /// CompleteObjectFlag - This is set to true if the slot is known to + /// be a complete object. When emitting an aggregate copy of a + /// non-POD C++ struct to a location which may not be a complete + /// object, only the data size of the type can be copied in order to + /// prevent unrelated fields from being overwritten. + unsigned CompleteObjectFlag : 1; public: enum IsAliased_t { IsNotAliased, IsAliased }; enum IsDestructed_t { IsNotDestructed, IsDestructed }; enum IsZeroed_t { IsNotZeroed, IsZeroed }; + enum IsCompleteObject_t { + IsNotCompleteObject, + MayNotBeCompleteObject = IsNotCompleteObject, + IsCompleteObject + }; enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers }; /// ignored - Returns an aggregate value slot indicating that the /// aggregate value is being ignored. static AggValueSlot ignored() { return forAddr(0, CharUnits(), Qualifiers(), IsNotDestructed, - DoesNotNeedGCBarriers, IsNotAliased); + DoesNotNeedGCBarriers, IsNotAliased, + IsCompleteObject); } /// forAddr - Make a slot for an aggregate value. @@ -377,6 +390,7 @@ public: IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, + IsCompleteObject_t isCompleteObject, IsZeroed_t isZeroed = IsNotZeroed) { AggValueSlot AV; AV.Addr = addr; @@ -386,15 +400,18 @@ public: AV.ObjCGCFlag = needsGC; AV.ZeroedFlag = isZeroed; AV.AliasedFlag = isAliased; + AV.CompleteObjectFlag = isCompleteObject; return AV; } static AggValueSlot forLValue(LValue LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, + IsCompleteObject_t isCompleteObject, IsZeroed_t isZeroed = IsNotZeroed) { return forAddr(LV.getAddress(), LV.getAlignment(), - LV.getQuals(), isDestructed, needsGC, isAliased, isZeroed); + LV.getQuals(), isDestructed, needsGC, isAliased, + isCompleteObject, isZeroed); } IsDestructed_t isExternallyDestructed() const { @@ -434,6 +451,10 @@ public: return IsAliased_t(AliasedFlag); } + IsCompleteObject_t isCompleteObject() const { + return IsCompleteObject_t(CompleteObjectFlag); + } + // FIXME: Alignment? RValue asRValue() const { return RValue::getAggregate(getAddr(), isVolatile()); |