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:51:51 PDT 2017


On 14/08/17 15:08, Vassil Vassilev wrote:
> 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?
   Could you paste the compiler invocation. Are we building with -O0 (I 
see quite a lot of things inline). Could it be an optimizer problem?
>>
>> 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