r310401 - PR19668, PR23034: Fix handling of move constructors and deleted copy

Vassil Vassilev via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 14 04:28:51 PDT 2017


Hi Diana,

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.
   That smells like our patch is interfering in some way...
>
> 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.
   Would you be able to run clang -E on the translation unit that 
crashes and send it over? If you could give us a minimal reproducer it 
would be even better.

Cheers, Vassil
>
> Cheers,
> Diana
>
> On 11 August 2017 at 15:34, Diana Picus <diana.picus at 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.vassilev at 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.picus at 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.picus at 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 <richard at 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 at 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.vassilev at 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.picus at 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.vassilev at 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 at 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 at 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 at move_ctor@@YAXUA at 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 at all_deleted@@YAXUA at 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 at implicitly_deleted@@YAXUA at 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 at implicitly_deleted@@YAXUA at 1@@Z"(i64
>>>>>>>>>>>>>> +// WIN64-19-LABEL: declare void
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> @"\01?foo at implicitly_deleted@@YAXUA at 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 at one_deleted@@YAXUA at 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 at two_copy_ctors@@YAXUB at 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 at definition_only@@YAPEAXUA at 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 at deleted_by_member@@YAPEAXUA at 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 at deleted_by_base@@YAPEAXUA at 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 at deleted_by_member_copy@@YAPEAXUA at 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 at deleted_by_base_copy@@YAPEAXUA at 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 at explicit_delete@@YAPEAXUA at 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 at implicitly_deleted_copy_ctor@@YAAEAHUA at 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 at implicitly_deleted_copy_ctor@@YAAEAHUB at 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 at implicitly_deleted_copy_ctor@@YAHTC at 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 at implicitly_deleted_copy_ctor@@YAHUD at 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 at implicitly_deleted_copy_ctor@@YAHTE at 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 at implicitly_deleted_copy_ctor@@YAHUF at 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 at lists.llvm.org
>>>>>>>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>> cfe-commits mailing list
>>>>>>>>>>>>> cfe-commits at lists.llvm.org
>>>>>>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>>>>>>>>>>>
>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>> cfe-commits mailing list
>>>>>>>>>>>> cfe-commits at lists.llvm.org
>>>>>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> cfe-commits mailing list
>>>>>>> cfe-commits at lists.llvm.org
>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>>>>



More information about the cfe-commits mailing list