summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2015-07-14 07:55:48 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2015-07-14 07:55:48 +0000
commit94436b9e9d3b3fea8166f8917af0792d38e1ee16 (patch)
tree7703f9dea8019a7f9f0ac7263d25ef79b868fcac /lib
parente2695b039ea365a935f3983768b620af17ee57c0 (diff)
downloadclang-94436b9e9d3b3fea8166f8917af0792d38e1ee16.tar.gz
Fix for clang memcpyizer bugs 23911 and 23924 (patch by Denis Zobnin)
The fix is to remove duplicate copy-initialization of the only memcpy-able struct member and to correct the address of aggregately initialized members in destructors' calls during stack unwinding (in order to obtain address of struct member by using GEP instead of 'bitcast'). Differential Revision: http://reviews.llvm.org/D10990 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@242127 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/CGClass.cpp36
1 files changed, 23 insertions, 13 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index b977824888..c49f182c21 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -554,6 +554,20 @@ static bool isMemcpyEquivalentSpecialMember(const CXXMethodDecl *D) {
return false;
}
+static void EmitLValueForAnyFieldInitialization(CodeGenFunction &CGF,
+ CXXCtorInitializer *MemberInit,
+ LValue &LHS) {
+ FieldDecl *Field = MemberInit->getAnyMember();
+ if (MemberInit->isIndirectMemberInitializer()) {
+ // If we are initializing an anonymous union field, drill down to the field.
+ IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember();
+ for (const auto *I : IndirectField->chain())
+ LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(I));
+ } else {
+ LHS = CGF.EmitLValueForFieldInitialization(LHS, Field);
+ }
+}
+
static void EmitMemberInitializer(CodeGenFunction &CGF,
const CXXRecordDecl *ClassDecl,
CXXCtorInitializer *MemberInit,
@@ -572,16 +586,7 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy);
- if (MemberInit->isIndirectMemberInitializer()) {
- // If we are initializing an anonymous union field, drill down to
- // the field.
- IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember();
- for (const auto *I : IndirectField->chain())
- LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(I));
- FieldType = MemberInit->getIndirectMember()->getAnonField()->getType();
- } else {
- LHS = CGF.EmitLValueForFieldInitialization(LHS, Field);
- }
+ EmitLValueForAnyFieldInitialization(CGF, MemberInit, LHS);
// Special case: if we are in a copy or move constructor, and we are copying
// an array of PODs or classes with trivial copy constructors, ignore the
@@ -1072,6 +1077,7 @@ namespace {
CopyingValueRepresentation CVR(CGF);
EmitMemberInitializer(CGF, ConstructorDecl->getParent(),
AggregatedInits[0], ConstructorDecl, Args);
+ AggregatedInits.clear();
}
reset();
return;
@@ -1088,10 +1094,14 @@ namespace {
LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy);
for (unsigned i = 0; i < AggregatedInits.size(); ++i) {
- QualType FieldType = AggregatedInits[i]->getMember()->getType();
+ CXXCtorInitializer *MemberInit = AggregatedInits[i];
+ QualType FieldType = MemberInit->getAnyMember()->getType();
QualType::DestructionKind dtorKind = FieldType.isDestructedType();
- if (CGF.needsEHCleanup(dtorKind))
- CGF.pushEHDestroy(dtorKind, LHS.getAddress(), FieldType);
+ if (!CGF.needsEHCleanup(dtorKind))
+ continue;
+ LValue FieldLHS = LHS;
+ EmitLValueForAnyFieldInitialization(CGF, MemberInit, FieldLHS);
+ CGF.pushEHDestroy(dtorKind, FieldLHS.getAddress(), FieldType);
}
}