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 07:08:27 PDT 2017


On 14/08/17 13:04, Diana Picus wrote:
> See attached.
Thanks! It looks like asan_test.i doesn't have gtest.cc which appears in 
the stack trace. Am I missing something?
>
> On 14 August 2017 at 13:30, Vassil Vassilev <v.g.vassilev at gmail.com> wrote:
>> On 14/08/17 11:27, Diana Picus wrote:
>>> Hi,
>>>
>>> Strangely enough, it turns out that if I run
>>> Asan-armhf-with-calls-Noinst-Test on the command line it fails,
>>> although it doesn't fail when run with lit. I've attached the stack
>>> trace from gdb. It looks like some trouble passing down va_arg
>>> parameters, but I haven't looked into too much details. The segfault
>>> happens when we try to do a   ldrb   r3, [r0, r1], with r1 set to 0 by
>>> the current function and r0 passed down from the caller. I'm not sure
>>> if this is the exact same problem as the other tests, but feel free to
>>> have a look at that code.
>>>
>>> Meanwhile, I've removed some clutter from Asan-armhf-with-calls-Test
>>> (which is the original failure that we were seeing) and left only one
>>> failing test that seemed small enough. I'll try to look at the
>>> disassembly before/after the patch and maybe even run valgrind on it
>>> (running it on the original binary naturally takes forever).
>>>
>>> Let me know if there's anything else I could try. I can also send you
>>> disassembly or even LLVM IR for the Asan-armhf-with-calls-Noinst-Test
>>> if you think it helps.
>>    disassembly and LLVM will greatly help as well.
>>
>>> Cheers,
>>> Diana
>>>
>>> On 11 August 2017 at 15:34, Diana Picus <diana.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