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