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

Diana Picus via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 14 05:04:58 PDT 2017


See attached.

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
>>>>>>>
>>>>>>>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: asan_test.s
Type: application/octet-stream
Size: 1288079 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170814/e9a1a4b3/attachment-0003.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: asan_test.ll
Type: application/octet-stream
Size: 554185 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170814/e9a1a4b3/attachment-0004.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: asan_test.i
Type: application/octet-stream
Size: 2218145 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170814/e9a1a4b3/attachment-0005.obj>


More information about the cfe-commits mailing list