Also if you want the disassembly for the whole test executable (with just that test in it): https://goo.gl/pjULbN
It's 177MB though. On 14 August 2017 at 14:04, Diana Picus <diana.pi...@linaro.org> wrote: > See attached. > > On 14 August 2017 at 13:30, Vassil Vassilev <v.g.vassi...@gmail.com> wrote: >> On 14/08/17 11:27, Diana Picus wrote: >>> >>> Hi, >>> >>> Strangely enough, it turns out that if I run >>> Asan-armhf-with-calls-Noinst-Test on the command line it fails, >>> although it doesn't fail when run with lit. I've attached the stack >>> trace from gdb. It looks like some trouble passing down va_arg >>> parameters, but I haven't looked into too much details. The segfault >>> happens when we try to do a ldrb r3, [r0, r1], with r1 set to 0 by >>> the current function and r0 passed down from the caller. I'm not sure >>> if this is the exact same problem as the other tests, but feel free to >>> have a look at that code. >>> >>> Meanwhile, I've removed some clutter from Asan-armhf-with-calls-Test >>> (which is the original failure that we were seeing) and left only one >>> failing test that seemed small enough. I'll try to look at the >>> disassembly before/after the patch and maybe even run valgrind on it >>> (running it on the original binary naturally takes forever). >>> >>> Let me know if there's anything else I could try. I can also send you >>> disassembly or even LLVM IR for the Asan-armhf-with-calls-Noinst-Test >>> if you think it helps. >> >> disassembly and LLVM will greatly help as well. >> >>> >>> Cheers, >>> Diana >>> >>> On 11 August 2017 at 15:34, Diana Picus <diana.pi...@linaro.org> wrote: >>>> >>>> Well, these are ASAN tests, I'm not sure how that would interact with >>>> Valgrind. >>>> Anyway, I'll try to reproduce the environment, I'm guessing it would >>>> be best to catch this in gdb so I can actually see what's going on. >>>> >>>> On 11 August 2017 at 15:21, Vassil Vassilev <v.g.vassi...@gmail.com> >>>> wrote: >>>>> >>>>> That's really strange. It looks like some random behavior. Did you run >>>>> some memory checker like valgrind? >>>>> >>>>> Do the environment provided by the test runner and yours match? >>>>> >>>>> Sent from my phone. Please excuse my brevity. >>>>> >>>>>> On 11 Aug 2017, at 15:58, Diana Picus <diana.pi...@linaro.org> wrote: >>>>>> >>>>>> Hi again, >>>>>> >>>>>> I finally got the debug build, but unfortunately the stack traces that >>>>>> the tests print look the same. My suspicion is that this is because >>>>>> the addresses printed by the tests are funny (i.e. odd numbers instead >>>>>> of divisible by 4). I tried to follow those addresses in an objdump of >>>>>> the executable, but I didn't have much success since most of them >>>>>> weren't really pointing to call instructions. >>>>>> >>>>>> When I try to run the tests manually in the shell or in gdb, they pass. >>>>>> >>>>>> I'm not sure what else to try. Thoughts? >>>>>> >>>>>> Thanks, >>>>>> Diana >>>>>> >>>>>>> On 11 August 2017 at 11:14, Diana Picus <diana.pi...@linaro.org> >>>>>>> wrote: >>>>>>> Hi guys, >>>>>>> >>>>>>> I'm SO sorry about the delays. I've been having all sorts of trouble >>>>>>> getting that debug build on the board (from ld running out of memory >>>>>>> to the board just crashing on me, in which case I need to ask someone >>>>>>> else to reboot it because I can't power cycle it remotely). I can >>>>>>> assure you this is one of my top priorities, I'll get those stack >>>>>>> traces as soon as I can. >>>>>>> >>>>>>> Thanks for your patience and sorry again, >>>>>>> Diana >>>>>>> >>>>>>>> On 10 August 2017 at 22:55, Richard Smith <rich...@metafoo.co.uk> >>>>>>>> wrote: >>>>>>>> Any news on this? We want this change in Clang 5, so the sooner we >>>>>>>> can >>>>>>>> understand and fix this regression the better... >>>>>>>> >>>>>>>> On 10 August 2017 at 01:28, Diana Picus via cfe-commits >>>>>>>> <cfe-commits@lists.llvm.org> wrote: >>>>>>>>> >>>>>>>>> Hi Vassil, >>>>>>>>> >>>>>>>>> My build is in progress, but since it's a full build it's probably >>>>>>>>> going to take another couple of hours to complete. I'll let you know >>>>>>>>> when it's done. >>>>>>>>> >>>>>>>>> Thanks, >>>>>>>>> Diana >>>>>>>>> >>>>>>>>> On 10 August 2017 at 10:09, Vassil Vassilev <v.g.vassi...@gmail.com> >>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>> It looks like I can not reproduce it on osx (non-arm)... :( >>>>>>>>>>> >>>>>>>>>>> On 09/08/17 22:54, Diana Picus wrote: >>>>>>>>>>> >>>>>>>>>>> Reverting this also fixed the selfhost bots: >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> http://lab.llvm.org:8011/builders/clang-cmake-thumbv7-a15-full-sh/builds/2142 >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> http://lab.llvm.org:8011/builders/clang-cmake-armv7-a15-selfhost/builds/2309 >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> http://lab.llvm.org:8011/builders/clang-cmake-armv7-a15-selfhost-neon/builds/1819 >>>>>>>>>>> >>>>>>>>>>> I'm afraid the logs for those look even less helpful. >>>>>>>>>>> >>>>>>>>>>>> On 9 August 2017 at 16:17, Diana Picus <diana.pi...@linaro.org> >>>>>>>>>>>> wrote: >>>>>>>>>>>> >>>>>>>>>>>> Hi, >>>>>>>>>>>> >>>>>>>>>>>> See attached. FWIW, when I ran this on a very similar machine, I >>>>>>>>>>>> got >>>>>>>>>>>> 194 failures, all of which went away after reverting. So there >>>>>>>>>>>> might >>>>>>>>>>>> be something fishy going on. >>>>>>>>>>>> >>>>>>>>>>>> Regards, >>>>>>>>>>>> Diana >>>>>>>>>>>> >>>>>>>>>>>> On 9 August 2017 at 15:02, Vassil Vassilev >>>>>>>>>>>> <v.g.vassi...@gmail.com> >>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>> Hi Diana, >>>>>>>>>>>>> >>>>>>>>>>>>> It seems the service is down. Could you send us the details >>>>>>>>>>>>> of the >>>>>>>>>>>>> failures (incl stack traces if any) >>>>>>>>>>>>> >>>>>>>>>>>>> Many thanks, >>>>>>>>>>>>> Vassil >>>>>>>>>>>>> >>>>>>>>>>>>>> On 09/08/17 15:27, Diana Picus via cfe-commits wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>> Hi Richard, >>>>>>>>>>>>>> >>>>>>>>>>>>>> I'm sorry but I've reverted this in r310464 because it was >>>>>>>>>>>>>> breaking >>>>>>>>>>>>>> some ASAN tests on this bot: >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> http://lab.llvm.org:8011/builders/clang-cmake-armv7-a15-full/builds/9452 >>>>>>>>>>>>>> >>>>>>>>>>>>>> Please let me know if I can help debug this. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Cheers, >>>>>>>>>>>>>> Diana >>>>>>>>>>>>>> >>>>>>>>>>>>>> On 8 August 2017 at 21:14, Richard Smith via cfe-commits >>>>>>>>>>>>>> <cfe-commits@lists.llvm.org> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I forgot to say: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Based on a patch by Vassil Vassilev, which was based on a >>>>>>>>>>>>>>> patch by >>>>>>>>>>>>>>> Bernd >>>>>>>>>>>>>>> Schmidt, which was based on a patch by Reid Kleckner. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On 8 August 2017 at 12:12, Richard Smith via cfe-commits >>>>>>>>>>>>>>> <cfe-commits@lists.llvm.org> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Author: rsmith >>>>>>>>>>>>>>>> Date: Tue Aug 8 12:12:28 2017 >>>>>>>>>>>>>>>> New Revision: 310401 >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=310401&view=rev >>>>>>>>>>>>>>>> Log: >>>>>>>>>>>>>>>> PR19668, PR23034: Fix handling of move constructors and >>>>>>>>>>>>>>>> deleted >>>>>>>>>>>>>>>> copy >>>>>>>>>>>>>>>> constructors when deciding whether classes should be passed >>>>>>>>>>>>>>>> indirectly. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> This fixes ABI differences between Clang and GCC: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> * Previously, Clang ignored the move constructor when >>>>>>>>>>>>>>>> making >>>>>>>>>>>>>>>> this >>>>>>>>>>>>>>>> determination. It now takes the move constructor into >>>>>>>>>>>>>>>> account, >>>>>>>>>>>>>>>> per >>>>>>>>>>>>>>>> https://github.com/itanium-cxx-abi/cxx-abi/pull/17 (this >>>>>>>>>>>>>>>> change >>>>>>>>>>>>>>>> may >>>>>>>>>>>>>>>> seem recent, but the ABI change was agreed on the >>>>>>>>>>>>>>>> Itanium C++ >>>>>>>>>>>>>>>> ABI >>>>>>>>>>>>>>>> list a long time ago). >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> * Previously, Clang's behavior when the copy constructor >>>>>>>>>>>>>>>> was >>>>>>>>>>>>>>>> deleted >>>>>>>>>>>>>>>> was unstable -- depending on whether the lazy >>>>>>>>>>>>>>>> declaration of >>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>> copy constructor had been triggered, you might get >>>>>>>>>>>>>>>> different >>>>>>>>>>>>>>>> behavior. >>>>>>>>>>>>>>>> We now eagerly declare the copy constructor whenever its >>>>>>>>>>>>>>>> deletedness >>>>>>>>>>>>>>>> is unclear, and ignore deleted copy/move constructors >>>>>>>>>>>>>>>> when >>>>>>>>>>>>>>>> looking >>>>>>>>>>>>>>>> for >>>>>>>>>>>>>>>> a trivial such constructor. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> This also fixes an ABI difference between Clang and MSVC: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> * If the copy constructor would be implicitly deleted (but >>>>>>>>>>>>>>>> has >>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>> been >>>>>>>>>>>>>>>> lazily declared yet), for instance because the class has >>>>>>>>>>>>>>>> an >>>>>>>>>>>>>>>> rvalue >>>>>>>>>>>>>>>> reference member, we would pass it directly. We now pass >>>>>>>>>>>>>>>> such >>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>> class >>>>>>>>>>>>>>>> indirectly, matching MSVC. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Modified: >>>>>>>>>>>>>>>> cfe/trunk/include/clang/AST/DeclCXX.h >>>>>>>>>>>>>>>> cfe/trunk/lib/AST/ASTImporter.cpp >>>>>>>>>>>>>>>> cfe/trunk/lib/AST/DeclCXX.cpp >>>>>>>>>>>>>>>> cfe/trunk/lib/CodeGen/CGCXXABI.cpp >>>>>>>>>>>>>>>> cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp >>>>>>>>>>>>>>>> cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp >>>>>>>>>>>>>>>> cfe/trunk/lib/Sema/SemaDeclCXX.cpp >>>>>>>>>>>>>>>> cfe/trunk/lib/Serialization/ASTReaderDecl.cpp >>>>>>>>>>>>>>>> cfe/trunk/lib/Serialization/ASTWriter.cpp >>>>>>>>>>>>>>>> cfe/trunk/test/CodeGenCXX/uncopyable-args.cpp >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Modified: cfe/trunk/include/clang/AST/DeclCXX.h >>>>>>>>>>>>>>>> URL: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=310401&r1=310400&r2=310401&view=diff >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>>>>> --- cfe/trunk/include/clang/AST/DeclCXX.h (original) >>>>>>>>>>>>>>>> +++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Aug 8 12:12:28 >>>>>>>>>>>>>>>> 2017 >>>>>>>>>>>>>>>> @@ -375,6 +375,7 @@ class CXXRecordDecl : public RecordDecl >>>>>>>>>>>>>>>> /// \brief These flags are \c true if a defaulted >>>>>>>>>>>>>>>> corresponding >>>>>>>>>>>>>>>> special >>>>>>>>>>>>>>>> /// member can't be fully analyzed without performing >>>>>>>>>>>>>>>> overload >>>>>>>>>>>>>>>> resolution. >>>>>>>>>>>>>>>> /// @{ >>>>>>>>>>>>>>>> + unsigned NeedOverloadResolutionForCopyConstructor : 1; >>>>>>>>>>>>>>>> unsigned NeedOverloadResolutionForMoveConstructor : 1; >>>>>>>>>>>>>>>> unsigned NeedOverloadResolutionForMoveAssignment : 1; >>>>>>>>>>>>>>>> unsigned NeedOverloadResolutionForDestructor : 1; >>>>>>>>>>>>>>>> @@ -383,6 +384,7 @@ class CXXRecordDecl : public RecordDecl >>>>>>>>>>>>>>>> /// \brief These flags are \c true if an implicit >>>>>>>>>>>>>>>> defaulted >>>>>>>>>>>>>>>> corresponding >>>>>>>>>>>>>>>> /// special member would be defined as deleted. >>>>>>>>>>>>>>>> /// @{ >>>>>>>>>>>>>>>> + unsigned DefaultedCopyConstructorIsDeleted : 1; >>>>>>>>>>>>>>>> unsigned DefaultedMoveConstructorIsDeleted : 1; >>>>>>>>>>>>>>>> unsigned DefaultedMoveAssignmentIsDeleted : 1; >>>>>>>>>>>>>>>> unsigned DefaultedDestructorIsDeleted : 1; >>>>>>>>>>>>>>>> @@ -415,6 +417,12 @@ class CXXRecordDecl : public RecordDecl >>>>>>>>>>>>>>>> /// constructor. >>>>>>>>>>>>>>>> unsigned HasDefaultedDefaultConstructor : 1; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> + /// \brief True if this class can be passed in a >>>>>>>>>>>>>>>> non-address-preserving >>>>>>>>>>>>>>>> + /// fashion (such as in registers) according to the C++ >>>>>>>>>>>>>>>> language >>>>>>>>>>>>>>>> rules. >>>>>>>>>>>>>>>> + /// This does not imply anything about how the ABI in >>>>>>>>>>>>>>>> use >>>>>>>>>>>>>>>> will >>>>>>>>>>>>>>>> actually >>>>>>>>>>>>>>>> + /// pass an object of this class. >>>>>>>>>>>>>>>> + unsigned CanPassInRegisters : 1; >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> /// \brief True if a defaulted default constructor for >>>>>>>>>>>>>>>> this >>>>>>>>>>>>>>>> class >>>>>>>>>>>>>>>> would >>>>>>>>>>>>>>>> /// be constexpr. >>>>>>>>>>>>>>>> unsigned DefaultedDefaultConstructorIsConstexpr : 1; >>>>>>>>>>>>>>>> @@ -811,18 +819,50 @@ public: >>>>>>>>>>>>>>>> return data().FirstFriend.isValid(); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> + /// \brief \c true if a defaulted copy constructor for >>>>>>>>>>>>>>>> this >>>>>>>>>>>>>>>> class >>>>>>>>>>>>>>>> would >>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>> + /// deleted. >>>>>>>>>>>>>>>> + bool defaultedCopyConstructorIsDeleted() const { >>>>>>>>>>>>>>>> + assert((!needsOverloadResolutionForCopyConstructor() || >>>>>>>>>>>>>>>> + (data().DeclaredSpecialMembers & >>>>>>>>>>>>>>>> SMF_CopyConstructor)) >>>>>>>>>>>>>>>> && >>>>>>>>>>>>>>>> + "this property has not yet been computed by >>>>>>>>>>>>>>>> Sema"); >>>>>>>>>>>>>>>> + return data().DefaultedCopyConstructorIsDeleted; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + /// \brief \c true if a defaulted move constructor for >>>>>>>>>>>>>>>> this >>>>>>>>>>>>>>>> class >>>>>>>>>>>>>>>> would >>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>> + /// deleted. >>>>>>>>>>>>>>>> + bool defaultedMoveConstructorIsDeleted() const { >>>>>>>>>>>>>>>> + assert((!needsOverloadResolutionForMoveConstructor() || >>>>>>>>>>>>>>>> + (data().DeclaredSpecialMembers & >>>>>>>>>>>>>>>> SMF_MoveConstructor)) >>>>>>>>>>>>>>>> && >>>>>>>>>>>>>>>> + "this property has not yet been computed by >>>>>>>>>>>>>>>> Sema"); >>>>>>>>>>>>>>>> + return data().DefaultedMoveConstructorIsDeleted; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + /// \brief \c true if a defaulted destructor for this >>>>>>>>>>>>>>>> class >>>>>>>>>>>>>>>> would >>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>> deleted. >>>>>>>>>>>>>>>> + bool defaultedDestructorIsDeleted() const { >>>>>>>>>>>>>>>> + return !data().DefaultedDestructorIsDeleted; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + /// \brief \c true if we know for sure that this class has >>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>> single, >>>>>>>>>>>>>>>> + /// accessible, unambiguous copy constructor that is not >>>>>>>>>>>>>>>> deleted. >>>>>>>>>>>>>>>> + bool hasSimpleCopyConstructor() const { >>>>>>>>>>>>>>>> + return !hasUserDeclaredCopyConstructor() && >>>>>>>>>>>>>>>> + !data().DefaultedCopyConstructorIsDeleted; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> /// \brief \c true if we know for sure that this class >>>>>>>>>>>>>>>> has a >>>>>>>>>>>>>>>> single, >>>>>>>>>>>>>>>> /// accessible, unambiguous move constructor that is not >>>>>>>>>>>>>>>> deleted. >>>>>>>>>>>>>>>> bool hasSimpleMoveConstructor() const { >>>>>>>>>>>>>>>> return !hasUserDeclaredMoveConstructor() && >>>>>>>>>>>>>>>> hasMoveConstructor() >>>>>>>>>>>>>>>> && >>>>>>>>>>>>>>>> !data().DefaultedMoveConstructorIsDeleted; >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> /// \brief \c true if we know for sure that this class >>>>>>>>>>>>>>>> has a >>>>>>>>>>>>>>>> single, >>>>>>>>>>>>>>>> /// accessible, unambiguous move assignment operator >>>>>>>>>>>>>>>> that is >>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>> deleted. >>>>>>>>>>>>>>>> bool hasSimpleMoveAssignment() const { >>>>>>>>>>>>>>>> return !hasUserDeclaredMoveAssignment() && >>>>>>>>>>>>>>>> hasMoveAssignment() >>>>>>>>>>>>>>>> && >>>>>>>>>>>>>>>> !data().DefaultedMoveAssignmentIsDeleted; >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> /// \brief \c true if we know for sure that this class >>>>>>>>>>>>>>>> has an >>>>>>>>>>>>>>>> accessible >>>>>>>>>>>>>>>> /// destructor that is not deleted. >>>>>>>>>>>>>>>> bool hasSimpleDestructor() const { >>>>>>>>>>>>>>>> @@ -878,7 +918,16 @@ public: >>>>>>>>>>>>>>>> /// \brief Determine whether we need to eagerly declare >>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>> defaulted >>>>>>>>>>>>>>>> copy >>>>>>>>>>>>>>>> /// constructor for this class. >>>>>>>>>>>>>>>> bool needsOverloadResolutionForCopyConstructor() const { >>>>>>>>>>>>>>>> - return data().HasMutableFields; >>>>>>>>>>>>>>>> + // C++17 [class.copy.ctor]p6: >>>>>>>>>>>>>>>> + // If the class definition declares a move constructor >>>>>>>>>>>>>>>> or >>>>>>>>>>>>>>>> move >>>>>>>>>>>>>>>> assignment >>>>>>>>>>>>>>>> + // operator, the implicitly declared copy constructor >>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>> defined >>>>>>>>>>>>>>>> as >>>>>>>>>>>>>>>> + // deleted. >>>>>>>>>>>>>>>> + // In MSVC mode, sometimes a declared move assignment >>>>>>>>>>>>>>>> does >>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>> delete >>>>>>>>>>>>>>>> an >>>>>>>>>>>>>>>> + // implicit copy constructor, so defer this choice to >>>>>>>>>>>>>>>> Sema. >>>>>>>>>>>>>>>> + if (data().UserDeclaredSpecialMembers & >>>>>>>>>>>>>>>> + (SMF_MoveConstructor | SMF_MoveAssignment)) >>>>>>>>>>>>>>>> + return true; >>>>>>>>>>>>>>>> + return data().NeedOverloadResolutionForCopyConstructor; >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> /// \brief Determine whether an implicit copy >>>>>>>>>>>>>>>> constructor for >>>>>>>>>>>>>>>> this >>>>>>>>>>>>>>>> type >>>>>>>>>>>>>>>> @@ -919,7 +968,16 @@ public: >>>>>>>>>>>>>>>> needsImplicitMoveConstructor(); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - /// \brief Set that we attempted to declare an implicitly >>>>>>>>>>>>>>>> move >>>>>>>>>>>>>>>> + /// \brief Set that we attempted to declare an implicit >>>>>>>>>>>>>>>> copy >>>>>>>>>>>>>>>> + /// constructor, but overload resolution failed so we >>>>>>>>>>>>>>>> deleted >>>>>>>>>>>>>>>> it. >>>>>>>>>>>>>>>> + void setImplicitCopyConstructorIsDeleted() { >>>>>>>>>>>>>>>> + assert((data().DefaultedCopyConstructorIsDeleted || >>>>>>>>>>>>>>>> + needsOverloadResolutionForCopyConstructor()) && >>>>>>>>>>>>>>>> + "Copy constructor should not be deleted"); >>>>>>>>>>>>>>>> + data().DefaultedCopyConstructorIsDeleted = true; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + /// \brief Set that we attempted to declare an implicit >>>>>>>>>>>>>>>> move >>>>>>>>>>>>>>>> /// constructor, but overload resolution failed so we >>>>>>>>>>>>>>>> deleted >>>>>>>>>>>>>>>> it. >>>>>>>>>>>>>>>> void setImplicitMoveConstructorIsDeleted() { >>>>>>>>>>>>>>>> assert((data().DefaultedMoveConstructorIsDeleted || >>>>>>>>>>>>>>>> @@ -1316,6 +1374,18 @@ public: >>>>>>>>>>>>>>>> return data().HasIrrelevantDestructor; >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> + /// \brief Determine whether this class has at least one >>>>>>>>>>>>>>>> trivial, >>>>>>>>>>>>>>>> non-deleted >>>>>>>>>>>>>>>> + /// copy or move constructor. >>>>>>>>>>>>>>>> + bool canPassInRegisters() const { >>>>>>>>>>>>>>>> + return data().CanPassInRegisters; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + /// \brief Set that we can pass this RecordDecl in >>>>>>>>>>>>>>>> registers. >>>>>>>>>>>>>>>> + // FIXME: This should be set as part of >>>>>>>>>>>>>>>> completeDefinition. >>>>>>>>>>>>>>>> + void setCanPassInRegisters(bool CanPass) { >>>>>>>>>>>>>>>> + data().CanPassInRegisters = CanPass; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> /// \brief Determine whether this class has a >>>>>>>>>>>>>>>> non-literal or/ >>>>>>>>>>>>>>>> volatile >>>>>>>>>>>>>>>> type >>>>>>>>>>>>>>>> /// non-static data member or base class. >>>>>>>>>>>>>>>> bool hasNonLiteralTypeFieldsOrBases() const { >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Modified: cfe/trunk/lib/AST/ASTImporter.cpp >>>>>>>>>>>>>>>> URL: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=310401&r1=310400&r2=310401&view=diff >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>>>>> --- cfe/trunk/lib/AST/ASTImporter.cpp (original) >>>>>>>>>>>>>>>> +++ cfe/trunk/lib/AST/ASTImporter.cpp Tue Aug 8 12:12:28 >>>>>>>>>>>>>>>> 2017 >>>>>>>>>>>>>>>> @@ -956,12 +956,16 @@ bool >>>>>>>>>>>>>>>> ASTNodeImporter::ImportDefinition(R >>>>>>>>>>>>>>>> ToData.HasUninitializedFields = >>>>>>>>>>>>>>>> FromData.HasUninitializedFields; >>>>>>>>>>>>>>>> ToData.HasInheritedConstructor = >>>>>>>>>>>>>>>> FromData.HasInheritedConstructor; >>>>>>>>>>>>>>>> ToData.HasInheritedAssignment = >>>>>>>>>>>>>>>> FromData.HasInheritedAssignment; >>>>>>>>>>>>>>>> + ToData.NeedOverloadResolutionForCopyConstructor >>>>>>>>>>>>>>>> + = FromData.NeedOverloadResolutionForCopyConstructor; >>>>>>>>>>>>>>>> ToData.NeedOverloadResolutionForMoveConstructor >>>>>>>>>>>>>>>> = FromData.NeedOverloadResolutionForMoveConstructor; >>>>>>>>>>>>>>>> ToData.NeedOverloadResolutionForMoveAssignment >>>>>>>>>>>>>>>> = FromData.NeedOverloadResolutionForMoveAssignment; >>>>>>>>>>>>>>>> ToData.NeedOverloadResolutionForDestructor >>>>>>>>>>>>>>>> = FromData.NeedOverloadResolutionForDestructor; >>>>>>>>>>>>>>>> + ToData.DefaultedCopyConstructorIsDeleted >>>>>>>>>>>>>>>> + = FromData.DefaultedCopyConstructorIsDeleted; >>>>>>>>>>>>>>>> ToData.DefaultedMoveConstructorIsDeleted >>>>>>>>>>>>>>>> = FromData.DefaultedMoveConstructorIsDeleted; >>>>>>>>>>>>>>>> ToData.DefaultedMoveAssignmentIsDeleted >>>>>>>>>>>>>>>> @@ -973,6 +977,7 @@ bool ASTNodeImporter::ImportDefinition(R >>>>>>>>>>>>>>>> = FromData.HasConstexprNonCopyMoveConstructor; >>>>>>>>>>>>>>>> ToData.HasDefaultedDefaultConstructor >>>>>>>>>>>>>>>> = FromData.HasDefaultedDefaultConstructor; >>>>>>>>>>>>>>>> + ToData.CanPassInRegisters = FromData.CanPassInRegisters; >>>>>>>>>>>>>>>> ToData.DefaultedDefaultConstructorIsConstexpr >>>>>>>>>>>>>>>> = FromData.DefaultedDefaultConstructorIsConstexpr; >>>>>>>>>>>>>>>> ToData.HasConstexprDefaultConstructor >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Modified: cfe/trunk/lib/AST/DeclCXX.cpp >>>>>>>>>>>>>>>> URL: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=310401&r1=310400&r2=310401&view=diff >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>>>>> --- cfe/trunk/lib/AST/DeclCXX.cpp (original) >>>>>>>>>>>>>>>> +++ cfe/trunk/lib/AST/DeclCXX.cpp Tue Aug 8 12:12:28 2017 >>>>>>>>>>>>>>>> @@ -55,15 +55,18 @@ CXXRecordDecl::DefinitionData::Definitio >>>>>>>>>>>>>>>> HasOnlyCMembers(true), HasInClassInitializer(false), >>>>>>>>>>>>>>>> HasUninitializedReferenceMember(false), >>>>>>>>>>>>>>>> HasUninitializedFields(false), >>>>>>>>>>>>>>>> HasInheritedConstructor(false), >>>>>>>>>>>>>>>> HasInheritedAssignment(false), >>>>>>>>>>>>>>>> + NeedOverloadResolutionForCopyConstructor(false), >>>>>>>>>>>>>>>> NeedOverloadResolutionForMoveConstructor(false), >>>>>>>>>>>>>>>> NeedOverloadResolutionForMoveAssignment(false), >>>>>>>>>>>>>>>> NeedOverloadResolutionForDestructor(false), >>>>>>>>>>>>>>>> + DefaultedCopyConstructorIsDeleted(false), >>>>>>>>>>>>>>>> DefaultedMoveConstructorIsDeleted(false), >>>>>>>>>>>>>>>> DefaultedMoveAssignmentIsDeleted(false), >>>>>>>>>>>>>>>> DefaultedDestructorIsDeleted(false), >>>>>>>>>>>>>>>> HasTrivialSpecialMembers(SMF_All), >>>>>>>>>>>>>>>> DeclaredNonTrivialSpecialMembers(0), >>>>>>>>>>>>>>>> HasIrrelevantDestructor(true), >>>>>>>>>>>>>>>> HasConstexprNonCopyMoveConstructor(false), >>>>>>>>>>>>>>>> HasDefaultedDefaultConstructor(false), >>>>>>>>>>>>>>>> + CanPassInRegisters(false), >>>>>>>>>>>>>>>> DefaultedDefaultConstructorIsConstexpr(true), >>>>>>>>>>>>>>>> HasConstexprDefaultConstructor(false), >>>>>>>>>>>>>>>> HasNonLiteralTypeFieldsOrBases(false), >>>>>>>>>>>>>>>> ComputedVisibleConversions(false), >>>>>>>>>>>>>>>> @@ -352,8 +355,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier >>>>>>>>>>>>>>>> setHasVolatileMember(true); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> // Keep track of the presence of mutable fields. >>>>>>>>>>>>>>>> - if (BaseClassDecl->hasMutableFields()) >>>>>>>>>>>>>>>> + if (BaseClassDecl->hasMutableFields()) { >>>>>>>>>>>>>>>> data().HasMutableFields = true; >>>>>>>>>>>>>>>> + data().NeedOverloadResolutionForCopyConstructor = >>>>>>>>>>>>>>>> true; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> if (BaseClassDecl->hasUninitializedReferenceMember()) >>>>>>>>>>>>>>>> data().HasUninitializedReferenceMember = true; >>>>>>>>>>>>>>>> @@ -406,6 +411,8 @@ void CXXRecordDecl::addedClassSubobject( >>>>>>>>>>>>>>>> // -- a direct or virtual base class B that cannot be >>>>>>>>>>>>>>>> copied/moved >>>>>>>>>>>>>>>> [...] >>>>>>>>>>>>>>>> // -- a non-static data member of class type M (or >>>>>>>>>>>>>>>> array >>>>>>>>>>>>>>>> thereof) >>>>>>>>>>>>>>>> // that cannot be copied or moved [...] >>>>>>>>>>>>>>>> + if (!Subobj->hasSimpleCopyConstructor()) >>>>>>>>>>>>>>>> + data().NeedOverloadResolutionForCopyConstructor = true; >>>>>>>>>>>>>>>> if (!Subobj->hasSimpleMoveConstructor()) >>>>>>>>>>>>>>>> data().NeedOverloadResolutionForMoveConstructor = >>>>>>>>>>>>>>>> true; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @@ -426,6 +433,7 @@ void CXXRecordDecl::addedClassSubobject( >>>>>>>>>>>>>>>> // -- any non-static data member has a type with a >>>>>>>>>>>>>>>> destructor >>>>>>>>>>>>>>>> // that is deleted or inaccessible from the >>>>>>>>>>>>>>>> defaulted >>>>>>>>>>>>>>>> [ctor or >>>>>>>>>>>>>>>> dtor]. >>>>>>>>>>>>>>>> if (!Subobj->hasSimpleDestructor()) { >>>>>>>>>>>>>>>> + data().NeedOverloadResolutionForCopyConstructor = true; >>>>>>>>>>>>>>>> data().NeedOverloadResolutionForMoveConstructor = >>>>>>>>>>>>>>>> true; >>>>>>>>>>>>>>>> data().NeedOverloadResolutionForDestructor = true; >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> @@ -711,8 +719,10 @@ void CXXRecordDecl::addedMember(Decl *D) >>>>>>>>>>>>>>>> data().IsStandardLayout = false; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> // Keep track of the presence of mutable fields. >>>>>>>>>>>>>>>> - if (Field->isMutable()) >>>>>>>>>>>>>>>> + if (Field->isMutable()) { >>>>>>>>>>>>>>>> data().HasMutableFields = true; >>>>>>>>>>>>>>>> + data().NeedOverloadResolutionForCopyConstructor = >>>>>>>>>>>>>>>> true; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> // C++11 [class.union]p8, DR1460: >>>>>>>>>>>>>>>> // If X is a union, a non-static data member of X >>>>>>>>>>>>>>>> that is >>>>>>>>>>>>>>>> not an >>>>>>>>>>>>>>>> anonymous >>>>>>>>>>>>>>>> @@ -756,6 +766,12 @@ void CXXRecordDecl::addedMember(Decl *D) >>>>>>>>>>>>>>>> // A standard-layout class is a class that: >>>>>>>>>>>>>>>> // -- has no non-static data members of type >>>>>>>>>>>>>>>> [...] >>>>>>>>>>>>>>>> reference, >>>>>>>>>>>>>>>> data().IsStandardLayout = false; >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + // C++1z [class.copy.ctor]p10: >>>>>>>>>>>>>>>> + // A defaulted copy constructor for a class X is >>>>>>>>>>>>>>>> defined >>>>>>>>>>>>>>>> as >>>>>>>>>>>>>>>> deleted if X has: >>>>>>>>>>>>>>>> + // -- a non-static data member of rvalue reference >>>>>>>>>>>>>>>> type >>>>>>>>>>>>>>>> + if (T->isRValueReferenceType()) >>>>>>>>>>>>>>>> + data().DefaultedCopyConstructorIsDeleted = true; >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> if (!Field->hasInClassInitializer() && >>>>>>>>>>>>>>>> !Field->isMutable()) >>>>>>>>>>>>>>>> { >>>>>>>>>>>>>>>> @@ -809,6 +825,10 @@ void CXXRecordDecl::addedMember(Decl *D) >>>>>>>>>>>>>>>> // We may need to perform overload resolution to >>>>>>>>>>>>>>>> determine >>>>>>>>>>>>>>>> whether a >>>>>>>>>>>>>>>> // field can be moved if it's const or volatile >>>>>>>>>>>>>>>> qualified. >>>>>>>>>>>>>>>> if (T.getCVRQualifiers() & (Qualifiers::Const | >>>>>>>>>>>>>>>> Qualifiers::Volatile)) { >>>>>>>>>>>>>>>> + // We need to care about 'const' for the copy >>>>>>>>>>>>>>>> constructor >>>>>>>>>>>>>>>> because an >>>>>>>>>>>>>>>> + // implicit copy constructor might be declared >>>>>>>>>>>>>>>> with a >>>>>>>>>>>>>>>> non-const >>>>>>>>>>>>>>>> + // parameter. >>>>>>>>>>>>>>>> + data().NeedOverloadResolutionForCopyConstructor = >>>>>>>>>>>>>>>> true; >>>>>>>>>>>>>>>> data().NeedOverloadResolutionForMoveConstructor >>>>>>>>>>>>>>>> = >>>>>>>>>>>>>>>> true; >>>>>>>>>>>>>>>> data().NeedOverloadResolutionForMoveAssignment = >>>>>>>>>>>>>>>> true; >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> @@ -819,6 +839,8 @@ void CXXRecordDecl::addedMember(Decl *D) >>>>>>>>>>>>>>>> // -- X is a union-like class that has a >>>>>>>>>>>>>>>> variant >>>>>>>>>>>>>>>> member >>>>>>>>>>>>>>>> with a >>>>>>>>>>>>>>>> // non-trivial [corresponding special >>>>>>>>>>>>>>>> member] >>>>>>>>>>>>>>>> if (isUnion()) { >>>>>>>>>>>>>>>> + if (FieldRec->hasNonTrivialCopyConstructor()) >>>>>>>>>>>>>>>> + data().DefaultedCopyConstructorIsDeleted = true; >>>>>>>>>>>>>>>> if (FieldRec->hasNonTrivialMoveConstructor()) >>>>>>>>>>>>>>>> data().DefaultedMoveConstructorIsDeleted = >>>>>>>>>>>>>>>> true; >>>>>>>>>>>>>>>> if (FieldRec->hasNonTrivialMoveAssignment()) >>>>>>>>>>>>>>>> @@ -830,6 +852,8 @@ void CXXRecordDecl::addedMember(Decl *D) >>>>>>>>>>>>>>>> // For an anonymous union member, our overload >>>>>>>>>>>>>>>> resolution >>>>>>>>>>>>>>>> will >>>>>>>>>>>>>>>> perform >>>>>>>>>>>>>>>> // overload resolution for its members. >>>>>>>>>>>>>>>> if (Field->isAnonymousStructOrUnion()) { >>>>>>>>>>>>>>>> + data().NeedOverloadResolutionForCopyConstructor |= >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> FieldRec->data().NeedOverloadResolutionForCopyConstructor; >>>>>>>>>>>>>>>> data().NeedOverloadResolutionForMoveConstructor >>>>>>>>>>>>>>>> |= >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> FieldRec->data().NeedOverloadResolutionForMoveConstructor; >>>>>>>>>>>>>>>> data().NeedOverloadResolutionForMoveAssignment >>>>>>>>>>>>>>>> |= >>>>>>>>>>>>>>>> @@ -915,8 +939,10 @@ void CXXRecordDecl::addedMember(Decl *D) >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> // Keep track of the presence of mutable fields. >>>>>>>>>>>>>>>> - if (FieldRec->hasMutableFields()) >>>>>>>>>>>>>>>> + if (FieldRec->hasMutableFields()) { >>>>>>>>>>>>>>>> data().HasMutableFields = true; >>>>>>>>>>>>>>>> + data().NeedOverloadResolutionForCopyConstructor = >>>>>>>>>>>>>>>> true; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> // C++11 [class.copy]p13: >>>>>>>>>>>>>>>> // If the implicitly-defined constructor would >>>>>>>>>>>>>>>> satisfy >>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>> @@ -1450,7 +1476,7 @@ void >>>>>>>>>>>>>>>> CXXRecordDecl::completeDefinition() >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> void >>>>>>>>>>>>>>>> CXXRecordDecl::completeDefinition(CXXFinalOverriderMap >>>>>>>>>>>>>>>> *FinalOverriders) { >>>>>>>>>>>>>>>> RecordDecl::completeDefinition(); >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> // If the class may be abstract (but hasn't been marked >>>>>>>>>>>>>>>> as >>>>>>>>>>>>>>>> such), >>>>>>>>>>>>>>>> check >>>>>>>>>>>>>>>> for >>>>>>>>>>>>>>>> // any pure final overriders. >>>>>>>>>>>>>>>> if (mayBeAbstract()) { >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Modified: cfe/trunk/lib/CodeGen/CGCXXABI.cpp >>>>>>>>>>>>>>>> URL: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.cpp?rev=310401&r1=310400&r2=310401&view=diff >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>>>>> --- cfe/trunk/lib/CodeGen/CGCXXABI.cpp (original) >>>>>>>>>>>>>>>> +++ cfe/trunk/lib/CodeGen/CGCXXABI.cpp Tue Aug 8 12:12:28 >>>>>>>>>>>>>>>> 2017 >>>>>>>>>>>>>>>> @@ -30,38 +30,9 @@ void CGCXXABI::ErrorUnsupportedABI(CodeG >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> bool CGCXXABI::canCopyArgument(const CXXRecordDecl *RD) >>>>>>>>>>>>>>>> const { >>>>>>>>>>>>>>>> - // If RD has a non-trivial move or copy constructor, we >>>>>>>>>>>>>>>> cannot >>>>>>>>>>>>>>>> copy >>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>> - // argument. >>>>>>>>>>>>>>>> - if (RD->hasNonTrivialCopyConstructor() || >>>>>>>>>>>>>>>> RD->hasNonTrivialMoveConstructor()) >>>>>>>>>>>>>>>> - return false; >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> - // If RD has a non-trivial destructor, we cannot copy the >>>>>>>>>>>>>>>> argument. >>>>>>>>>>>>>>>> - if (RD->hasNonTrivialDestructor()) >>>>>>>>>>>>>>>> - return false; >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> // We can only copy the argument if there exists at >>>>>>>>>>>>>>>> least one >>>>>>>>>>>>>>>> trivial, >>>>>>>>>>>>>>>> // non-deleted copy or move constructor. >>>>>>>>>>>>>>>> - // FIXME: This assumes that all lazily declared copy and >>>>>>>>>>>>>>>> move >>>>>>>>>>>>>>>> constructors are >>>>>>>>>>>>>>>> - // not deleted. This assumption might not be true in some >>>>>>>>>>>>>>>> corner >>>>>>>>>>>>>>>> cases. >>>>>>>>>>>>>>>> - bool CopyDeleted = false; >>>>>>>>>>>>>>>> - bool MoveDeleted = false; >>>>>>>>>>>>>>>> - for (const CXXConstructorDecl *CD : RD->ctors()) { >>>>>>>>>>>>>>>> - if (CD->isCopyConstructor() || CD->isMoveConstructor()) >>>>>>>>>>>>>>>> { >>>>>>>>>>>>>>>> - assert(CD->isTrivial()); >>>>>>>>>>>>>>>> - // We had at least one undeleted trivial copy or move >>>>>>>>>>>>>>>> ctor. >>>>>>>>>>>>>>>> Return >>>>>>>>>>>>>>>> - // directly. >>>>>>>>>>>>>>>> - if (!CD->isDeleted()) >>>>>>>>>>>>>>>> - return true; >>>>>>>>>>>>>>>> - if (CD->isCopyConstructor()) >>>>>>>>>>>>>>>> - CopyDeleted = true; >>>>>>>>>>>>>>>> - else >>>>>>>>>>>>>>>> - MoveDeleted = true; >>>>>>>>>>>>>>>> - } >>>>>>>>>>>>>>>> - } >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> - // If all trivial copy and move constructors are deleted, >>>>>>>>>>>>>>>> we >>>>>>>>>>>>>>>> cannot >>>>>>>>>>>>>>>> copy the >>>>>>>>>>>>>>>> - // argument. >>>>>>>>>>>>>>>> - return !(CopyDeleted && MoveDeleted); >>>>>>>>>>>>>>>> + return RD->canPassInRegisters(); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType >>>>>>>>>>>>>>>> T) { >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp >>>>>>>>>>>>>>>> URL: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=310401&r1=310400&r2=310401&view=diff >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>>>>> --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) >>>>>>>>>>>>>>>> +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue Aug 8 >>>>>>>>>>>>>>>> 12:12:28 >>>>>>>>>>>>>>>> 2017 >>>>>>>>>>>>>>>> @@ -63,11 +63,8 @@ public: >>>>>>>>>>>>>>>> bool classifyReturnType(CGFunctionInfo &FI) const >>>>>>>>>>>>>>>> override; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) >>>>>>>>>>>>>>>> const >>>>>>>>>>>>>>>> override >>>>>>>>>>>>>>>> { >>>>>>>>>>>>>>>> - // Structures with either a non-trivial destructor or a >>>>>>>>>>>>>>>> non-trivial >>>>>>>>>>>>>>>> - // copy constructor are always indirect. >>>>>>>>>>>>>>>> - // FIXME: Use canCopyArgument() when it is fixed to >>>>>>>>>>>>>>>> handle >>>>>>>>>>>>>>>> lazily >>>>>>>>>>>>>>>> declared >>>>>>>>>>>>>>>> - // special members. >>>>>>>>>>>>>>>> - if (RD->hasNonTrivialDestructor() || >>>>>>>>>>>>>>>> RD->hasNonTrivialCopyConstructor()) >>>>>>>>>>>>>>>> + // If C++ prohibits us from making a copy, pass by >>>>>>>>>>>>>>>> address. >>>>>>>>>>>>>>>> + if (!canCopyArgument(RD)) >>>>>>>>>>>>>>>> return RAA_Indirect; >>>>>>>>>>>>>>>> return RAA_Default; >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> @@ -1014,10 +1011,8 @@ bool >>>>>>>>>>>>>>>> ItaniumCXXABI::classifyReturnType(C >>>>>>>>>>>>>>>> if (!RD) >>>>>>>>>>>>>>>> return false; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - // Return indirectly if we have a non-trivial copy ctor or >>>>>>>>>>>>>>>> non-trivial >>>>>>>>>>>>>>>> dtor. >>>>>>>>>>>>>>>> - // FIXME: Use canCopyArgument() when it is fixed to handle >>>>>>>>>>>>>>>> lazily >>>>>>>>>>>>>>>> declared >>>>>>>>>>>>>>>> - // special members. >>>>>>>>>>>>>>>> - if (RD->hasNonTrivialDestructor() || >>>>>>>>>>>>>>>> RD->hasNonTrivialCopyConstructor()) { >>>>>>>>>>>>>>>> + // If C++ prohibits us from making a copy, return by >>>>>>>>>>>>>>>> address. >>>>>>>>>>>>>>>> + if (!canCopyArgument(RD)) { >>>>>>>>>>>>>>>> auto Align = >>>>>>>>>>>>>>>> CGM.getContext().getTypeAlignInChars(FI.getReturnType()); >>>>>>>>>>>>>>>> FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, >>>>>>>>>>>>>>>> /*ByVal=*/false); >>>>>>>>>>>>>>>> return true; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp >>>>>>>>>>>>>>>> URL: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=310401&r1=310400&r2=310401&view=diff >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>>>>> --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original) >>>>>>>>>>>>>>>> +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Tue Aug 8 >>>>>>>>>>>>>>>> 12:12:28 >>>>>>>>>>>>>>>> 2017 >>>>>>>>>>>>>>>> @@ -819,46 +819,44 @@ MicrosoftCXXABI::getRecordArgABI(const >>>>>>>>>>>>>>>> C >>>>>>>>>>>>>>>> return RAA_Default; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> case llvm::Triple::x86_64: >>>>>>>>>>>>>>>> - // Win64 passes objects with non-trivial copy ctors >>>>>>>>>>>>>>>> indirectly. >>>>>>>>>>>>>>>> - if (RD->hasNonTrivialCopyConstructor()) >>>>>>>>>>>>>>>> - return RAA_Indirect; >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> - // If an object has a destructor, we'd really like to >>>>>>>>>>>>>>>> pass it >>>>>>>>>>>>>>>> indirectly >>>>>>>>>>>>>>>> + // If a class has a destructor, we'd really like to pass >>>>>>>>>>>>>>>> it >>>>>>>>>>>>>>>> indirectly >>>>>>>>>>>>>>>> // because it allows us to elide copies. >>>>>>>>>>>>>>>> Unfortunately, >>>>>>>>>>>>>>>> MSVC >>>>>>>>>>>>>>>> makes >>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>> // impossible for small types, which it will pass in a >>>>>>>>>>>>>>>> single >>>>>>>>>>>>>>>> register or >>>>>>>>>>>>>>>> // stack slot. Most objects with dtors are large-ish, >>>>>>>>>>>>>>>> so >>>>>>>>>>>>>>>> handle >>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>> early. >>>>>>>>>>>>>>>> // We can't call out all large objects as being >>>>>>>>>>>>>>>> indirect >>>>>>>>>>>>>>>> because >>>>>>>>>>>>>>>> there are >>>>>>>>>>>>>>>> // multiple x64 calling conventions and the C++ ABI >>>>>>>>>>>>>>>> code >>>>>>>>>>>>>>>> shouldn't >>>>>>>>>>>>>>>> dictate >>>>>>>>>>>>>>>> // how we pass large POD types. >>>>>>>>>>>>>>>> + // >>>>>>>>>>>>>>>> + // Note: This permits small classes with nontrivial >>>>>>>>>>>>>>>> destructors >>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>> + // passed in registers, which is non-conforming. >>>>>>>>>>>>>>>> if (RD->hasNonTrivialDestructor() && >>>>>>>>>>>>>>>> getContext().getTypeSize(RD->getTypeForDecl()) > >>>>>>>>>>>>>>>> 64) >>>>>>>>>>>>>>>> return RAA_Indirect; >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - // If this is true, the implicit copy constructor that >>>>>>>>>>>>>>>> Sema >>>>>>>>>>>>>>>> would >>>>>>>>>>>>>>>> have >>>>>>>>>>>>>>>> - // created would not be deleted. FIXME: We should >>>>>>>>>>>>>>>> provide a >>>>>>>>>>>>>>>> more >>>>>>>>>>>>>>>> direct way >>>>>>>>>>>>>>>> - // for CodeGen to ask whether the constructor was >>>>>>>>>>>>>>>> deleted. >>>>>>>>>>>>>>>> - if (!RD->hasUserDeclaredCopyConstructor() && >>>>>>>>>>>>>>>> - !RD->hasUserDeclaredMoveConstructor() && >>>>>>>>>>>>>>>> - !RD->needsOverloadResolutionForMoveConstructor() && >>>>>>>>>>>>>>>> - !RD->hasUserDeclaredMoveAssignment() && >>>>>>>>>>>>>>>> - !RD->needsOverloadResolutionForMoveAssignment()) >>>>>>>>>>>>>>>> - return RAA_Default; >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> - // Otherwise, Sema should have created an implicit copy >>>>>>>>>>>>>>>> constructor >>>>>>>>>>>>>>>> if >>>>>>>>>>>>>>>> - // needed. >>>>>>>>>>>>>>>> - assert(!RD->needsImplicitCopyConstructor()); >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> - // We have to make sure the trivial copy constructor >>>>>>>>>>>>>>>> isn't >>>>>>>>>>>>>>>> deleted. >>>>>>>>>>>>>>>> - for (const CXXConstructorDecl *CD : RD->ctors()) { >>>>>>>>>>>>>>>> - if (CD->isCopyConstructor()) { >>>>>>>>>>>>>>>> - assert(CD->isTrivial()); >>>>>>>>>>>>>>>> - // We had at least one undeleted trivial copy ctor. >>>>>>>>>>>>>>>> Return >>>>>>>>>>>>>>>> directly. >>>>>>>>>>>>>>>> - if (!CD->isDeleted()) >>>>>>>>>>>>>>>> - return RAA_Default; >>>>>>>>>>>>>>>> + // If a class has at least one non-deleted, trivial copy >>>>>>>>>>>>>>>> constructor, >>>>>>>>>>>>>>>> it >>>>>>>>>>>>>>>> + // is passed according to the C ABI. Otherwise, it is >>>>>>>>>>>>>>>> passed >>>>>>>>>>>>>>>> indirectly. >>>>>>>>>>>>>>>> + // >>>>>>>>>>>>>>>> + // Note: This permits classes with non-trivial copy or >>>>>>>>>>>>>>>> move >>>>>>>>>>>>>>>> ctors >>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>> be >>>>>>>>>>>>>>>> + // passed in registers, so long as they *also* have a >>>>>>>>>>>>>>>> trivial >>>>>>>>>>>>>>>> copy >>>>>>>>>>>>>>>> ctor, >>>>>>>>>>>>>>>> + // which is non-conforming. >>>>>>>>>>>>>>>> + if (RD->needsImplicitCopyConstructor()) { >>>>>>>>>>>>>>>> + // If the copy ctor has not yet been declared, we can >>>>>>>>>>>>>>>> read >>>>>>>>>>>>>>>> its >>>>>>>>>>>>>>>> triviality >>>>>>>>>>>>>>>> + // off the AST. >>>>>>>>>>>>>>>> + if (!RD->defaultedCopyConstructorIsDeleted() && >>>>>>>>>>>>>>>> + RD->hasTrivialCopyConstructor()) >>>>>>>>>>>>>>>> + return RAA_Default; >>>>>>>>>>>>>>>> + } else { >>>>>>>>>>>>>>>> + // Otherwise, we need to find the copy constructor(s) >>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>> ask. >>>>>>>>>>>>>>>> + for (const CXXConstructorDecl *CD : RD->ctors()) { >>>>>>>>>>>>>>>> + if (CD->isCopyConstructor()) { >>>>>>>>>>>>>>>> + // We had at least one nondeleted trivial copy >>>>>>>>>>>>>>>> ctor. >>>>>>>>>>>>>>>> Return >>>>>>>>>>>>>>>> directly. >>>>>>>>>>>>>>>> + if (!CD->isDeleted() && CD->isTrivial()) >>>>>>>>>>>>>>>> + return RAA_Default; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - // The trivial copy constructor was deleted. Return >>>>>>>>>>>>>>>> indirectly. >>>>>>>>>>>>>>>> + // We have no trivial, non-deleted copy constructor. >>>>>>>>>>>>>>>> return RAA_Indirect; >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp >>>>>>>>>>>>>>>> URL: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=310401&r1=310400&r2=310401&view=diff >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>>>>> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) >>>>>>>>>>>>>>>> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Aug 8 12:12:28 >>>>>>>>>>>>>>>> 2017 >>>>>>>>>>>>>>>> @@ -5726,6 +5726,53 @@ static void >>>>>>>>>>>>>>>> DefineImplicitSpecialMember( >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> +/// Determine whether a type is permitted to be passed or >>>>>>>>>>>>>>>> returned >>>>>>>>>>>>>>>> in >>>>>>>>>>>>>>>> +/// registers, per C++ [class.temporary]p3. >>>>>>>>>>>>>>>> +static bool computeCanPassInRegisters(Sema &S, CXXRecordDecl >>>>>>>>>>>>>>>> *D) >>>>>>>>>>>>>>>> { >>>>>>>>>>>>>>>> + if (D->isDependentType() || D->isInvalidDecl()) >>>>>>>>>>>>>>>> + return false; >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + // Per C++ [class.temporary]p3, the relevant condition is: >>>>>>>>>>>>>>>> + // each copy constructor, move constructor, and >>>>>>>>>>>>>>>> destructor of >>>>>>>>>>>>>>>> X >>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>> + // either trivial or deleted, and X has at least one >>>>>>>>>>>>>>>> non-deleted >>>>>>>>>>>>>>>> copy >>>>>>>>>>>>>>>> + // or move constructor >>>>>>>>>>>>>>>> + bool HasNonDeletedCopyOrMove = false; >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + if (D->needsImplicitCopyConstructor() && >>>>>>>>>>>>>>>> + !D->defaultedCopyConstructorIsDeleted()) { >>>>>>>>>>>>>>>> + if (!D->hasTrivialCopyConstructor()) >>>>>>>>>>>>>>>> + return false; >>>>>>>>>>>>>>>> + HasNonDeletedCopyOrMove = true; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + if (S.getLangOpts().CPlusPlus11 && >>>>>>>>>>>>>>>> D->needsImplicitMoveConstructor() >>>>>>>>>>>>>>>> && >>>>>>>>>>>>>>>> + !D->defaultedMoveConstructorIsDeleted()) { >>>>>>>>>>>>>>>> + if (!D->hasTrivialMoveConstructor()) >>>>>>>>>>>>>>>> + return false; >>>>>>>>>>>>>>>> + HasNonDeletedCopyOrMove = true; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + if (D->needsImplicitDestructor() && >>>>>>>>>>>>>>>> !D->defaultedDestructorIsDeleted() >>>>>>>>>>>>>>>> && >>>>>>>>>>>>>>>> + !D->hasTrivialDestructor()) >>>>>>>>>>>>>>>> + return false; >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + for (const CXXMethodDecl *MD : D->methods()) { >>>>>>>>>>>>>>>> + if (MD->isDeleted()) >>>>>>>>>>>>>>>> + continue; >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + auto *CD = dyn_cast<CXXConstructorDecl>(MD); >>>>>>>>>>>>>>>> + if (CD && CD->isCopyOrMoveConstructor()) >>>>>>>>>>>>>>>> + HasNonDeletedCopyOrMove = true; >>>>>>>>>>>>>>>> + else if (!isa<CXXDestructorDecl>(MD)) >>>>>>>>>>>>>>>> + continue; >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + if (!MD->isTrivial()) >>>>>>>>>>>>>>>> + return false; >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + return HasNonDeletedCopyOrMove; >>>>>>>>>>>>>>>> +} >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> /// \brief Perform semantic checks on a class definition >>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>> has >>>>>>>>>>>>>>>> been >>>>>>>>>>>>>>>> /// completing, introducing implicitly-declared members, >>>>>>>>>>>>>>>> checking >>>>>>>>>>>>>>>> for >>>>>>>>>>>>>>>> /// abstract types, etc. >>>>>>>>>>>>>>>> @@ -5870,6 +5917,8 @@ void >>>>>>>>>>>>>>>> Sema::CheckCompletedCXXClass(CXXRec >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> checkClassLevelDLLAttribute(Record); >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> Record->setCanPassInRegisters(computeCanPassInRegisters(*this, >>>>>>>>>>>>>>>> Record)); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> /// Look up the special member function that would be >>>>>>>>>>>>>>>> called by >>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>> special >>>>>>>>>>>>>>>> @@ -7496,8 +7545,7 @@ void >>>>>>>>>>>>>>>> Sema::ActOnFinishCXXMemberSpecifica >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> reinterpret_cast<Decl**>(FieldCollector->getCurFields()), >>>>>>>>>>>>>>>> FieldCollector->getCurNumFields()), LBrac, >>>>>>>>>>>>>>>> RBrac, >>>>>>>>>>>>>>>> AttrList); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - CheckCompletedCXXClass( >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> dyn_cast_or_null<CXXRecordDecl>(TagDecl)); >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> CheckCompletedCXXClass(dyn_cast_or_null<CXXRecordDecl>(TagDecl)); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> /// AddImplicitlyDeclaredMembersToClass - Adds any >>>>>>>>>>>>>>>> implicitly-declared >>>>>>>>>>>>>>>> @@ -11929,8 +11977,10 @@ CXXConstructorDecl >>>>>>>>>>>>>>>> *Sema::DeclareImplici >>>>>>>>>>>>>>>> Scope *S = getScopeForContext(ClassDecl); >>>>>>>>>>>>>>>> CheckImplicitSpecialMemberDeclaration(S, >>>>>>>>>>>>>>>> CopyConstructor); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - if (ShouldDeleteSpecialMember(CopyConstructor, >>>>>>>>>>>>>>>> CXXCopyConstructor)) >>>>>>>>>>>>>>>> + if (ShouldDeleteSpecialMember(CopyConstructor, >>>>>>>>>>>>>>>> CXXCopyConstructor)) { >>>>>>>>>>>>>>>> + ClassDecl->setImplicitCopyConstructorIsDeleted(); >>>>>>>>>>>>>>>> SetDeclDeleted(CopyConstructor, ClassLoc); >>>>>>>>>>>>>>>> + } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> if (S) >>>>>>>>>>>>>>>> PushOnScopeChains(CopyConstructor, S, false); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp >>>>>>>>>>>>>>>> URL: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=310401&r1=310400&r2=310401&view=diff >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>>>>> --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) >>>>>>>>>>>>>>>> +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Aug 8 >>>>>>>>>>>>>>>> 12:12:28 >>>>>>>>>>>>>>>> 2017 >>>>>>>>>>>>>>>> @@ -1559,9 +1559,11 @@ void >>>>>>>>>>>>>>>> ASTDeclReader::ReadCXXDefinitionDat >>>>>>>>>>>>>>>> Data.HasUninitializedFields = Record.readInt(); >>>>>>>>>>>>>>>> Data.HasInheritedConstructor = Record.readInt(); >>>>>>>>>>>>>>>> Data.HasInheritedAssignment = Record.readInt(); >>>>>>>>>>>>>>>> + Data.NeedOverloadResolutionForCopyConstructor = >>>>>>>>>>>>>>>> Record.readInt(); >>>>>>>>>>>>>>>> Data.NeedOverloadResolutionForMoveConstructor = >>>>>>>>>>>>>>>> Record.readInt(); >>>>>>>>>>>>>>>> Data.NeedOverloadResolutionForMoveAssignment = >>>>>>>>>>>>>>>> Record.readInt(); >>>>>>>>>>>>>>>> Data.NeedOverloadResolutionForDestructor = >>>>>>>>>>>>>>>> Record.readInt(); >>>>>>>>>>>>>>>> + Data.DefaultedCopyConstructorIsDeleted = Record.readInt(); >>>>>>>>>>>>>>>> Data.DefaultedMoveConstructorIsDeleted = >>>>>>>>>>>>>>>> Record.readInt(); >>>>>>>>>>>>>>>> Data.DefaultedMoveAssignmentIsDeleted = >>>>>>>>>>>>>>>> Record.readInt(); >>>>>>>>>>>>>>>> Data.DefaultedDestructorIsDeleted = Record.readInt(); >>>>>>>>>>>>>>>> @@ -1570,6 +1572,7 @@ void >>>>>>>>>>>>>>>> ASTDeclReader::ReadCXXDefinitionDat >>>>>>>>>>>>>>>> Data.HasIrrelevantDestructor = Record.readInt(); >>>>>>>>>>>>>>>> Data.HasConstexprNonCopyMoveConstructor = >>>>>>>>>>>>>>>> Record.readInt(); >>>>>>>>>>>>>>>> Data.HasDefaultedDefaultConstructor = Record.readInt(); >>>>>>>>>>>>>>>> + Data.CanPassInRegisters = Record.readInt(); >>>>>>>>>>>>>>>> Data.DefaultedDefaultConstructorIsConstexpr = >>>>>>>>>>>>>>>> Record.readInt(); >>>>>>>>>>>>>>>> Data.HasConstexprDefaultConstructor = Record.readInt(); >>>>>>>>>>>>>>>> Data.HasNonLiteralTypeFieldsOrBases = Record.readInt(); >>>>>>>>>>>>>>>> @@ -1697,9 +1700,11 @@ void >>>>>>>>>>>>>>>> ASTDeclReader::MergeDefinitionData( >>>>>>>>>>>>>>>> MATCH_FIELD(HasUninitializedFields) >>>>>>>>>>>>>>>> MATCH_FIELD(HasInheritedConstructor) >>>>>>>>>>>>>>>> MATCH_FIELD(HasInheritedAssignment) >>>>>>>>>>>>>>>> + MATCH_FIELD(NeedOverloadResolutionForCopyConstructor) >>>>>>>>>>>>>>>> MATCH_FIELD(NeedOverloadResolutionForMoveConstructor) >>>>>>>>>>>>>>>> MATCH_FIELD(NeedOverloadResolutionForMoveAssignment) >>>>>>>>>>>>>>>> MATCH_FIELD(NeedOverloadResolutionForDestructor) >>>>>>>>>>>>>>>> + MATCH_FIELD(DefaultedCopyConstructorIsDeleted) >>>>>>>>>>>>>>>> MATCH_FIELD(DefaultedMoveConstructorIsDeleted) >>>>>>>>>>>>>>>> MATCH_FIELD(DefaultedMoveAssignmentIsDeleted) >>>>>>>>>>>>>>>> MATCH_FIELD(DefaultedDestructorIsDeleted) >>>>>>>>>>>>>>>> @@ -1708,6 +1713,7 @@ void >>>>>>>>>>>>>>>> ASTDeclReader::MergeDefinitionData( >>>>>>>>>>>>>>>> MATCH_FIELD(HasIrrelevantDestructor) >>>>>>>>>>>>>>>> OR_FIELD(HasConstexprNonCopyMoveConstructor) >>>>>>>>>>>>>>>> OR_FIELD(HasDefaultedDefaultConstructor) >>>>>>>>>>>>>>>> + MATCH_FIELD(CanPassInRegisters) >>>>>>>>>>>>>>>> MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr) >>>>>>>>>>>>>>>> OR_FIELD(HasConstexprDefaultConstructor) >>>>>>>>>>>>>>>> MATCH_FIELD(HasNonLiteralTypeFieldsOrBases) >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp >>>>>>>>>>>>>>>> URL: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=310401&r1=310400&r2=310401&view=diff >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>>>>> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) >>>>>>>>>>>>>>>> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Aug 8 >>>>>>>>>>>>>>>> 12:12:28 >>>>>>>>>>>>>>>> 2017 >>>>>>>>>>>>>>>> @@ -5875,9 +5875,11 @@ void >>>>>>>>>>>>>>>> ASTRecordWriter::AddCXXDefinitionDa >>>>>>>>>>>>>>>> Record->push_back(Data.HasUninitializedFields); >>>>>>>>>>>>>>>> Record->push_back(Data.HasInheritedConstructor); >>>>>>>>>>>>>>>> Record->push_back(Data.HasInheritedAssignment); >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Record->push_back(Data.NeedOverloadResolutionForCopyConstructor); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Record->push_back(Data.NeedOverloadResolutionForMoveConstructor); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Record->push_back(Data.NeedOverloadResolutionForMoveAssignment); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Record->push_back(Data.NeedOverloadResolutionForDestructor); >>>>>>>>>>>>>>>> + Record->push_back(Data.DefaultedCopyConstructorIsDeleted); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Record->push_back(Data.DefaultedMoveConstructorIsDeleted); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Record->push_back(Data.DefaultedMoveAssignmentIsDeleted); >>>>>>>>>>>>>>>> Record->push_back(Data.DefaultedDestructorIsDeleted); >>>>>>>>>>>>>>>> @@ -5886,6 +5888,7 @@ void >>>>>>>>>>>>>>>> ASTRecordWriter::AddCXXDefinitionDa >>>>>>>>>>>>>>>> Record->push_back(Data.HasIrrelevantDestructor); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Record->push_back(Data.HasConstexprNonCopyMoveConstructor); >>>>>>>>>>>>>>>> Record->push_back(Data.HasDefaultedDefaultConstructor); >>>>>>>>>>>>>>>> + Record->push_back(Data.CanPassInRegisters); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Record->push_back(Data.DefaultedDefaultConstructorIsConstexpr); >>>>>>>>>>>>>>>> Record->push_back(Data.HasConstexprDefaultConstructor); >>>>>>>>>>>>>>>> Record->push_back(Data.HasNonLiteralTypeFieldsOrBases); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Modified: cfe/trunk/test/CodeGenCXX/uncopyable-args.cpp >>>>>>>>>>>>>>>> URL: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/uncopyable-args.cpp?rev=310401&r1=310400&r2=310401&view=diff >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>>>>> --- cfe/trunk/test/CodeGenCXX/uncopyable-args.cpp (original) >>>>>>>>>>>>>>>> +++ cfe/trunk/test/CodeGenCXX/uncopyable-args.cpp Tue Aug 8 >>>>>>>>>>>>>>>> 12:12:28 >>>>>>>>>>>>>>>> 2017 >>>>>>>>>>>>>>>> @@ -1,5 +1,6 @@ >>>>>>>>>>>>>>>> // RUN: %clang_cc1 -std=c++11 -triple >>>>>>>>>>>>>>>> x86_64-unknown-unknown >>>>>>>>>>>>>>>> -emit-llvm >>>>>>>>>>>>>>>> -o - %s | FileCheck %s >>>>>>>>>>>>>>>> -// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc >>>>>>>>>>>>>>>> -emit-llvm >>>>>>>>>>>>>>>> -o >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> %s | FileCheck %s -check-prefix=WIN64 >>>>>>>>>>>>>>>> +// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc >>>>>>>>>>>>>>>> -emit-llvm >>>>>>>>>>>>>>>> -o >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> %s -fms-compatibility -fms-compatibility-version=18 | >>>>>>>>>>>>>>>> FileCheck %s >>>>>>>>>>>>>>>> -check-prefix=WIN64 -check-prefix=WIN64-18 >>>>>>>>>>>>>>>> +// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc >>>>>>>>>>>>>>>> -emit-llvm >>>>>>>>>>>>>>>> -o >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> %s -fms-compatibility -fms-compatibility-version=19 | >>>>>>>>>>>>>>>> FileCheck %s >>>>>>>>>>>>>>>> -check-prefix=WIN64 -check-prefix=WIN64-19 >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> namespace trivial { >>>>>>>>>>>>>>>> // Trivial structs should be passed directly. >>>>>>>>>>>>>>>> @@ -52,12 +53,11 @@ void foo(A); >>>>>>>>>>>>>>>> void bar() { >>>>>>>>>>>>>>>> foo({}); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> -// FIXME: The copy ctor is implicitly deleted. >>>>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: define void @_ZN9move_ctor3barEv() >>>>>>>>>>>>>>>> -// CHECK-DISABLED: call void @_Z{{.*}}C1Ev( >>>>>>>>>>>>>>>> -// CHECK-DISABLED-NOT: call >>>>>>>>>>>>>>>> -// CHECK-DISABLED: call void >>>>>>>>>>>>>>>> @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"* %{{.*}}) >>>>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: declare void >>>>>>>>>>>>>>>> @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"*) >>>>>>>>>>>>>>>> +// CHECK-LABEL: define void @_ZN9move_ctor3barEv() >>>>>>>>>>>>>>>> +// CHECK: call void @_Z{{.*}}C1Ev( >>>>>>>>>>>>>>>> +// CHECK-NOT: call >>>>>>>>>>>>>>>> +// CHECK: call void >>>>>>>>>>>>>>>> @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"* >>>>>>>>>>>>>>>> %{{.*}}) >>>>>>>>>>>>>>>> +// CHECK-LABEL: declare void >>>>>>>>>>>>>>>> @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"*) >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> // WIN64-LABEL: declare void >>>>>>>>>>>>>>>> @"\01?foo@move_ctor@@YAXUA@1@@Z"(%"struct.move_ctor::A"*) >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> @@ -73,12 +73,11 @@ void foo(A); >>>>>>>>>>>>>>>> void bar() { >>>>>>>>>>>>>>>> foo({}); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> -// FIXME: The copy ctor is deleted. >>>>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: define void >>>>>>>>>>>>>>>> @_ZN11all_deleted3barEv() >>>>>>>>>>>>>>>> -// CHECK-DISABLED: call void @_Z{{.*}}C1Ev( >>>>>>>>>>>>>>>> -// CHECK-DISABLED-NOT: call >>>>>>>>>>>>>>>> -// CHECK-DISABLED: call void >>>>>>>>>>>>>>>> @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"* >>>>>>>>>>>>>>>> %{{.*}}) >>>>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: declare void >>>>>>>>>>>>>>>> @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"*) >>>>>>>>>>>>>>>> +// CHECK-LABEL: define void @_ZN11all_deleted3barEv() >>>>>>>>>>>>>>>> +// CHECK: call void @_Z{{.*}}C1Ev( >>>>>>>>>>>>>>>> +// CHECK-NOT: call >>>>>>>>>>>>>>>> +// CHECK: call void >>>>>>>>>>>>>>>> @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"* >>>>>>>>>>>>>>>> %{{.*}}) >>>>>>>>>>>>>>>> +// CHECK-LABEL: declare void >>>>>>>>>>>>>>>> @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"*) >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> // WIN64-LABEL: declare void >>>>>>>>>>>>>>>> @"\01?foo@all_deleted@@YAXUA@1@@Z"(%"struct.all_deleted::A"*) >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> @@ -93,14 +92,15 @@ void foo(A); >>>>>>>>>>>>>>>> void bar() { >>>>>>>>>>>>>>>> foo({}); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> -// FIXME: The copy and move ctors are implicitly deleted. >>>>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: define void >>>>>>>>>>>>>>>> @_ZN18implicitly_deleted3barEv() >>>>>>>>>>>>>>>> -// CHECK-DISABLED: call void @_Z{{.*}}C1Ev( >>>>>>>>>>>>>>>> -// CHECK-DISABLED-NOT: call >>>>>>>>>>>>>>>> -// CHECK-DISABLED: call void >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"* >>>>>>>>>>>>>>>> %{{.*}}) >>>>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: declare void >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"*) >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> -// WIN64-LABEL: declare void >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @"\01?foo@implicitly_deleted@@YAXUA@1@@Z"(%"struct.implicitly_deleted::A"*) >>>>>>>>>>>>>>>> +// CHECK-LABEL: define void @_ZN18implicitly_deleted3barEv() >>>>>>>>>>>>>>>> +// CHECK: call void @_Z{{.*}}C1Ev( >>>>>>>>>>>>>>>> +// CHECK-NOT: call >>>>>>>>>>>>>>>> +// CHECK: call void >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"* >>>>>>>>>>>>>>>> %{{.*}}) >>>>>>>>>>>>>>>> +// CHECK-LABEL: declare void >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"*) >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> +// In MSVC 2013, the copy ctor is not deleted by a move >>>>>>>>>>>>>>>> assignment. >>>>>>>>>>>>>>>> In >>>>>>>>>>>>>>>> MSVC 2015, it is. >>>>>>>>>>>>>>>> +// WIN64-18-LABEL: declare void >>>>>>>>>>>>>>>> @"\01?foo@implicitly_deleted@@YAXUA@1@@Z"(i64 >>>>>>>>>>>>>>>> +// WIN64-19-LABEL: declare void >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @"\01?foo@implicitly_deleted@@YAXUA@1@@Z"(%"struct.implicitly_deleted::A"*) >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> namespace one_deleted { >>>>>>>>>>>>>>>> @@ -113,12 +113,11 @@ void foo(A); >>>>>>>>>>>>>>>> void bar() { >>>>>>>>>>>>>>>> foo({}); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> -// FIXME: The copy constructor is implicitly deleted. >>>>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: define void >>>>>>>>>>>>>>>> @_ZN11one_deleted3barEv() >>>>>>>>>>>>>>>> -// CHECK-DISABLED: call void @_Z{{.*}}C1Ev( >>>>>>>>>>>>>>>> -// CHECK-DISABLED-NOT: call >>>>>>>>>>>>>>>> -// CHECK-DISABLED: call void >>>>>>>>>>>>>>>> @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"* >>>>>>>>>>>>>>>> %{{.*}}) >>>>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: declare void >>>>>>>>>>>>>>>> @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"*) >>>>>>>>>>>>>>>> +// CHECK-LABEL: define void @_ZN11one_deleted3barEv() >>>>>>>>>>>>>>>> +// CHECK: call void @_Z{{.*}}C1Ev( >>>>>>>>>>>>>>>> +// CHECK-NOT: call >>>>>>>>>>>>>>>> +// CHECK: call void >>>>>>>>>>>>>>>> @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"* >>>>>>>>>>>>>>>> %{{.*}}) >>>>>>>>>>>>>>>> +// CHECK-LABEL: declare void >>>>>>>>>>>>>>>> @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"*) >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> // WIN64-LABEL: declare void >>>>>>>>>>>>>>>> @"\01?foo@one_deleted@@YAXUA@1@@Z"(%"struct.one_deleted::A"*) >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> @@ -195,12 +194,10 @@ void foo(B); >>>>>>>>>>>>>>>> void bar() { >>>>>>>>>>>>>>>> foo({}); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> -// FIXME: This class has a non-trivial copy ctor and a >>>>>>>>>>>>>>>> trivial >>>>>>>>>>>>>>>> copy >>>>>>>>>>>>>>>> ctor. >>>>>>>>>>>>>>>> It's >>>>>>>>>>>>>>>> -// not clear whether we should pass by address or in >>>>>>>>>>>>>>>> registers. >>>>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: define void >>>>>>>>>>>>>>>> @_ZN14two_copy_ctors3barEv() >>>>>>>>>>>>>>>> -// CHECK-DISABLED: call void @_Z{{.*}}C1Ev( >>>>>>>>>>>>>>>> -// CHECK-DISABLED: call void >>>>>>>>>>>>>>>> @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* >>>>>>>>>>>>>>>> %{{.*}}) >>>>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: declare void >>>>>>>>>>>>>>>> @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"*) >>>>>>>>>>>>>>>> +// CHECK-LABEL: define void @_ZN14two_copy_ctors3barEv() >>>>>>>>>>>>>>>> +// CHECK: call void @_Z{{.*}}C1Ev( >>>>>>>>>>>>>>>> +// CHECK: call void >>>>>>>>>>>>>>>> @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* >>>>>>>>>>>>>>>> %{{.*}}) >>>>>>>>>>>>>>>> +// CHECK-LABEL: declare void >>>>>>>>>>>>>>>> @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"*) >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> // WIN64-LABEL: declare void >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @"\01?foo@two_copy_ctors@@YAXUB@1@@Z"(%"struct.two_copy_ctors::B"*) >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> @@ -212,6 +209,7 @@ struct A { >>>>>>>>>>>>>>>> void *p; >>>>>>>>>>>>>>>> }; >>>>>>>>>>>>>>>> void *foo(A a) { return a.p; } >>>>>>>>>>>>>>>> +// CHECK-LABEL: define i8* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN15definition_only3fooENS_1AE(%"struct.definition_only::A"* >>>>>>>>>>>>>>>> // WIN64-LABEL: define i8* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @"\01?foo@definition_only@@YAPEAXUA@1@@Z"(%"struct.definition_only::A"* >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @@ -226,6 +224,7 @@ struct A { >>>>>>>>>>>>>>>> B b; >>>>>>>>>>>>>>>> }; >>>>>>>>>>>>>>>> void *foo(A a) { return a.b.p; } >>>>>>>>>>>>>>>> +// CHECK-LABEL: define i8* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN17deleted_by_member3fooENS_1AE(%"struct.deleted_by_member::A"* >>>>>>>>>>>>>>>> // WIN64-LABEL: define i8* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @"\01?foo@deleted_by_member@@YAPEAXUA@1@@Z"(%"struct.deleted_by_member::A"* >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @@ -239,6 +238,7 @@ struct A : B { >>>>>>>>>>>>>>>> A(); >>>>>>>>>>>>>>>> }; >>>>>>>>>>>>>>>> void *foo(A a) { return a.p; } >>>>>>>>>>>>>>>> +// CHECK-LABEL: define i8* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN15deleted_by_base3fooENS_1AE(%"struct.deleted_by_base::A"* >>>>>>>>>>>>>>>> // WIN64-LABEL: define i8* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @"\01?foo@deleted_by_base@@YAPEAXUA@1@@Z"(%"struct.deleted_by_base::A"* >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @@ -253,6 +253,7 @@ struct A { >>>>>>>>>>>>>>>> B b; >>>>>>>>>>>>>>>> }; >>>>>>>>>>>>>>>> void *foo(A a) { return a.b.p; } >>>>>>>>>>>>>>>> +// CHECK-LABEL: define i8* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN22deleted_by_member_copy3fooENS_1AE(%"struct.deleted_by_member_copy::A"* >>>>>>>>>>>>>>>> // WIN64-LABEL: define i8* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @"\01?foo@deleted_by_member_copy@@YAPEAXUA@1@@Z"(%"struct.deleted_by_member_copy::A"* >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @@ -266,6 +267,7 @@ struct A : B { >>>>>>>>>>>>>>>> A(); >>>>>>>>>>>>>>>> }; >>>>>>>>>>>>>>>> void *foo(A a) { return a.p; } >>>>>>>>>>>>>>>> +// CHECK-LABEL: define i8* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN20deleted_by_base_copy3fooENS_1AE(%"struct.deleted_by_base_copy::A"* >>>>>>>>>>>>>>>> // WIN64-LABEL: define i8* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @"\01?foo@deleted_by_base_copy@@YAPEAXUA@1@@Z"(%"struct.deleted_by_base_copy::A"* >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @@ -275,6 +277,75 @@ struct A { >>>>>>>>>>>>>>>> A(const A &o) = delete; >>>>>>>>>>>>>>>> void *p; >>>>>>>>>>>>>>>> }; >>>>>>>>>>>>>>>> +// CHECK-LABEL: define i8* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN15explicit_delete3fooENS_1AE(%"struct.explicit_delete::A"* >>>>>>>>>>>>>>>> // WIN64-LABEL: define i8* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @"\01?foo@explicit_delete@@YAPEAXUA@1@@Z"(%"struct.explicit_delete::A"* >>>>>>>>>>>>>>>> void *foo(A a) { return a.p; } >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> +namespace implicitly_deleted_copy_ctor { >>>>>>>>>>>>>>>> +struct A { >>>>>>>>>>>>>>>> + // No move ctor due to copy assignment. >>>>>>>>>>>>>>>> + A &operator=(const A&); >>>>>>>>>>>>>>>> + // Deleted copy ctor due to rvalue ref member. >>>>>>>>>>>>>>>> + int &&ref; >>>>>>>>>>>>>>>> +}; >>>>>>>>>>>>>>>> +// CHECK-LABEL: define {{.*}} >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(%"struct.implicitly_deleted_copy_ctor::A"* >>>>>>>>>>>>>>>> +// WIN64-LABEL: define {{.*}} >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @"\01?foo@implicitly_deleted_copy_ctor@@YAAEAHUA@1@@Z"(%"struct.implicitly_deleted_copy_ctor::A"* >>>>>>>>>>>>>>>> +int &foo(A a) { return a.ref; } >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> +struct B { >>>>>>>>>>>>>>>> + // Passed direct: has non-deleted trivial copy ctor. >>>>>>>>>>>>>>>> + B &operator=(const B&); >>>>>>>>>>>>>>>> + int &ref; >>>>>>>>>>>>>>>> +}; >>>>>>>>>>>>>>>> +int &foo(B b) { return b.ref; } >>>>>>>>>>>>>>>> +// CHECK-LABEL: define {{.*}} >>>>>>>>>>>>>>>> @_ZN28implicitly_deleted_copy_ctor3fooENS_1BE(i32* >>>>>>>>>>>>>>>> +// WIN64-LABEL: define {{.*}} >>>>>>>>>>>>>>>> @"\01?foo@implicitly_deleted_copy_ctor@@YAAEAHUB@1@@Z"(i64 >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> +struct X { X(const X&); }; >>>>>>>>>>>>>>>> +struct Y { Y(const Y&) = default; }; >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> +union C { >>>>>>>>>>>>>>>> + C &operator=(const C&); >>>>>>>>>>>>>>>> + // Passed indirect: copy ctor deleted due to variant >>>>>>>>>>>>>>>> member >>>>>>>>>>>>>>>> with >>>>>>>>>>>>>>>> nontrivial copy ctor. >>>>>>>>>>>>>>>> + X x; >>>>>>>>>>>>>>>> + int n; >>>>>>>>>>>>>>>> +}; >>>>>>>>>>>>>>>> +int foo(C c) { return c.n; } >>>>>>>>>>>>>>>> +// CHECK-LABEL: define {{.*}} >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN28implicitly_deleted_copy_ctor3fooENS_1CE(%"union.implicitly_deleted_copy_ctor::C"* >>>>>>>>>>>>>>>> +// WIN64-LABEL: define {{.*}} >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @"\01?foo@implicitly_deleted_copy_ctor@@YAHTC@1@@Z"(%"union.implicitly_deleted_copy_ctor::C"* >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> +struct D { >>>>>>>>>>>>>>>> + D &operator=(const D&); >>>>>>>>>>>>>>>> + // Passed indirect: copy ctor deleted due to variant >>>>>>>>>>>>>>>> member >>>>>>>>>>>>>>>> with >>>>>>>>>>>>>>>> nontrivial copy ctor. >>>>>>>>>>>>>>>> + union { >>>>>>>>>>>>>>>> + X x; >>>>>>>>>>>>>>>> + int n; >>>>>>>>>>>>>>>> + }; >>>>>>>>>>>>>>>> +}; >>>>>>>>>>>>>>>> +int foo(D d) { return d.n; } >>>>>>>>>>>>>>>> +// CHECK-LABEL: define {{.*}} >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @_ZN28implicitly_deleted_copy_ctor3fooENS_1DE(%"struct.implicitly_deleted_copy_ctor::D"* >>>>>>>>>>>>>>>> +// WIN64-LABEL: define {{.*}} >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> @"\01?foo@implicitly_deleted_copy_ctor@@YAHUD@1@@Z"(%"struct.implicitly_deleted_copy_ctor::D"* >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> +union E { >>>>>>>>>>>>>>>> + // Passed direct: has non-deleted trivial copy ctor. >>>>>>>>>>>>>>>> + E &operator=(const E&); >>>>>>>>>>>>>>>> + Y y; >>>>>>>>>>>>>>>> + int n; >>>>>>>>>>>>>>>> +}; >>>>>>>>>>>>>>>> +int foo(E e) { return e.n; } >>>>>>>>>>>>>>>> +// CHECK-LABEL: define {{.*}} >>>>>>>>>>>>>>>> @_ZN28implicitly_deleted_copy_ctor3fooENS_1EE(i32 >>>>>>>>>>>>>>>> +// WIN64-LABEL: define {{.*}} >>>>>>>>>>>>>>>> @"\01?foo@implicitly_deleted_copy_ctor@@YAHTE@1@@Z"(i32 >>>>>>>>>>>>>>>> + >>>>>>>>>>>>>>>> +struct F { >>>>>>>>>>>>>>>> + // Passed direct: has non-deleted trivial copy ctor. >>>>>>>>>>>>>>>> + F &operator=(const F&); >>>>>>>>>>>>>>>> + union { >>>>>>>>>>>>>>>> + Y y; >>>>>>>>>>>>>>>> + int n; >>>>>>>>>>>>>>>> + }; >>>>>>>>>>>>>>>> +}; >>>>>>>>>>>>>>>> +int foo(F f) { return f.n; } >>>>>>>>>>>>>>>> +// CHECK-LABEL: define {{.*}} >>>>>>>>>>>>>>>> @_ZN28implicitly_deleted_copy_ctor3fooENS_1FE(i32 >>>>>>>>>>>>>>>> +// WIN64-LABEL: define {{.*}} >>>>>>>>>>>>>>>> @"\01?foo@implicitly_deleted_copy_ctor@@YAHUF@1@@Z"(i32 >>>>>>>>>>>>>>>> +} >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Modified: >>>>>>>>>>>>>>>> cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp >>>>>>>>>>>>>>>> URL: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp?rev=310401&r1=310400&r2=310401&view=diff >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> ============================================================================== >>>>>>>>>>>>>>>> --- >>>>>>>>>>>>>>>> cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp >>>>>>>>>>>>>>>> (original) >>>>>>>>>>>>>>>> +++ >>>>>>>>>>>>>>>> cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp >>>>>>>>>>>>>>>> Tue >>>>>>>>>>>>>>>> Aug >>>>>>>>>>>>>>>> 8 12:12:28 2017 >>>>>>>>>>>>>>>> @@ -1108,26 +1108,35 @@ TEST(ConstructorDeclaration, >>>>>>>>>>>>>>>> IsExplicit) >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> TEST(ConstructorDeclaration, Kinds) { >>>>>>>>>>>>>>>> - EXPECT_TRUE(matches("struct S { S(); };", >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> cxxConstructorDecl(isDefaultConstructor()))); >>>>>>>>>>>>>>>> - EXPECT_TRUE(notMatches("struct S { S(); };", >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> cxxConstructorDecl(isCopyConstructor()))); >>>>>>>>>>>>>>>> - EXPECT_TRUE(notMatches("struct S { S(); };", >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> cxxConstructorDecl(isMoveConstructor()))); >>>>>>>>>>>>>>>> + EXPECT_TRUE(matches( >>>>>>>>>>>>>>>> + "struct S { S(); };", >>>>>>>>>>>>>>>> + cxxConstructorDecl(isDefaultConstructor(), >>>>>>>>>>>>>>>> unless(isImplicit())))); >>>>>>>>>>>>>>>> + EXPECT_TRUE(notMatches( >>>>>>>>>>>>>>>> + "struct S { S(); };", >>>>>>>>>>>>>>>> + cxxConstructorDecl(isCopyConstructor(), >>>>>>>>>>>>>>>> unless(isImplicit())))); >>>>>>>>>>>>>>>> + EXPECT_TRUE(notMatches( >>>>>>>>>>>>>>>> + "struct S { S(); };", >>>>>>>>>>>>>>>> + cxxConstructorDecl(isMoveConstructor(), >>>>>>>>>>>>>>>> unless(isImplicit())))); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - EXPECT_TRUE(notMatches("struct S { S(const S&); };", >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> cxxConstructorDecl(isDefaultConstructor()))); >>>>>>>>>>>>>>>> - EXPECT_TRUE(matches("struct S { S(const S&); };", >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> cxxConstructorDecl(isCopyConstructor()))); >>>>>>>>>>>>>>>> - EXPECT_TRUE(notMatches("struct S { S(const S&); };", >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> cxxConstructorDecl(isMoveConstructor()))); >>>>>>>>>>>>>>>> + EXPECT_TRUE(notMatches( >>>>>>>>>>>>>>>> + "struct S { S(const S&); };", >>>>>>>>>>>>>>>> + cxxConstructorDecl(isDefaultConstructor(), >>>>>>>>>>>>>>>> unless(isImplicit())))); >>>>>>>>>>>>>>>> + EXPECT_TRUE(matches( >>>>>>>>>>>>>>>> + "struct S { S(const S&); };", >>>>>>>>>>>>>>>> + cxxConstructorDecl(isCopyConstructor(), >>>>>>>>>>>>>>>> unless(isImplicit())))); >>>>>>>>>>>>>>>> + EXPECT_TRUE(notMatches( >>>>>>>>>>>>>>>> + "struct S { S(const S&); };", >>>>>>>>>>>>>>>> + cxxConstructorDecl(isMoveConstructor(), >>>>>>>>>>>>>>>> unless(isImplicit())))); >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - EXPECT_TRUE(notMatches("struct S { S(S&&); };", >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> cxxConstructorDecl(isDefaultConstructor()))); >>>>>>>>>>>>>>>> - EXPECT_TRUE(notMatches("struct S { S(S&&); };", >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> cxxConstructorDecl(isCopyConstructor()))); >>>>>>>>>>>>>>>> - EXPECT_TRUE(matches("struct S { S(S&&); };", >>>>>>>>>>>>>>>> - >>>>>>>>>>>>>>>> cxxConstructorDecl(isMoveConstructor()))); >>>>>>>>>>>>>>>> + EXPECT_TRUE(notMatches( >>>>>>>>>>>>>>>> + "struct S { S(S&&); };", >>>>>>>>>>>>>>>> + cxxConstructorDecl(isDefaultConstructor(), >>>>>>>>>>>>>>>> unless(isImplicit())))); >>>>>>>>>>>>>>>> + EXPECT_TRUE(notMatches( >>>>>>>>>>>>>>>> + "struct S { S(S&&); };", >>>>>>>>>>>>>>>> + cxxConstructorDecl(isCopyConstructor(), >>>>>>>>>>>>>>>> unless(isImplicit())))); >>>>>>>>>>>>>>>> + EXPECT_TRUE(matches( >>>>>>>>>>>>>>>> + "struct S { S(S&&); };", >>>>>>>>>>>>>>>> + cxxConstructorDecl(isMoveConstructor(), >>>>>>>>>>>>>>>> unless(isImplicit())))); >>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> TEST(ConstructorDeclaration, IsUserProvided) { >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>> cfe-commits mailing list >>>>>>>>>>>>>>>> cfe-commits@lists.llvm.org >>>>>>>>>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>> cfe-commits mailing list >>>>>>>>>>>>>>> cfe-commits@lists.llvm.org >>>>>>>>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>>>>>>>>>>>>> >>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>> cfe-commits mailing list >>>>>>>>>>>>>> cfe-commits@lists.llvm.org >>>>>>>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> cfe-commits mailing list >>>>>>>>> cfe-commits@lists.llvm.org >>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>>>>>> >>>>>>>> >> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits