diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-11-14 07:36:28 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-11-14 07:36:28 +0000 |
commit | 93af2b839224badbb0555f8920c44fc9a1c793fe (patch) | |
tree | 7c6c7450106d0b2c5d8388dcbc26de316504481c /lib/AST/DeclCXX.cpp | |
parent | 4a030228d1bfa0cab89114a18d6b50b44eb3a1a8 (diff) |
PR14279: Work around this major miscompilation by treating move operations as
non-trivial if they would not call a move operation, even if they would in fact
call a trivial copy operation. A proper fix is to follow, but this small
directed fix is intended for porting to the 3.2 release branch.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167920 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/DeclCXX.cpp')
-rw-r--r-- | lib/AST/DeclCXX.cpp | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 9db33357a6..82e630acef 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -240,10 +240,13 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, // -- the constructor selected to copy/move each direct base class // subobject is trivial, and // FIXME: C++0x: We need to only consider the selected constructor - // instead of all of them. + // instead of all of them. For now, we treat a move constructor as being + // non-trivial if it calls anything other than a trivial move constructor. if (!BaseClassDecl->hasTrivialCopyConstructor()) data().HasTrivialCopyConstructor = false; - if (!BaseClassDecl->hasTrivialMoveConstructor()) + if (!BaseClassDecl->hasTrivialMoveConstructor() || + !(BaseClassDecl->hasDeclaredMoveConstructor() || + BaseClassDecl->needsImplicitMoveConstructor())) data().HasTrivialMoveConstructor = false; // C++0x [class.copy]p27: @@ -255,7 +258,9 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, // of all of them. if (!BaseClassDecl->hasTrivialCopyAssignment()) data().HasTrivialCopyAssignment = false; - if (!BaseClassDecl->hasTrivialMoveAssignment()) + if (!BaseClassDecl->hasTrivialMoveAssignment() || + !(BaseClassDecl->hasDeclaredMoveAssignment() || + BaseClassDecl->needsImplicitMoveAssignment())) data().HasTrivialMoveAssignment = false; // C++11 [class.ctor]p6: @@ -830,7 +835,9 @@ NotASpecialMember:; // FIXME: C++0x: We don't correctly model 'selected' constructors. if (!FieldRec->hasTrivialCopyConstructor()) data().HasTrivialCopyConstructor = false; - if (!FieldRec->hasTrivialMoveConstructor()) + if (!FieldRec->hasTrivialMoveConstructor() || + !(FieldRec->hasDeclaredMoveConstructor() || + FieldRec->needsImplicitMoveConstructor())) data().HasTrivialMoveConstructor = false; // C++0x [class.copy]p27: @@ -842,7 +849,9 @@ NotASpecialMember:; // FIXME: C++0x: We don't correctly model 'selected' operators. if (!FieldRec->hasTrivialCopyAssignment()) data().HasTrivialCopyAssignment = false; - if (!FieldRec->hasTrivialMoveAssignment()) + if (!FieldRec->hasTrivialMoveAssignment() || + !(FieldRec->hasDeclaredMoveAssignment() || + FieldRec->needsImplicitMoveAssignment())) data().HasTrivialMoveAssignment = false; if (!FieldRec->hasTrivialDestructor()) |