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

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 14 15:53:43 PDT 2017


On 14 August 2017 at 03:27, Diana Picus via cfe-commits <
cfe-commits at lists.llvm.org> 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.
>

LLVM IR from before and after the change (with -Xclang
-disable-llvm-passes, so we can see the frontend output before the
optimizers run) would be a huge help. That should make it pretty easy to
determine whether the issue is a frontend bug or whether we've exposed a
(pre-existing) optimizer bug / UB in gtest.


> 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.NeedOverloadResolutionForCopyC
> onstructor);
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Record->push_back(Data.NeedOverloadResolutionForMoveC
> onstructor);
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Record->push_back(Data.NeedOverloadResolutionForMoveA
> ssignment);
> >>>>>>>>>>>>>     Record->push_back(Data.NeedOverloadResolutionForDestr
> uctor);
> >>>>>>>>>>>>> +  Record->push_back(Data.DefaultedCopyConstructorIsDele
> ted);
> >>>>>>>>>>>>>     Record->push_back(Data.DefaultedMoveConstructorIsDele
> ted);
> >>>>>>>>>>>>>     Record->push_back(Data.DefaultedMoveAssignmentIsDelet
> ed);
> >>>>>>>>>>>>>     Record->push_back(Data.DefaultedDestructorIsDeleted);
> >>>>>>>>>>>>> @@ -5886,6 +5888,7 @@ void ASTRecordWriter::
> AddCXXDefinitionDa
> >>>>>>>>>>>>>     Record->push_back(Data.HasIrrelevantDestructor);
> >>>>>>>>>>>>>     Record->push_back(Data.HasConstexprNonCopyMoveConstru
> ctor);
> >>>>>>>>>>>>>     Record->push_back(Data.HasDefaultedDefaultConstructor);
> >>>>>>>>>>>>> +  Record->push_back(Data.CanPassInRegisters);
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> Record->push_back(Data.DefaultedDefaultConstructorIsC
> onstexpr);
> >>>>>>>>>>>>>     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
> >>>>>
> >>>>>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170814/d2e93de4/attachment-0001.html>


More information about the cfe-commits mailing list