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. 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 >>>>> >>>>>
#0 0x00116304 in __sanitizer::internal_strlen(char const*) () at /home/diana.picus/linaro-scripts/bisect/llvm/projects/compiler-rt/lib/sanitizer_common/sanitizer_libc.cc:174 #1 0x00073aa0 in printf_common () at /home/diana.picus/linaro-scripts/bisect/llvm/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors_format.inc:546 #2 0x00073f80 in vfprintf () at /home/diana.picus/linaro-scripts/bisect/llvm/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:1506 #3 0x0002f3c8 in vprintf (__fmt=0x13613b " YOU HAVE %d DISABLED %s\n\n", __arg=...) at /usr/include/arm-linux-gnueabihf/bits/stdio.h:38 #4 testing::internal::ColoredPrintf (color=testing::internal::COLOR_YELLOW, fmt=<optimized out>) at /home/diana.picus/linaro-scripts/bisect/llvm/utils/unittest/googletest/src/gtest.cc:2998 #5 0x0003121c in testing::internal::PrettyUnitTestResultPrinter::OnTestIterationEnd (this=<optimized out>, unit_test=...) at /home/diana.picus/linaro-scripts/bisect/llvm/utils/unittest/googletest/src/gtest.cc:3222 #6 0x00031c64 in testing::internal::TestEventRepeater::OnTestIterationEnd (this=0xb4600580, unit_test=..., iteration=<optimized out>) at /home/diana.picus/linaro-scripts/bisect/llvm/utils/unittest/googletest/src/gtest.cc:3341 #7 0x00037468 in testing::internal::UnitTestImpl::RunAllTests (this=0xb3a03dc0) at /home/diana.picus/linaro-scripts/bisect/llvm/utils/unittest/googletest/src/gtest.cc:4663 #8 0x00036d74 in testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> ( method=(bool (testing::internal::UnitTestImpl::*)(testing::internal::UnitTestImpl * const)) 0x36f50 <testing::internal::UnitTestImpl::RunAllTests()>, location=<optimized out>, object=<optimized out>) at /home/diana.picus/linaro-scripts/bisect/llvm/utils/unittest/googletest/src/gtest.cc:2402 #9 testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (object=0xb3a03dc0, method=(bool (testing::internal::UnitTestImpl::*)(testing::internal::UnitTestImpl * const)) 0x36f50 <testing::internal::UnitTestImpl::RunAllTests()>, location=0x1363fc "auxiliary test code (environments or event listeners)") at /home/diana.picus/linaro-scripts/bisect/llvm/utils/unittest/googletest/src/gtest.cc:2438 #10 0x00036cbc in testing::UnitTest::Run (this=0x16f3ec <testing::UnitTest::GetInstance()::instance>) at /home/diana.picus/linaro-scripts/bisect/llvm/utils/unittest/googletest/src/gtest.cc:4257 #11 0x00055c58 in RUN_ALL_TESTS () at /home/diana.picus/linaro-scripts/bisect/llvm/utils/unittest/googletest/include/gtest/gtest.h:2233 #12 main (argc=1, argv=<optimized out>) at /home/diana.picus/linaro-scripts/bisect/compiler-rt/lib/asan/tests/asan_test_main.cc:55
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits