<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 14 August 2017 at 03:27, Diana Picus via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br>
<br>
Strangely enough, it turns out that if I run<br>
Asan-armhf-with-calls-Noinst-<wbr>Test on the command line it fails,<br>
although it doesn't fail when run with lit. I've attached the stack<br>
trace from gdb. It looks like some trouble passing down va_arg<br>
parameters, but I haven't looked into too much details. The segfault<br>
happens when we try to do a   ldrb   r3, [r0, r1], with r1 set to 0 by<br>
the current function and r0 passed down from the caller. I'm not sure<br>
if this is the exact same problem as the other tests, but feel free to<br>
have a look at that code.<br>
<br>
Meanwhile, I've removed some clutter from Asan-armhf-with-calls-Test<br>
(which is the original failure that we were seeing) and left only one<br>
failing test that seemed small enough. I'll try to look at the<br>
disassembly before/after the patch and maybe even run valgrind on it<br>
(running it on the original binary naturally takes forever).<br>
<br>
Let me know if there's anything else I could try. I can also send you<br>
disassembly or even LLVM IR for the Asan-armhf-with-calls-Noinst-<wbr>Test<br>
if you think it helps.<br></blockquote><div><br></div><div>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.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Cheers,<br>
Diana<br>
<div class="gmail-HOEnZb"><div class="gmail-h5"><br>
On 11 August 2017 at 15:34, Diana Picus <<a href="mailto:diana.picus@linaro.org">diana.picus@linaro.org</a>> wrote:<br>
> Well, these are ASAN tests, I'm not sure how that would interact with Valgrind.<br>
> Anyway, I'll try to reproduce the environment, I'm guessing it would<br>
> be best to catch this in gdb so I can actually see what's going on.<br>
><br>
> On 11 August 2017 at 15:21, Vassil Vassilev <<a href="mailto:v.g.vassilev@gmail.com">v.g.vassilev@gmail.com</a>> wrote:<br>
>> That's really strange. It looks like some random behavior. Did you run some memory checker like valgrind?<br>
>><br>
>> Do the environment provided by the test runner and yours match?<br>
>><br>
>> Sent from my phone. Please excuse my brevity.<br>
>><br>
>>> On 11 Aug 2017, at 15:58, Diana Picus <<a href="mailto:diana.picus@linaro.org">diana.picus@linaro.org</a>> wrote:<br>
>>><br>
>>> Hi again,<br>
>>><br>
>>> I finally got the debug build, but unfortunately the stack traces that<br>
>>> the tests print look the same. My suspicion is that this is because<br>
>>> the addresses printed by the tests are funny (i.e. odd numbers instead<br>
>>> of divisible by 4). I tried to follow those addresses in an objdump of<br>
>>> the executable, but I didn't have much success since most of them<br>
>>> weren't really pointing to call instructions.<br>
>>><br>
>>> When I try to run the tests manually in the shell or in gdb, they pass.<br>
>>><br>
>>> I'm not sure what else to try. Thoughts?<br>
>>><br>
>>> Thanks,<br>
>>> Diana<br>
>>><br>
>>>> On 11 August 2017 at 11:14, Diana Picus <<a href="mailto:diana.picus@linaro.org">diana.picus@linaro.org</a>> wrote:<br>
>>>> Hi guys,<br>
>>>><br>
>>>> I'm SO sorry about the delays. I've been having all sorts of trouble<br>
>>>> getting that debug build on the board (from ld running out of memory<br>
>>>> to the board just crashing on me, in which case I need to ask someone<br>
>>>> else to reboot it because I can't power cycle it remotely). I can<br>
>>>> assure you this is one of my top priorities, I'll get those stack<br>
>>>> traces as soon as I can.<br>
>>>><br>
>>>> Thanks for your patience and sorry again,<br>
>>>> Diana<br>
>>>><br>
>>>>> On 10 August 2017 at 22:55, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
>>>>> Any news on this? We want this change in Clang 5, so the sooner we can<br>
>>>>> understand and fix this regression the better...<br>
>>>>><br>
>>>>> On 10 August 2017 at 01:28, Diana Picus via cfe-commits<br>
>>>>> <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
>>>>>><br>
>>>>>> Hi Vassil,<br>
>>>>>><br>
>>>>>> My build is in progress, but since it's a full build it's probably<br>
>>>>>> going to take another couple of hours to complete. I'll let you know<br>
>>>>>> when it's done.<br>
>>>>>><br>
>>>>>> Thanks,<br>
>>>>>> Diana<br>
>>>>>><br>
>>>>>> On 10 August 2017 at 10:09, Vassil Vassilev <<a href="mailto:v.g.vassilev@gmail.com">v.g.vassilev@gmail.com</a>><br>
>>>>>> wrote:<br>
>>>>>>> It looks like I can not reproduce it on osx (non-arm)... :(<br>
>>>>>>>> On 09/08/17 22:54, Diana Picus wrote:<br>
>>>>>>>><br>
>>>>>>>> Reverting this also fixed the selfhost bots:<br>
>>>>>>>><br>
>>>>>>>><br>
>>>>>>>> <a href="http://lab.llvm.org:8011/builders/clang-cmake-thumbv7-a15-full-sh/builds/2142" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/<wbr>builders/clang-cmake-thumbv7-<wbr>a15-full-sh/builds/2142</a><br>
>>>>>>>><br>
>>>>>>>><br>
>>>>>>>> <a href="http://lab.llvm.org:8011/builders/clang-cmake-armv7-a15-selfhost/builds/2309" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/<wbr>builders/clang-cmake-armv7-<wbr>a15-selfhost/builds/2309</a><br>
>>>>>>>><br>
>>>>>>>><br>
>>>>>>>> <a href="http://lab.llvm.org:8011/builders/clang-cmake-armv7-a15-selfhost-neon/builds/1819" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/<wbr>builders/clang-cmake-armv7-<wbr>a15-selfhost-neon/builds/1819</a><br>
>>>>>>>><br>
>>>>>>>> I'm afraid the logs for those look even less helpful.<br>
>>>>>>>><br>
>>>>>>>>> On 9 August 2017 at 16:17, Diana Picus <<a href="mailto:diana.picus@linaro.org">diana.picus@linaro.org</a>> wrote:<br>
>>>>>>>>><br>
>>>>>>>>> Hi,<br>
>>>>>>>>><br>
>>>>>>>>> See attached. FWIW, when I ran this on a very similar machine, I got<br>
>>>>>>>>> 194 failures, all of which went away after reverting. So there might<br>
>>>>>>>>> be something fishy going on.<br>
>>>>>>>>><br>
>>>>>>>>> Regards,<br>
>>>>>>>>> Diana<br>
>>>>>>>>><br>
>>>>>>>>> On 9 August 2017 at 15:02, Vassil Vassilev <<a href="mailto:v.g.vassilev@gmail.com">v.g.vassilev@gmail.com</a>><br>
>>>>>>>>> wrote:<br>
>>>>>>>>>><br>
>>>>>>>>>> Hi Diana,<br>
>>>>>>>>>><br>
>>>>>>>>>>   It seems the service is down. Could you send us the details of the<br>
>>>>>>>>>> failures (incl stack traces if any)<br>
>>>>>>>>>><br>
>>>>>>>>>> Many thanks,<br>
>>>>>>>>>> Vassil<br>
>>>>>>>>>><br>
>>>>>>>>>>> On 09/08/17 15:27, Diana Picus via cfe-commits wrote:<br>
>>>>>>>>>>><br>
>>>>>>>>>>> Hi Richard,<br>
>>>>>>>>>>><br>
>>>>>>>>>>> I'm sorry but I've reverted this in r310464 because it was breaking<br>
>>>>>>>>>>> some ASAN tests on this bot:<br>
>>>>>>>>>>><br>
>>>>>>>>>>><br>
>>>>>>>>>>> <a href="http://lab.llvm.org:8011/builders/clang-cmake-armv7-a15-full/builds/9452" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/<wbr>builders/clang-cmake-armv7-<wbr>a15-full/builds/9452</a><br>
>>>>>>>>>>><br>
>>>>>>>>>>> Please let me know if I can help debug this.<br>
>>>>>>>>>>><br>
>>>>>>>>>>> Cheers,<br>
>>>>>>>>>>> Diana<br>
>>>>>>>>>>><br>
>>>>>>>>>>> On 8 August 2017 at 21:14, Richard Smith via cfe-commits<br>
>>>>>>>>>>> <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
>>>>>>>>>>>><br>
>>>>>>>>>>>> I forgot to say:<br>
>>>>>>>>>>>><br>
>>>>>>>>>>>> Based on a patch by Vassil Vassilev, which was based on a patch by<br>
>>>>>>>>>>>> Bernd<br>
>>>>>>>>>>>> Schmidt, which was based on a patch by Reid Kleckner.<br>
>>>>>>>>>>>><br>
>>>>>>>>>>>> On 8 August 2017 at 12:12, Richard Smith via cfe-commits<br>
>>>>>>>>>>>> <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Author: rsmith<br>
>>>>>>>>>>>>> Date: Tue Aug  8 12:12:28 2017<br>
>>>>>>>>>>>>> New Revision: 310401<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=310401&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=310401&view=rev</a><br>
>>>>>>>>>>>>> Log:<br>
>>>>>>>>>>>>> PR19668, PR23034: Fix handling of move constructors and deleted<br>
>>>>>>>>>>>>> copy<br>
>>>>>>>>>>>>> constructors when deciding whether classes should be passed<br>
>>>>>>>>>>>>> indirectly.<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> This fixes ABI differences between Clang and GCC:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   * Previously, Clang ignored the move constructor when making<br>
>>>>>>>>>>>>> this<br>
>>>>>>>>>>>>>     determination. It now takes the move constructor into<br>
>>>>>>>>>>>>> account,<br>
>>>>>>>>>>>>> per<br>
>>>>>>>>>>>>>     <a href="https://github.com/itanium-cxx-abi/cxx-abi/pull/17" rel="noreferrer" target="_blank">https://github.com/itanium-<wbr>cxx-abi/cxx-abi/pull/17</a> (this<br>
>>>>>>>>>>>>> change<br>
>>>>>>>>>>>>> may<br>
>>>>>>>>>>>>>     seem recent, but the ABI change was agreed on the Itanium C++<br>
>>>>>>>>>>>>> ABI<br>
>>>>>>>>>>>>>     list a long time ago).<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   * Previously, Clang's behavior when the copy constructor was<br>
>>>>>>>>>>>>> deleted<br>
>>>>>>>>>>>>>     was unstable -- depending on whether the lazy declaration of<br>
>>>>>>>>>>>>> the<br>
>>>>>>>>>>>>>     copy constructor had been triggered, you might get different<br>
>>>>>>>>>>>>> behavior.<br>
>>>>>>>>>>>>>     We now eagerly declare the copy constructor whenever its<br>
>>>>>>>>>>>>> deletedness<br>
>>>>>>>>>>>>>     is unclear, and ignore deleted copy/move constructors when<br>
>>>>>>>>>>>>> looking<br>
>>>>>>>>>>>>> for<br>
>>>>>>>>>>>>>     a trivial such constructor.<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> This also fixes an ABI difference between Clang and MSVC:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   * If the copy constructor would be implicitly deleted (but has<br>
>>>>>>>>>>>>> not<br>
>>>>>>>>>>>>> been<br>
>>>>>>>>>>>>>     lazily declared yet), for instance because the class has an<br>
>>>>>>>>>>>>> rvalue<br>
>>>>>>>>>>>>>     reference member, we would pass it directly. We now pass such<br>
>>>>>>>>>>>>> a<br>
>>>>>>>>>>>>> class<br>
>>>>>>>>>>>>>     indirectly, matching MSVC.<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Modified:<br>
>>>>>>>>>>>>>      cfe/trunk/include/clang/AST/<wbr>DeclCXX.h<br>
>>>>>>>>>>>>>      cfe/trunk/lib/AST/ASTImporter.<wbr>cpp<br>
>>>>>>>>>>>>>      cfe/trunk/lib/AST/DeclCXX.cpp<br>
>>>>>>>>>>>>>      cfe/trunk/lib/CodeGen/<wbr>CGCXXABI.cpp<br>
>>>>>>>>>>>>>      cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp<br>
>>>>>>>>>>>>>      cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp<br>
>>>>>>>>>>>>>      cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp<br>
>>>>>>>>>>>>>      cfe/trunk/lib/Serialization/<wbr>ASTReaderDecl.cpp<br>
>>>>>>>>>>>>>      cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp<br>
>>>>>>>>>>>>>      cfe/trunk/test/CodeGenCXX/<wbr>uncopyable-args.cpp<br>
>>>>>>>>>>>>>      cfe/trunk/unittests/<wbr>ASTMatchers/<wbr>ASTMatchersNarrowingTest.cpp<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Modified: cfe/trunk/include/clang/AST/<wbr>DeclCXX.h<br>
>>>>>>>>>>>>> URL:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=310401&r1=310400&r2=310401&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/AST/DeclCXX.h?rev=<wbr>310401&r1=310400&r2=310401&<wbr>view=diff</a><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>>>>>>>>>>> --- cfe/trunk/include/clang/AST/<wbr>DeclCXX.h (original)<br>
>>>>>>>>>>>>> +++ cfe/trunk/include/clang/AST/<wbr>DeclCXX.h Tue Aug  8 12:12:28 2017<br>
>>>>>>>>>>>>> @@ -375,6 +375,7 @@ class CXXRecordDecl : public RecordDecl<br>
>>>>>>>>>>>>>       /// \brief These flags are \c true if a defaulted<br>
>>>>>>>>>>>>> corresponding<br>
>>>>>>>>>>>>> special<br>
>>>>>>>>>>>>>       /// member can't be fully analyzed without performing<br>
>>>>>>>>>>>>> overload<br>
>>>>>>>>>>>>> resolution.<br>
>>>>>>>>>>>>>       /// @{<br>
>>>>>>>>>>>>> +    unsigned NeedOverloadResolutionForCopyC<wbr>onstructor : 1;<br>
>>>>>>>>>>>>>       unsigned NeedOverloadResolutionForMoveC<wbr>onstructor : 1;<br>
>>>>>>>>>>>>>       unsigned NeedOverloadResolutionForMoveA<wbr>ssignment : 1;<br>
>>>>>>>>>>>>>       unsigned NeedOverloadResolutionForDestr<wbr>uctor : 1;<br>
>>>>>>>>>>>>> @@ -383,6 +384,7 @@ class CXXRecordDecl : public RecordDecl<br>
>>>>>>>>>>>>>       /// \brief These flags are \c true if an implicit defaulted<br>
>>>>>>>>>>>>> corresponding<br>
>>>>>>>>>>>>>       /// special member would be defined as deleted.<br>
>>>>>>>>>>>>>       /// @{<br>
>>>>>>>>>>>>> +    unsigned DefaultedCopyConstructorIsDele<wbr>ted : 1;<br>
>>>>>>>>>>>>>       unsigned DefaultedMoveConstructorIsDele<wbr>ted : 1;<br>
>>>>>>>>>>>>>       unsigned DefaultedMoveAssignmentIsDelet<wbr>ed : 1;<br>
>>>>>>>>>>>>>       unsigned DefaultedDestructorIsDeleted : 1;<br>
>>>>>>>>>>>>> @@ -415,6 +417,12 @@ class CXXRecordDecl : public RecordDecl<br>
>>>>>>>>>>>>>       /// constructor.<br>
>>>>>>>>>>>>>       unsigned HasDefaultedDefaultConstructor : 1;<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> +    /// \brief True if this class can be passed in a<br>
>>>>>>>>>>>>> non-address-preserving<br>
>>>>>>>>>>>>> +    /// fashion (such as in registers) according to the C++<br>
>>>>>>>>>>>>> language<br>
>>>>>>>>>>>>> rules.<br>
>>>>>>>>>>>>> +    /// This does not imply anything about how the ABI in use<br>
>>>>>>>>>>>>> will<br>
>>>>>>>>>>>>> actually<br>
>>>>>>>>>>>>> +    /// pass an object of this class.<br>
>>>>>>>>>>>>> +    unsigned CanPassInRegisters : 1;<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>>       /// \brief True if a defaulted default constructor for this<br>
>>>>>>>>>>>>> class<br>
>>>>>>>>>>>>> would<br>
>>>>>>>>>>>>>       /// be constexpr.<br>
>>>>>>>>>>>>>       unsigned DefaultedDefaultConstructorIsC<wbr>onstexpr : 1;<br>
>>>>>>>>>>>>> @@ -811,18 +819,50 @@ public:<br>
>>>>>>>>>>>>>       return data().FirstFriend.isValid();<br>
>>>>>>>>>>>>>     }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> +  /// \brief \c true if a defaulted copy constructor for this<br>
>>>>>>>>>>>>> class<br>
>>>>>>>>>>>>> would<br>
>>>>>>>>>>>>> be<br>
>>>>>>>>>>>>> +  /// deleted.<br>
>>>>>>>>>>>>> +  bool defaultedCopyConstructorIsDele<wbr>ted() const {<br>
>>>>>>>>>>>>> +    assert((!<wbr>needsOverloadResolutionForCopy<wbr>Constructor() ||<br>
>>>>>>>>>>>>> +            (data().DeclaredSpecialMembers &<br>
>>>>>>>>>>>>> SMF_CopyConstructor))<br>
>>>>>>>>>>>>> &&<br>
>>>>>>>>>>>>> +           "this property has not yet been computed by Sema");<br>
>>>>>>>>>>>>> +    return data().<wbr>DefaultedCopyConstructorIsDele<wbr>ted;<br>
>>>>>>>>>>>>> +  }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +  /// \brief \c true if a defaulted move constructor for this<br>
>>>>>>>>>>>>> class<br>
>>>>>>>>>>>>> would<br>
>>>>>>>>>>>>> be<br>
>>>>>>>>>>>>> +  /// deleted.<br>
>>>>>>>>>>>>> +  bool defaultedMoveConstructorIsDele<wbr>ted() const {<br>
>>>>>>>>>>>>> +    assert((!<wbr>needsOverloadResolutionForMove<wbr>Constructor() ||<br>
>>>>>>>>>>>>> +            (data().DeclaredSpecialMembers &<br>
>>>>>>>>>>>>> SMF_MoveConstructor))<br>
>>>>>>>>>>>>> &&<br>
>>>>>>>>>>>>> +           "this property has not yet been computed by Sema");<br>
>>>>>>>>>>>>> +    return data().<wbr>DefaultedMoveConstructorIsDele<wbr>ted;<br>
>>>>>>>>>>>>> +  }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +  /// \brief \c true if a defaulted destructor for this class<br>
>>>>>>>>>>>>> would<br>
>>>>>>>>>>>>> be<br>
>>>>>>>>>>>>> deleted.<br>
>>>>>>>>>>>>> +  bool defaultedDestructorIsDeleted() const {<br>
>>>>>>>>>>>>> +    return !data().<wbr>DefaultedDestructorIsDeleted;<br>
>>>>>>>>>>>>> +  }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +  /// \brief \c true if we know for sure that this class has a<br>
>>>>>>>>>>>>> single,<br>
>>>>>>>>>>>>> +  /// accessible, unambiguous copy constructor that is not<br>
>>>>>>>>>>>>> deleted.<br>
>>>>>>>>>>>>> +  bool hasSimpleCopyConstructor() const {<br>
>>>>>>>>>>>>> +    return !<wbr>hasUserDeclaredCopyConstructor<wbr>() &&<br>
>>>>>>>>>>>>> +           !data().<wbr>DefaultedCopyConstructorIsDele<wbr>ted;<br>
>>>>>>>>>>>>> +  }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>>     /// \brief \c true if we know for sure that this class has a<br>
>>>>>>>>>>>>> single,<br>
>>>>>>>>>>>>>     /// accessible, unambiguous move constructor that is not<br>
>>>>>>>>>>>>> deleted.<br>
>>>>>>>>>>>>>     bool hasSimpleMoveConstructor() const {<br>
>>>>>>>>>>>>>       return !<wbr>hasUserDeclaredMoveConstructor<wbr>() &&<br>
>>>>>>>>>>>>> hasMoveConstructor()<br>
>>>>>>>>>>>>> &&<br>
>>>>>>>>>>>>>              !data().<wbr>DefaultedMoveConstructorIsDele<wbr>ted;<br>
>>>>>>>>>>>>>     }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>>     /// \brief \c true if we know for sure that this class has a<br>
>>>>>>>>>>>>> single,<br>
>>>>>>>>>>>>>     /// accessible, unambiguous move assignment operator that is<br>
>>>>>>>>>>>>> not<br>
>>>>>>>>>>>>> deleted.<br>
>>>>>>>>>>>>>     bool hasSimpleMoveAssignment() const {<br>
>>>>>>>>>>>>>       return !<wbr>hasUserDeclaredMoveAssignment(<wbr>) &&<br>
>>>>>>>>>>>>> hasMoveAssignment()<br>
>>>>>>>>>>>>> &&<br>
>>>>>>>>>>>>>              !data().<wbr>DefaultedMoveAssignmentIsDelet<wbr>ed;<br>
>>>>>>>>>>>>>     }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>>     /// \brief \c true if we know for sure that this class has an<br>
>>>>>>>>>>>>> accessible<br>
>>>>>>>>>>>>>     /// destructor that is not deleted.<br>
>>>>>>>>>>>>>     bool hasSimpleDestructor() const {<br>
>>>>>>>>>>>>> @@ -878,7 +918,16 @@ public:<br>
>>>>>>>>>>>>>     /// \brief Determine whether we need to eagerly declare a<br>
>>>>>>>>>>>>> defaulted<br>
>>>>>>>>>>>>> copy<br>
>>>>>>>>>>>>>     /// constructor for this class.<br>
>>>>>>>>>>>>>     bool needsOverloadResolutionForCopy<wbr>Constructor() const {<br>
>>>>>>>>>>>>> -    return data().HasMutableFields;<br>
>>>>>>>>>>>>> +    // C++17 [class.copy.ctor]p6:<br>
>>>>>>>>>>>>> +    //   If the class definition declares a move constructor or<br>
>>>>>>>>>>>>> move<br>
>>>>>>>>>>>>> assignment<br>
>>>>>>>>>>>>> +    //   operator, the implicitly declared copy constructor is<br>
>>>>>>>>>>>>> defined<br>
>>>>>>>>>>>>> as<br>
>>>>>>>>>>>>> +    //   deleted.<br>
>>>>>>>>>>>>> +    // In MSVC mode, sometimes a declared move assignment does<br>
>>>>>>>>>>>>> not<br>
>>>>>>>>>>>>> delete<br>
>>>>>>>>>>>>> an<br>
>>>>>>>>>>>>> +    // implicit copy constructor, so defer this choice to Sema.<br>
>>>>>>>>>>>>> +    if (data().<wbr>UserDeclaredSpecialMembers &<br>
>>>>>>>>>>>>> +        (SMF_MoveConstructor | SMF_MoveAssignment))<br>
>>>>>>>>>>>>> +      return true;<br>
>>>>>>>>>>>>> +    return data().<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor;<br>
>>>>>>>>>>>>>     }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>     /// \brief Determine whether an implicit copy constructor for<br>
>>>>>>>>>>>>> this<br>
>>>>>>>>>>>>> type<br>
>>>>>>>>>>>>> @@ -919,7 +968,16 @@ public:<br>
>>>>>>>>>>>>>              needsImplicitMoveConstructor()<wbr>;<br>
>>>>>>>>>>>>>     }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> -  /// \brief Set that we attempted to declare an implicitly move<br>
>>>>>>>>>>>>> +  /// \brief Set that we attempted to declare an implicit copy<br>
>>>>>>>>>>>>> +  /// constructor, but overload resolution failed so we deleted<br>
>>>>>>>>>>>>> it.<br>
>>>>>>>>>>>>> +  void setImplicitCopyConstructorIsDe<wbr>leted() {<br>
>>>>>>>>>>>>> +    assert((data().<wbr>DefaultedCopyConstructorIsDele<wbr>ted ||<br>
>>>>>>>>>>>>> +            needsOverloadResolutionForCopy<wbr>Constructor()) &&<br>
>>>>>>>>>>>>> +           "Copy constructor should not be deleted");<br>
>>>>>>>>>>>>> +    data().<wbr>DefaultedCopyConstructorIsDele<wbr>ted = true;<br>
>>>>>>>>>>>>> +  }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +  /// \brief Set that we attempted to declare an implicit move<br>
>>>>>>>>>>>>>     /// constructor, but overload resolution failed so we deleted<br>
>>>>>>>>>>>>> it.<br>
>>>>>>>>>>>>>     void setImplicitMoveConstructorIsDe<wbr>leted() {<br>
>>>>>>>>>>>>>       assert((data().<wbr>DefaultedMoveConstructorIsDele<wbr>ted ||<br>
>>>>>>>>>>>>> @@ -1316,6 +1374,18 @@ public:<br>
>>>>>>>>>>>>>       return data().<wbr>HasIrrelevantDestructor;<br>
>>>>>>>>>>>>>     }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> +  /// \brief Determine whether this class has at least one<br>
>>>>>>>>>>>>> trivial,<br>
>>>>>>>>>>>>> non-deleted<br>
>>>>>>>>>>>>> +  /// copy or move constructor.<br>
>>>>>>>>>>>>> +  bool canPassInRegisters() const {<br>
>>>>>>>>>>>>> +    return data().CanPassInRegisters;<br>
>>>>>>>>>>>>> +  }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +  /// \brief Set that we can pass this RecordDecl in registers.<br>
>>>>>>>>>>>>> +  // FIXME: This should be set as part of completeDefinition.<br>
>>>>>>>>>>>>> +  void setCanPassInRegisters(bool CanPass) {<br>
>>>>>>>>>>>>> +    data().CanPassInRegisters = CanPass;<br>
>>>>>>>>>>>>> +  }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>>     /// \brief Determine whether this class has a non-literal or/<br>
>>>>>>>>>>>>> volatile<br>
>>>>>>>>>>>>> type<br>
>>>>>>>>>>>>>     /// non-static data member or base class.<br>
>>>>>>>>>>>>>     bool hasNonLiteralTypeFieldsOrBases<wbr>() const {<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Modified: cfe/trunk/lib/AST/ASTImporter.<wbr>cpp<br>
>>>>>>>>>>>>> URL:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=310401&r1=310400&r2=310401&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>ASTImporter.cpp?rev=310401&r1=<wbr>310400&r2=310401&view=diff</a><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>>>>>>>>>>> --- cfe/trunk/lib/AST/ASTImporter.<wbr>cpp (original)<br>
>>>>>>>>>>>>> +++ cfe/trunk/lib/AST/ASTImporter.<wbr>cpp Tue Aug  8 12:12:28 2017<br>
>>>>>>>>>>>>> @@ -956,12 +956,16 @@ bool ASTNodeImporter::<wbr>ImportDefinition(R<br>
>>>>>>>>>>>>>       ToData.HasUninitializedFields =<br>
>>>>>>>>>>>>> FromData.<wbr>HasUninitializedFields;<br>
>>>>>>>>>>>>>       ToData.HasInheritedConstructor =<br>
>>>>>>>>>>>>> FromData.<wbr>HasInheritedConstructor;<br>
>>>>>>>>>>>>>       ToData.HasInheritedAssignment =<br>
>>>>>>>>>>>>> FromData.<wbr>HasInheritedAssignment;<br>
>>>>>>>>>>>>> +    ToData.<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor<br>
>>>>>>>>>>>>> +      = FromData.<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor;<br>
>>>>>>>>>>>>>       ToData.<wbr>NeedOverloadResolutionForMoveC<wbr>onstructor<br>
>>>>>>>>>>>>>         = FromData.<wbr>NeedOverloadResolutionForMoveC<wbr>onstructor;<br>
>>>>>>>>>>>>>       ToData.<wbr>NeedOverloadResolutionForMoveA<wbr>ssignment<br>
>>>>>>>>>>>>>         = FromData.<wbr>NeedOverloadResolutionForMoveA<wbr>ssignment;<br>
>>>>>>>>>>>>>       ToData.<wbr>NeedOverloadResolutionForDestr<wbr>uctor<br>
>>>>>>>>>>>>>         = FromData.<wbr>NeedOverloadResolutionForDestr<wbr>uctor;<br>
>>>>>>>>>>>>> +    ToData.<wbr>DefaultedCopyConstructorIsDele<wbr>ted<br>
>>>>>>>>>>>>> +      = FromData.<wbr>DefaultedCopyConstructorIsDele<wbr>ted;<br>
>>>>>>>>>>>>>       ToData.<wbr>DefaultedMoveConstructorIsDele<wbr>ted<br>
>>>>>>>>>>>>>         = FromData.<wbr>DefaultedMoveConstructorIsDele<wbr>ted;<br>
>>>>>>>>>>>>>       ToData.<wbr>DefaultedMoveAssignmentIsDelet<wbr>ed<br>
>>>>>>>>>>>>> @@ -973,6 +977,7 @@ bool ASTNodeImporter::<wbr>ImportDefinition(R<br>
>>>>>>>>>>>>>         = FromData.<wbr>HasConstexprNonCopyMoveConstru<wbr>ctor;<br>
>>>>>>>>>>>>>       ToData.<wbr>HasDefaultedDefaultConstructor<br>
>>>>>>>>>>>>>         = FromData.<wbr>HasDefaultedDefaultConstructor<wbr>;<br>
>>>>>>>>>>>>> +    ToData.CanPassInRegisters = FromData.CanPassInRegisters;<br>
>>>>>>>>>>>>>       ToData.<wbr>DefaultedDefaultConstructorIsC<wbr>onstexpr<br>
>>>>>>>>>>>>>         = FromData.<wbr>DefaultedDefaultConstructorIsC<wbr>onstexpr;<br>
>>>>>>>>>>>>>       ToData.<wbr>HasConstexprDefaultConstructor<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Modified: cfe/trunk/lib/AST/DeclCXX.cpp<br>
>>>>>>>>>>>>> URL:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=310401&r1=310400&r2=310401&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>DeclCXX.cpp?rev=310401&r1=<wbr>310400&r2=310401&view=diff</a><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>>>>>>>>>>> --- cfe/trunk/lib/AST/DeclCXX.cpp (original)<br>
>>>>>>>>>>>>> +++ cfe/trunk/lib/AST/DeclCXX.cpp Tue Aug  8 12:12:28 2017<br>
>>>>>>>>>>>>> @@ -55,15 +55,18 @@ CXXRecordDecl::DefinitionData:<wbr>:Definitio<br>
>>>>>>>>>>>>>         HasOnlyCMembers(true), HasInClassInitializer(false),<br>
>>>>>>>>>>>>>         HasUninitializedReferenceMembe<wbr>r(false),<br>
>>>>>>>>>>>>> HasUninitializedFields(false),<br>
>>>>>>>>>>>>>         HasInheritedConstructor(false)<wbr>,<br>
>>>>>>>>>>>>> HasInheritedAssignment(false),<br>
>>>>>>>>>>>>> +      NeedOverloadResolutionForCopyC<wbr>onstructor(false),<br>
>>>>>>>>>>>>>         NeedOverloadResolutionForMoveC<wbr>onstructor(false),<br>
>>>>>>>>>>>>>         NeedOverloadResolutionForMoveA<wbr>ssignment(false),<br>
>>>>>>>>>>>>>         NeedOverloadResolutionForDestr<wbr>uctor(false),<br>
>>>>>>>>>>>>> +      DefaultedCopyConstructorIsDele<wbr>ted(false),<br>
>>>>>>>>>>>>>         DefaultedMoveConstructorIsDele<wbr>ted(false),<br>
>>>>>>>>>>>>>         DefaultedMoveAssignmentIsDelet<wbr>ed(false),<br>
>>>>>>>>>>>>>         DefaultedDestructorIsDeleted(<wbr>false),<br>
>>>>>>>>>>>>> HasTrivialSpecialMembers(SMF_<wbr>All),<br>
>>>>>>>>>>>>>         DeclaredNonTrivialSpecialMembe<wbr>rs(0),<br>
>>>>>>>>>>>>> HasIrrelevantDestructor(true),<br>
>>>>>>>>>>>>>         HasConstexprNonCopyMoveConstru<wbr>ctor(false),<br>
>>>>>>>>>>>>>         HasDefaultedDefaultConstructor<wbr>(false),<br>
>>>>>>>>>>>>> +      CanPassInRegisters(false),<br>
>>>>>>>>>>>>>         DefaultedDefaultConstructorIsC<wbr>onstexpr(true),<br>
>>>>>>>>>>>>>         HasConstexprDefaultConstructor<wbr>(false),<br>
>>>>>>>>>>>>>         HasNonLiteralTypeFieldsOrBases<wbr>(false),<br>
>>>>>>>>>>>>> ComputedVisibleConversions(<wbr>false),<br>
>>>>>>>>>>>>> @@ -352,8 +355,10 @@ CXXRecordDecl::setBases(<wbr>CXXBaseSpecifier<br>
>>>>>>>>>>>>>         setHasVolatileMember(true);<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>       // Keep track of the presence of mutable fields.<br>
>>>>>>>>>>>>> -    if (BaseClassDecl-><wbr>hasMutableFields())<br>
>>>>>>>>>>>>> +    if (BaseClassDecl-><wbr>hasMutableFields()) {<br>
>>>>>>>>>>>>>         data().HasMutableFields = true;<br>
>>>>>>>>>>>>> +      data().<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor = true;<br>
>>>>>>>>>>>>> +    }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>       if (BaseClassDecl-><wbr>hasUninitializedReferenceMembe<wbr>r())<br>
>>>>>>>>>>>>>         data().<wbr>HasUninitializedReferenceMembe<wbr>r = true;<br>
>>>>>>>>>>>>> @@ -406,6 +411,8 @@ void CXXRecordDecl::<wbr>addedClassSubobject(<br>
>>>>>>>>>>>>>     //    -- a direct or virtual base class B that cannot be<br>
>>>>>>>>>>>>> copied/moved<br>
>>>>>>>>>>>>> [...]<br>
>>>>>>>>>>>>>     //    -- a non-static data member of class type M (or array<br>
>>>>>>>>>>>>> thereof)<br>
>>>>>>>>>>>>>     //       that cannot be copied or moved [...]<br>
>>>>>>>>>>>>> +  if (!Subobj-><wbr>hasSimpleCopyConstructor())<br>
>>>>>>>>>>>>> +    data().<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor = true;<br>
>>>>>>>>>>>>>     if (!Subobj-><wbr>hasSimpleMoveConstructor())<br>
>>>>>>>>>>>>>       data().<wbr>NeedOverloadResolutionForMoveC<wbr>onstructor = true;<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @@ -426,6 +433,7 @@ void CXXRecordDecl::<wbr>addedClassSubobject(<br>
>>>>>>>>>>>>>     //    -- any non-static data member has a type with a<br>
>>>>>>>>>>>>> destructor<br>
>>>>>>>>>>>>>     //       that is deleted or inaccessible from the defaulted<br>
>>>>>>>>>>>>> [ctor or<br>
>>>>>>>>>>>>> dtor].<br>
>>>>>>>>>>>>>     if (!Subobj->hasSimpleDestructor(<wbr>)) {<br>
>>>>>>>>>>>>> +    data().<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor = true;<br>
>>>>>>>>>>>>>       data().<wbr>NeedOverloadResolutionForMoveC<wbr>onstructor = true;<br>
>>>>>>>>>>>>>       data().<wbr>NeedOverloadResolutionForDestr<wbr>uctor = true;<br>
>>>>>>>>>>>>>     }<br>
>>>>>>>>>>>>> @@ -711,8 +719,10 @@ void CXXRecordDecl::addedMember(<wbr>Decl *D)<br>
>>>>>>>>>>>>>         data().IsStandardLayout = false;<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>       // Keep track of the presence of mutable fields.<br>
>>>>>>>>>>>>> -    if (Field->isMutable())<br>
>>>>>>>>>>>>> +    if (Field->isMutable()) {<br>
>>>>>>>>>>>>>         data().HasMutableFields = true;<br>
>>>>>>>>>>>>> +      data().<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor = true;<br>
>>>>>>>>>>>>> +    }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>       // C++11 [class.union]p8, DR1460:<br>
>>>>>>>>>>>>>       //   If X is a union, a non-static data member of X that is<br>
>>>>>>>>>>>>> not an<br>
>>>>>>>>>>>>> anonymous<br>
>>>>>>>>>>>>> @@ -756,6 +766,12 @@ void CXXRecordDecl::addedMember(<wbr>Decl *D)<br>
>>>>>>>>>>>>>         //   A standard-layout class is a class that:<br>
>>>>>>>>>>>>>         //    -- has no non-static data members of type [...]<br>
>>>>>>>>>>>>> reference,<br>
>>>>>>>>>>>>>         data().IsStandardLayout = false;<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +      // C++1z [class.copy.ctor]p10:<br>
>>>>>>>>>>>>> +      //   A defaulted copy constructor for a class X is defined<br>
>>>>>>>>>>>>> as<br>
>>>>>>>>>>>>> deleted if X has:<br>
>>>>>>>>>>>>> +      //    -- a non-static data member of rvalue reference type<br>
>>>>>>>>>>>>> +      if (T->isRValueReferenceType())<br>
>>>>>>>>>>>>> +        data().<wbr>DefaultedCopyConstructorIsDele<wbr>ted = true;<br>
>>>>>>>>>>>>>       }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>       if (!Field-><wbr>hasInClassInitializer() && !Field->isMutable())<br>
>>>>>>>>>>>>> {<br>
>>>>>>>>>>>>> @@ -809,6 +825,10 @@ void CXXRecordDecl::addedMember(<wbr>Decl *D)<br>
>>>>>>>>>>>>>           // We may need to perform overload resolution to<br>
>>>>>>>>>>>>> determine<br>
>>>>>>>>>>>>> whether a<br>
>>>>>>>>>>>>>           // field can be moved if it's const or volatile<br>
>>>>>>>>>>>>> qualified.<br>
>>>>>>>>>>>>>           if (T.getCVRQualifiers() & (Qualifiers::Const |<br>
>>>>>>>>>>>>> Qualifiers::Volatile)) {<br>
>>>>>>>>>>>>> +          // We need to care about 'const' for the copy<br>
>>>>>>>>>>>>> constructor<br>
>>>>>>>>>>>>> because an<br>
>>>>>>>>>>>>> +          // implicit copy constructor might be declared with a<br>
>>>>>>>>>>>>> non-const<br>
>>>>>>>>>>>>> +          // parameter.<br>
>>>>>>>>>>>>> +          data().<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor = true;<br>
>>>>>>>>>>>>>             data().<wbr>NeedOverloadResolutionForMoveC<wbr>onstructor =<br>
>>>>>>>>>>>>> true;<br>
>>>>>>>>>>>>>             data().<wbr>NeedOverloadResolutionForMoveA<wbr>ssignment =<br>
>>>>>>>>>>>>> true;<br>
>>>>>>>>>>>>>           }<br>
>>>>>>>>>>>>> @@ -819,6 +839,8 @@ void CXXRecordDecl::addedMember(<wbr>Decl *D)<br>
>>>>>>>>>>>>>           //    -- X is a union-like class that has a variant<br>
>>>>>>>>>>>>> member<br>
>>>>>>>>>>>>> with a<br>
>>>>>>>>>>>>>           //       non-trivial [corresponding special member]<br>
>>>>>>>>>>>>>           if (isUnion()) {<br>
>>>>>>>>>>>>> +          if (FieldRec-><wbr>hasNonTrivialCopyConstructor()<wbr>)<br>
>>>>>>>>>>>>> +            data().<wbr>DefaultedCopyConstructorIsDele<wbr>ted = true;<br>
>>>>>>>>>>>>>             if (FieldRec-><wbr>hasNonTrivialMoveConstructor()<wbr>)<br>
>>>>>>>>>>>>>               data().<wbr>DefaultedMoveConstructorIsDele<wbr>ted = true;<br>
>>>>>>>>>>>>>             if (FieldRec-><wbr>hasNonTrivialMoveAssignment())<br>
>>>>>>>>>>>>> @@ -830,6 +852,8 @@ void CXXRecordDecl::addedMember(<wbr>Decl *D)<br>
>>>>>>>>>>>>>           // For an anonymous union member, our overload<br>
>>>>>>>>>>>>> resolution<br>
>>>>>>>>>>>>> will<br>
>>>>>>>>>>>>> perform<br>
>>>>>>>>>>>>>           // overload resolution for its members.<br>
>>>>>>>>>>>>>           if (Field-><wbr>isAnonymousStructOrUnion()) {<br>
>>>>>>>>>>>>> +          data().<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor |=<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> FieldRec->data().<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor;<br>
>>>>>>>>>>>>>             data().<wbr>NeedOverloadResolutionForMoveC<wbr>onstructor |=<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> FieldRec->data().<wbr>NeedOverloadResolutionForMoveC<wbr>onstructor;<br>
>>>>>>>>>>>>>             data().<wbr>NeedOverloadResolutionForMoveA<wbr>ssignment |=<br>
>>>>>>>>>>>>> @@ -915,8 +939,10 @@ void CXXRecordDecl::addedMember(<wbr>Decl *D)<br>
>>>>>>>>>>>>>           }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>           // Keep track of the presence of mutable fields.<br>
>>>>>>>>>>>>> -        if (FieldRec->hasMutableFields())<br>
>>>>>>>>>>>>> +        if (FieldRec->hasMutableFields()) {<br>
>>>>>>>>>>>>>             data().HasMutableFields = true;<br>
>>>>>>>>>>>>> +          data().<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor = true;<br>
>>>>>>>>>>>>> +        }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>           // C++11 [class.copy]p13:<br>
>>>>>>>>>>>>>           //   If the implicitly-defined constructor would<br>
>>>>>>>>>>>>> satisfy<br>
>>>>>>>>>>>>> the<br>
>>>>>>>>>>>>> @@ -1450,7 +1476,7 @@ void CXXRecordDecl::<wbr>completeDefinition()<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   void CXXRecordDecl::<wbr>completeDefinition(<wbr>CXXFinalOverriderMap<br>
>>>>>>>>>>>>> *FinalOverriders) {<br>
>>>>>>>>>>>>>     RecordDecl::<wbr>completeDefinition();<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>>     // If the class may be abstract (but hasn't been marked as<br>
>>>>>>>>>>>>> such),<br>
>>>>>>>>>>>>> check<br>
>>>>>>>>>>>>> for<br>
>>>>>>>>>>>>>     // any pure final overriders.<br>
>>>>>>>>>>>>>     if (mayBeAbstract()) {<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Modified: cfe/trunk/lib/CodeGen/<wbr>CGCXXABI.cpp<br>
>>>>>>>>>>>>> URL:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.cpp?rev=310401&r1=310400&r2=310401&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>CGCXXABI.cpp?rev=310401&r1=<wbr>310400&r2=310401&view=diff</a><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>>>>>>>>>>> --- cfe/trunk/lib/CodeGen/<wbr>CGCXXABI.cpp (original)<br>
>>>>>>>>>>>>> +++ cfe/trunk/lib/CodeGen/<wbr>CGCXXABI.cpp Tue Aug  8 12:12:28 2017<br>
>>>>>>>>>>>>> @@ -30,38 +30,9 @@ void CGCXXABI::ErrorUnsupportedABI(<wbr>CodeG<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   bool CGCXXABI::canCopyArgument(<wbr>const CXXRecordDecl *RD) const {<br>
>>>>>>>>>>>>> -  // If RD has a non-trivial move or copy constructor, we cannot<br>
>>>>>>>>>>>>> copy<br>
>>>>>>>>>>>>> the<br>
>>>>>>>>>>>>> -  // argument.<br>
>>>>>>>>>>>>> -  if (RD-><wbr>hasNonTrivialCopyConstructor() ||<br>
>>>>>>>>>>>>> RD-><wbr>hasNonTrivialMoveConstructor()<wbr>)<br>
>>>>>>>>>>>>> -    return false;<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> -  // If RD has a non-trivial destructor, we cannot copy the<br>
>>>>>>>>>>>>> argument.<br>
>>>>>>>>>>>>> -  if (RD->hasNonTrivialDestructor()<wbr>)<br>
>>>>>>>>>>>>> -    return false;<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>>     // We can only copy the argument if there exists at least one<br>
>>>>>>>>>>>>> trivial,<br>
>>>>>>>>>>>>>     // non-deleted copy or move constructor.<br>
>>>>>>>>>>>>> -  // FIXME: This assumes that all lazily declared copy and move<br>
>>>>>>>>>>>>> constructors are<br>
>>>>>>>>>>>>> -  // not deleted.  This assumption might not be true in some<br>
>>>>>>>>>>>>> corner<br>
>>>>>>>>>>>>> cases.<br>
>>>>>>>>>>>>> -  bool CopyDeleted = false;<br>
>>>>>>>>>>>>> -  bool MoveDeleted = false;<br>
>>>>>>>>>>>>> -  for (const CXXConstructorDecl *CD : RD->ctors()) {<br>
>>>>>>>>>>>>> -    if (CD->isCopyConstructor() || CD->isMoveConstructor()) {<br>
>>>>>>>>>>>>> -      assert(CD->isTrivial());<br>
>>>>>>>>>>>>> -      // We had at least one undeleted trivial copy or move ctor.<br>
>>>>>>>>>>>>> Return<br>
>>>>>>>>>>>>> -      // directly.<br>
>>>>>>>>>>>>> -      if (!CD->isDeleted())<br>
>>>>>>>>>>>>> -        return true;<br>
>>>>>>>>>>>>> -      if (CD->isCopyConstructor())<br>
>>>>>>>>>>>>> -        CopyDeleted = true;<br>
>>>>>>>>>>>>> -      else<br>
>>>>>>>>>>>>> -        MoveDeleted = true;<br>
>>>>>>>>>>>>> -    }<br>
>>>>>>>>>>>>> -  }<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> -  // If all trivial copy and move constructors are deleted, we<br>
>>>>>>>>>>>>> cannot<br>
>>>>>>>>>>>>> copy the<br>
>>>>>>>>>>>>> -  // argument.<br>
>>>>>>>>>>>>> -  return !(CopyDeleted && MoveDeleted);<br>
>>>>>>>>>>>>> +  return RD->canPassInRegisters();<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   llvm::Constant *CGCXXABI::<wbr>GetBogusMemberPointer(QualType T) {<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Modified: cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp<br>
>>>>>>>>>>>>> URL:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=310401&r1=310400&r2=310401&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp?rev=310401&<wbr>r1=310400&r2=310401&view=diff</a><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>>>>>>>>>>> --- cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp (original)<br>
>>>>>>>>>>>>> +++ cfe/trunk/lib/CodeGen/<wbr>ItaniumCXXABI.cpp Tue Aug  8 12:12:28<br>
>>>>>>>>>>>>> 2017<br>
>>>>>>>>>>>>> @@ -63,11 +63,8 @@ public:<br>
>>>>>>>>>>>>>     bool classifyReturnType(<wbr>CGFunctionInfo &FI) const override;<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>     RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const<br>
>>>>>>>>>>>>> override<br>
>>>>>>>>>>>>> {<br>
>>>>>>>>>>>>> -    // Structures with either a non-trivial destructor or a<br>
>>>>>>>>>>>>> non-trivial<br>
>>>>>>>>>>>>> -    // copy constructor are always indirect.<br>
>>>>>>>>>>>>> -    // FIXME: Use canCopyArgument() when it is fixed to handle<br>
>>>>>>>>>>>>> lazily<br>
>>>>>>>>>>>>> declared<br>
>>>>>>>>>>>>> -    // special members.<br>
>>>>>>>>>>>>> -    if (RD->hasNonTrivialDestructor() ||<br>
>>>>>>>>>>>>> RD-><wbr>hasNonTrivialCopyConstructor()<wbr>)<br>
>>>>>>>>>>>>> +    // If C++ prohibits us from making a copy, pass by address.<br>
>>>>>>>>>>>>> +    if (!canCopyArgument(RD))<br>
>>>>>>>>>>>>>         return RAA_Indirect;<br>
>>>>>>>>>>>>>       return RAA_Default;<br>
>>>>>>>>>>>>>     }<br>
>>>>>>>>>>>>> @@ -1014,10 +1011,8 @@ bool ItaniumCXXABI::<wbr>classifyReturnType(C<br>
>>>>>>>>>>>>>     if (!RD)<br>
>>>>>>>>>>>>>       return false;<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> -  // Return indirectly if we have a non-trivial copy ctor or<br>
>>>>>>>>>>>>> non-trivial<br>
>>>>>>>>>>>>> dtor.<br>
>>>>>>>>>>>>> -  // FIXME: Use canCopyArgument() when it is fixed to handle<br>
>>>>>>>>>>>>> lazily<br>
>>>>>>>>>>>>> declared<br>
>>>>>>>>>>>>> -  // special members.<br>
>>>>>>>>>>>>> -  if (RD->hasNonTrivialDestructor() ||<br>
>>>>>>>>>>>>> RD-><wbr>hasNonTrivialCopyConstructor()<wbr>) {<br>
>>>>>>>>>>>>> +  // If C++ prohibits us from making a copy, return by address.<br>
>>>>>>>>>>>>> +  if (!canCopyArgument(RD)) {<br>
>>>>>>>>>>>>>       auto Align =<br>
>>>>>>>>>>>>> CGM.getContext().<wbr>getTypeAlignInChars(FI.<wbr>getReturnType());<br>
>>>>>>>>>>>>>       FI.getReturnInfo() = ABIArgInfo::getIndirect(Align,<br>
>>>>>>>>>>>>> /*ByVal=*/false);<br>
>>>>>>>>>>>>>       return true;<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Modified: cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp<br>
>>>>>>>>>>>>> URL:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=310401&r1=310400&r2=310401&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp?rev=<wbr>310401&r1=310400&r2=310401&<wbr>view=diff</a><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>>>>>>>>>>> --- cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp (original)<br>
>>>>>>>>>>>>> +++ cfe/trunk/lib/CodeGen/<wbr>MicrosoftCXXABI.cpp Tue Aug  8 12:12:28<br>
>>>>>>>>>>>>> 2017<br>
>>>>>>>>>>>>> @@ -819,46 +819,44 @@ MicrosoftCXXABI::<wbr>getRecordArgABI(const C<br>
>>>>>>>>>>>>>       return RAA_Default;<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>     case llvm::Triple::x86_64:<br>
>>>>>>>>>>>>> -    // Win64 passes objects with non-trivial copy ctors<br>
>>>>>>>>>>>>> indirectly.<br>
>>>>>>>>>>>>> -    if (RD-><wbr>hasNonTrivialCopyConstructor()<wbr>)<br>
>>>>>>>>>>>>> -      return RAA_Indirect;<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> -    // If an object has a destructor, we'd really like to pass it<br>
>>>>>>>>>>>>> indirectly<br>
>>>>>>>>>>>>> +    // If a class has a destructor, we'd really like to pass it<br>
>>>>>>>>>>>>> indirectly<br>
>>>>>>>>>>>>>       // because it allows us to elide copies.  Unfortunately,<br>
>>>>>>>>>>>>> MSVC<br>
>>>>>>>>>>>>> makes<br>
>>>>>>>>>>>>> that<br>
>>>>>>>>>>>>>       // impossible for small types, which it will pass in a<br>
>>>>>>>>>>>>> single<br>
>>>>>>>>>>>>> register or<br>
>>>>>>>>>>>>>       // stack slot. Most objects with dtors are large-ish, so<br>
>>>>>>>>>>>>> handle<br>
>>>>>>>>>>>>> that<br>
>>>>>>>>>>>>> early.<br>
>>>>>>>>>>>>>       // We can't call out all large objects as being indirect<br>
>>>>>>>>>>>>> because<br>
>>>>>>>>>>>>> there are<br>
>>>>>>>>>>>>>       // multiple x64 calling conventions and the C++ ABI code<br>
>>>>>>>>>>>>> shouldn't<br>
>>>>>>>>>>>>> dictate<br>
>>>>>>>>>>>>>       // how we pass large POD types.<br>
>>>>>>>>>>>>> +    //<br>
>>>>>>>>>>>>> +    // Note: This permits small classes with nontrivial<br>
>>>>>>>>>>>>> destructors<br>
>>>>>>>>>>>>> to<br>
>>>>>>>>>>>>> be<br>
>>>>>>>>>>>>> +    // passed in registers, which is non-conforming.<br>
>>>>>>>>>>>>>       if (RD->hasNonTrivialDestructor() &&<br>
>>>>>>>>>>>>>           getContext().getTypeSize(RD-><wbr>getTypeForDecl()) > 64)<br>
>>>>>>>>>>>>>         return RAA_Indirect;<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> -    // If this is true, the implicit copy constructor that Sema<br>
>>>>>>>>>>>>> would<br>
>>>>>>>>>>>>> have<br>
>>>>>>>>>>>>> -    // created would not be deleted. FIXME: We should provide a<br>
>>>>>>>>>>>>> more<br>
>>>>>>>>>>>>> direct way<br>
>>>>>>>>>>>>> -    // for CodeGen to ask whether the constructor was deleted.<br>
>>>>>>>>>>>>> -    if (!RD-><wbr>hasUserDeclaredCopyConstructor<wbr>() &&<br>
>>>>>>>>>>>>> -        !RD-><wbr>hasUserDeclaredMoveConstructor<wbr>() &&<br>
>>>>>>>>>>>>> -        !RD-><wbr>needsOverloadResolutionForMove<wbr>Constructor() &&<br>
>>>>>>>>>>>>> -        !RD-><wbr>hasUserDeclaredMoveAssignment(<wbr>) &&<br>
>>>>>>>>>>>>> -        !RD-><wbr>needsOverloadResolutionForMove<wbr>Assignment())<br>
>>>>>>>>>>>>> -      return RAA_Default;<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> -    // Otherwise, Sema should have created an implicit copy<br>
>>>>>>>>>>>>> constructor<br>
>>>>>>>>>>>>> if<br>
>>>>>>>>>>>>> -    // needed.<br>
>>>>>>>>>>>>> -    assert(!RD-><wbr>needsImplicitCopyConstructor()<wbr>);<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> -    // We have to make sure the trivial copy constructor isn't<br>
>>>>>>>>>>>>> deleted.<br>
>>>>>>>>>>>>> -    for (const CXXConstructorDecl *CD : RD->ctors()) {<br>
>>>>>>>>>>>>> -      if (CD->isCopyConstructor()) {<br>
>>>>>>>>>>>>> -        assert(CD->isTrivial());<br>
>>>>>>>>>>>>> -        // We had at least one undeleted trivial copy ctor.<br>
>>>>>>>>>>>>> Return<br>
>>>>>>>>>>>>> directly.<br>
>>>>>>>>>>>>> -        if (!CD->isDeleted())<br>
>>>>>>>>>>>>> -          return RAA_Default;<br>
>>>>>>>>>>>>> +    // If a class has at least one non-deleted, trivial copy<br>
>>>>>>>>>>>>> constructor,<br>
>>>>>>>>>>>>> it<br>
>>>>>>>>>>>>> +    // is passed according to the C ABI. Otherwise, it is passed<br>
>>>>>>>>>>>>> indirectly.<br>
>>>>>>>>>>>>> +    //<br>
>>>>>>>>>>>>> +    // Note: This permits classes with non-trivial copy or move<br>
>>>>>>>>>>>>> ctors<br>
>>>>>>>>>>>>> to<br>
>>>>>>>>>>>>> be<br>
>>>>>>>>>>>>> +    // passed in registers, so long as they *also* have a trivial<br>
>>>>>>>>>>>>> copy<br>
>>>>>>>>>>>>> ctor,<br>
>>>>>>>>>>>>> +    // which is non-conforming.<br>
>>>>>>>>>>>>> +    if (RD-><wbr>needsImplicitCopyConstructor()<wbr>) {<br>
>>>>>>>>>>>>> +      // If the copy ctor has not yet been declared, we can read<br>
>>>>>>>>>>>>> its<br>
>>>>>>>>>>>>> triviality<br>
>>>>>>>>>>>>> +      // off the AST.<br>
>>>>>>>>>>>>> +      if (!RD-><wbr>defaultedCopyConstructorIsDele<wbr>ted() &&<br>
>>>>>>>>>>>>> +          RD->hasTrivialCopyConstructor(<wbr>))<br>
>>>>>>>>>>>>> +        return RAA_Default;<br>
>>>>>>>>>>>>> +    } else {<br>
>>>>>>>>>>>>> +      // Otherwise, we need to find the copy constructor(s) and<br>
>>>>>>>>>>>>> ask.<br>
>>>>>>>>>>>>> +      for (const CXXConstructorDecl *CD : RD->ctors()) {<br>
>>>>>>>>>>>>> +        if (CD->isCopyConstructor()) {<br>
>>>>>>>>>>>>> +          // We had at least one nondeleted trivial copy ctor.<br>
>>>>>>>>>>>>> Return<br>
>>>>>>>>>>>>> directly.<br>
>>>>>>>>>>>>> +          if (!CD->isDeleted() && CD->isTrivial())<br>
>>>>>>>>>>>>> +            return RAA_Default;<br>
>>>>>>>>>>>>> +        }<br>
>>>>>>>>>>>>>         }<br>
>>>>>>>>>>>>>       }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> -    // The trivial copy constructor was deleted.  Return<br>
>>>>>>>>>>>>> indirectly.<br>
>>>>>>>>>>>>> +    // We have no trivial, non-deleted copy constructor.<br>
>>>>>>>>>>>>>       return RAA_Indirect;<br>
>>>>>>>>>>>>>     }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Modified: cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp<br>
>>>>>>>>>>>>> URL:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=310401&r1=310400&r2=310401&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp?rev=310401&r1=<wbr>310400&r2=310401&view=diff</a><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>>>>>>>>>>> --- cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp (original)<br>
>>>>>>>>>>>>> +++ cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp Tue Aug  8 12:12:28 2017<br>
>>>>>>>>>>>>> @@ -5726,6 +5726,53 @@ static void DefineImplicitSpecialMember(<br>
>>>>>>>>>>>>>     }<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> +/// Determine whether a type is permitted to be passed or<br>
>>>>>>>>>>>>> returned<br>
>>>>>>>>>>>>> in<br>
>>>>>>>>>>>>> +/// registers, per C++ [class.temporary]p3.<br>
>>>>>>>>>>>>> +static bool computeCanPassInRegisters(Sema &S, CXXRecordDecl *D)<br>
>>>>>>>>>>>>> {<br>
>>>>>>>>>>>>> +  if (D->isDependentType() || D->isInvalidDecl())<br>
>>>>>>>>>>>>> +    return false;<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +  // Per C++ [class.temporary]p3, the relevant condition is:<br>
>>>>>>>>>>>>> +  //   each copy constructor, move constructor, and destructor of<br>
>>>>>>>>>>>>> X<br>
>>>>>>>>>>>>> is<br>
>>>>>>>>>>>>> +  //   either trivial or deleted, and X has at least one<br>
>>>>>>>>>>>>> non-deleted<br>
>>>>>>>>>>>>> copy<br>
>>>>>>>>>>>>> +  //   or move constructor<br>
>>>>>>>>>>>>> +  bool HasNonDeletedCopyOrMove = false;<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +  if (D-><wbr>needsImplicitCopyConstructor() &&<br>
>>>>>>>>>>>>> +      !D-><wbr>defaultedCopyConstructorIsDele<wbr>ted()) {<br>
>>>>>>>>>>>>> +    if (!D-><wbr>hasTrivialCopyConstructor())<br>
>>>>>>>>>>>>> +      return false;<br>
>>>>>>>>>>>>> +    HasNonDeletedCopyOrMove = true;<br>
>>>>>>>>>>>>> +  }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +  if (S.getLangOpts().CPlusPlus11 &&<br>
>>>>>>>>>>>>> D-><wbr>needsImplicitMoveConstructor()<br>
>>>>>>>>>>>>> &&<br>
>>>>>>>>>>>>> +      !D-><wbr>defaultedMoveConstructorIsDele<wbr>ted()) {<br>
>>>>>>>>>>>>> +    if (!D-><wbr>hasTrivialMoveConstructor())<br>
>>>>>>>>>>>>> +      return false;<br>
>>>>>>>>>>>>> +    HasNonDeletedCopyOrMove = true;<br>
>>>>>>>>>>>>> +  }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +  if (D->needsImplicitDestructor() &&<br>
>>>>>>>>>>>>> !D-><wbr>defaultedDestructorIsDeleted()<br>
>>>>>>>>>>>>> &&<br>
>>>>>>>>>>>>> +      !D->hasTrivialDestructor())<br>
>>>>>>>>>>>>> +    return false;<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +  for (const CXXMethodDecl *MD : D->methods()) {<br>
>>>>>>>>>>>>> +    if (MD->isDeleted())<br>
>>>>>>>>>>>>> +      continue;<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +    auto *CD = dyn_cast<CXXConstructorDecl>(<wbr>MD);<br>
>>>>>>>>>>>>> +    if (CD && CD->isCopyOrMoveConstructor())<br>
>>>>>>>>>>>>> +      HasNonDeletedCopyOrMove = true;<br>
>>>>>>>>>>>>> +    else if (!isa<CXXDestructorDecl>(MD))<br>
>>>>>>>>>>>>> +      continue;<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +    if (!MD->isTrivial())<br>
>>>>>>>>>>>>> +      return false;<br>
>>>>>>>>>>>>> +  }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +  return HasNonDeletedCopyOrMove;<br>
>>>>>>>>>>>>> +}<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>>   /// \brief Perform semantic checks on a class definition that<br>
>>>>>>>>>>>>> has<br>
>>>>>>>>>>>>> been<br>
>>>>>>>>>>>>>   /// completing, introducing implicitly-declared members,<br>
>>>>>>>>>>>>> checking<br>
>>>>>>>>>>>>> for<br>
>>>>>>>>>>>>>   /// abstract types, etc.<br>
>>>>>>>>>>>>> @@ -5870,6 +5917,8 @@ void Sema::CheckCompletedCXXClass(<wbr>CXXRec<br>
>>>>>>>>>>>>>     }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>     checkClassLevelDLLAttribute(<wbr>Record);<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +  Record->setCanPassInRegisters(<wbr>computeCanPassInRegisters(*<wbr>this,<br>
>>>>>>>>>>>>> Record));<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   /// Look up the special member function that would be called by<br>
>>>>>>>>>>>>> a<br>
>>>>>>>>>>>>> special<br>
>>>>>>>>>>>>> @@ -7496,8 +7545,7 @@ void Sema::<wbr>ActOnFinishCXXMemberSpecifica<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> reinterpret_cast<Decl**>(<wbr>FieldCollector->getCurFields()<wbr>),<br>
>>>>>>>>>>>>>                 FieldCollector-><wbr>getCurNumFields()), LBrac, RBrac,<br>
>>>>>>>>>>>>> AttrList);<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> -  CheckCompletedCXXClass(<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> dyn_cast_or_null<<wbr>CXXRecordDecl>(TagDecl));<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> CheckCompletedCXXClass(dyn_<wbr>cast_or_null<CXXRecordDecl>(<wbr>TagDecl));<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   /// AddImplicitlyDeclaredMembersTo<wbr>Class - Adds any<br>
>>>>>>>>>>>>> implicitly-declared<br>
>>>>>>>>>>>>> @@ -11929,8 +11977,10 @@ CXXConstructorDecl *Sema::DeclareImplici<br>
>>>>>>>>>>>>>     Scope *S = getScopeForContext(ClassDecl);<br>
>>>>>>>>>>>>>     CheckImplicitSpecialMemberDecl<wbr>aration(S, CopyConstructor);<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> -  if (ShouldDeleteSpecialMember(<wbr>CopyConstructor,<br>
>>>>>>>>>>>>> CXXCopyConstructor))<br>
>>>>>>>>>>>>> +  if (ShouldDeleteSpecialMember(<wbr>CopyConstructor,<br>
>>>>>>>>>>>>> CXXCopyConstructor)) {<br>
>>>>>>>>>>>>> +    ClassDecl-><wbr>setImplicitCopyConstructorIsDe<wbr>leted();<br>
>>>>>>>>>>>>>       SetDeclDeleted(<wbr>CopyConstructor, ClassLoc);<br>
>>>>>>>>>>>>> +  }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>     if (S)<br>
>>>>>>>>>>>>>       PushOnScopeChains(<wbr>CopyConstructor, S, false);<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Modified: cfe/trunk/lib/Serialization/<wbr>ASTReaderDecl.cpp<br>
>>>>>>>>>>>>> URL:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=310401&r1=310400&r2=310401&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Serialization/ASTReaderDecl.<wbr>cpp?rev=310401&r1=310400&r2=<wbr>310401&view=diff</a><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>>>>>>>>>>> --- cfe/trunk/lib/Serialization/<wbr>ASTReaderDecl.cpp (original)<br>
>>>>>>>>>>>>> +++ cfe/trunk/lib/Serialization/<wbr>ASTReaderDecl.cpp Tue Aug  8<br>
>>>>>>>>>>>>> 12:12:28<br>
>>>>>>>>>>>>> 2017<br>
>>>>>>>>>>>>> @@ -1559,9 +1559,11 @@ void ASTDeclReader::<wbr>ReadCXXDefinitionDat<br>
>>>>>>>>>>>>>     Data.HasUninitializedFields = Record.readInt();<br>
>>>>>>>>>>>>>     Data.HasInheritedConstructor = Record.readInt();<br>
>>>>>>>>>>>>>     Data.HasInheritedAssignment = Record.readInt();<br>
>>>>>>>>>>>>> +  Data.<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor =<br>
>>>>>>>>>>>>> Record.readInt();<br>
>>>>>>>>>>>>>     Data.<wbr>NeedOverloadResolutionForMoveC<wbr>onstructor =<br>
>>>>>>>>>>>>> Record.readInt();<br>
>>>>>>>>>>>>>     Data.<wbr>NeedOverloadResolutionForMoveA<wbr>ssignment =<br>
>>>>>>>>>>>>> Record.readInt();<br>
>>>>>>>>>>>>>     Data.<wbr>NeedOverloadResolutionForDestr<wbr>uctor = Record.readInt();<br>
>>>>>>>>>>>>> +  Data.<wbr>DefaultedCopyConstructorIsDele<wbr>ted = Record.readInt();<br>
>>>>>>>>>>>>>     Data.<wbr>DefaultedMoveConstructorIsDele<wbr>ted = Record.readInt();<br>
>>>>>>>>>>>>>     Data.<wbr>DefaultedMoveAssignmentIsDelet<wbr>ed = Record.readInt();<br>
>>>>>>>>>>>>>     Data.<wbr>DefaultedDestructorIsDeleted = Record.readInt();<br>
>>>>>>>>>>>>> @@ -1570,6 +1572,7 @@ void ASTDeclReader::<wbr>ReadCXXDefinitionDat<br>
>>>>>>>>>>>>>     Data.HasIrrelevantDestructor = Record.readInt();<br>
>>>>>>>>>>>>>     Data.<wbr>HasConstexprNonCopyMoveConstru<wbr>ctor = Record.readInt();<br>
>>>>>>>>>>>>>     Data.<wbr>HasDefaultedDefaultConstructor = Record.readInt();<br>
>>>>>>>>>>>>> +  Data.CanPassInRegisters = Record.readInt();<br>
>>>>>>>>>>>>>     Data.<wbr>DefaultedDefaultConstructorIsC<wbr>onstexpr =<br>
>>>>>>>>>>>>> Record.readInt();<br>
>>>>>>>>>>>>>     Data.<wbr>HasConstexprDefaultConstructor = Record.readInt();<br>
>>>>>>>>>>>>>     Data.<wbr>HasNonLiteralTypeFieldsOrBases = Record.readInt();<br>
>>>>>>>>>>>>> @@ -1697,9 +1700,11 @@ void ASTDeclReader::<wbr>MergeDefinitionData(<br>
>>>>>>>>>>>>>     MATCH_FIELD(<wbr>HasUninitializedFields)<br>
>>>>>>>>>>>>>     MATCH_FIELD(<wbr>HasInheritedConstructor)<br>
>>>>>>>>>>>>>     MATCH_FIELD(<wbr>HasInheritedAssignment)<br>
>>>>>>>>>>>>> +  MATCH_FIELD(<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor)<br>
>>>>>>>>>>>>>     MATCH_FIELD(<wbr>NeedOverloadResolutionForMoveC<wbr>onstructor)<br>
>>>>>>>>>>>>>     MATCH_FIELD(<wbr>NeedOverloadResolutionForMoveA<wbr>ssignment)<br>
>>>>>>>>>>>>>     MATCH_FIELD(<wbr>NeedOverloadResolutionForDestr<wbr>uctor)<br>
>>>>>>>>>>>>> +  MATCH_FIELD(<wbr>DefaultedCopyConstructorIsDele<wbr>ted)<br>
>>>>>>>>>>>>>     MATCH_FIELD(<wbr>DefaultedMoveConstructorIsDele<wbr>ted)<br>
>>>>>>>>>>>>>     MATCH_FIELD(<wbr>DefaultedMoveAssignmentIsDelet<wbr>ed)<br>
>>>>>>>>>>>>>     MATCH_FIELD(<wbr>DefaultedDestructorIsDeleted)<br>
>>>>>>>>>>>>> @@ -1708,6 +1713,7 @@ void ASTDeclReader::<wbr>MergeDefinitionData(<br>
>>>>>>>>>>>>>     MATCH_FIELD(<wbr>HasIrrelevantDestructor)<br>
>>>>>>>>>>>>>     OR_FIELD(<wbr>HasConstexprNonCopyMoveConstru<wbr>ctor)<br>
>>>>>>>>>>>>>     OR_FIELD(<wbr>HasDefaultedDefaultConstructor<wbr>)<br>
>>>>>>>>>>>>> +  MATCH_FIELD(<wbr>CanPassInRegisters)<br>
>>>>>>>>>>>>>     MATCH_FIELD(<wbr>DefaultedDefaultConstructorIsC<wbr>onstexpr)<br>
>>>>>>>>>>>>>     OR_FIELD(<wbr>HasConstexprDefaultConstructor<wbr>)<br>
>>>>>>>>>>>>>     MATCH_FIELD(<wbr>HasNonLiteralTypeFieldsOrBases<wbr>)<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Modified: cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp<br>
>>>>>>>>>>>>> URL:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=310401&r1=310400&r2=310401&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Serialization/ASTWriter.cpp?<wbr>rev=310401&r1=310400&r2=<wbr>310401&view=diff</a><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>>>>>>>>>>> --- cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp (original)<br>
>>>>>>>>>>>>> +++ cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp Tue Aug  8 12:12:28<br>
>>>>>>>>>>>>> 2017<br>
>>>>>>>>>>>>> @@ -5875,9 +5875,11 @@ void ASTRecordWriter::<wbr>AddCXXDefinitionDa<br>
>>>>>>>>>>>>>     Record->push_back(Data.<wbr>HasUninitializedFields);<br>
>>>>>>>>>>>>>     Record->push_back(Data.<wbr>HasInheritedConstructor);<br>
>>>>>>>>>>>>>     Record->push_back(Data.<wbr>HasInheritedAssignment);<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> Record->push_back(Data.<wbr>NeedOverloadResolutionForCopyC<wbr>onstructor);<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Record->push_back(Data.<wbr>NeedOverloadResolutionForMoveC<wbr>onstructor);<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Record->push_back(Data.<wbr>NeedOverloadResolutionForMoveA<wbr>ssignment);<br>
>>>>>>>>>>>>>     Record->push_back(Data.<wbr>NeedOverloadResolutionForDestr<wbr>uctor);<br>
>>>>>>>>>>>>> +  Record->push_back(Data.<wbr>DefaultedCopyConstructorIsDele<wbr>ted);<br>
>>>>>>>>>>>>>     Record->push_back(Data.<wbr>DefaultedMoveConstructorIsDele<wbr>ted);<br>
>>>>>>>>>>>>>     Record->push_back(Data.<wbr>DefaultedMoveAssignmentIsDelet<wbr>ed);<br>
>>>>>>>>>>>>>     Record->push_back(Data.<wbr>DefaultedDestructorIsDeleted);<br>
>>>>>>>>>>>>> @@ -5886,6 +5888,7 @@ void ASTRecordWriter::<wbr>AddCXXDefinitionDa<br>
>>>>>>>>>>>>>     Record->push_back(Data.<wbr>HasIrrelevantDestructor);<br>
>>>>>>>>>>>>>     Record->push_back(Data.<wbr>HasConstexprNonCopyMoveConstru<wbr>ctor);<br>
>>>>>>>>>>>>>     Record->push_back(Data.<wbr>HasDefaultedDefaultConstructor<wbr>);<br>
>>>>>>>>>>>>> +  Record->push_back(Data.<wbr>CanPassInRegisters);<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Record->push_back(Data.<wbr>DefaultedDefaultConstructorIsC<wbr>onstexpr);<br>
>>>>>>>>>>>>>     Record->push_back(Data.<wbr>HasConstexprDefaultConstructor<wbr>);<br>
>>>>>>>>>>>>>     Record->push_back(Data.<wbr>HasNonLiteralTypeFieldsOrBases<wbr>);<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Modified: cfe/trunk/test/CodeGenCXX/<wbr>uncopyable-args.cpp<br>
>>>>>>>>>>>>> URL:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/uncopyable-args.cpp?rev=310401&r1=310400&r2=310401&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>CodeGenCXX/uncopyable-args.<wbr>cpp?rev=310401&r1=310400&r2=<wbr>310401&view=diff</a><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>>>>>>>>>>> --- cfe/trunk/test/CodeGenCXX/<wbr>uncopyable-args.cpp (original)<br>
>>>>>>>>>>>>> +++ cfe/trunk/test/CodeGenCXX/<wbr>uncopyable-args.cpp Tue Aug  8<br>
>>>>>>>>>>>>> 12:12:28<br>
>>>>>>>>>>>>> 2017<br>
>>>>>>>>>>>>> @@ -1,5 +1,6 @@<br>
>>>>>>>>>>>>>   // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown<br>
>>>>>>>>>>>>> -emit-llvm<br>
>>>>>>>>>>>>> -o - %s | FileCheck %s<br>
>>>>>>>>>>>>> -// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc<br>
>>>>>>>>>>>>> -emit-llvm<br>
>>>>>>>>>>>>> -o<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> %s | FileCheck %s -check-prefix=WIN64<br>
>>>>>>>>>>>>> +// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc<br>
>>>>>>>>>>>>> -emit-llvm<br>
>>>>>>>>>>>>> -o<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> %s -fms-compatibility -fms-compatibility-version=18 | FileCheck %s<br>
>>>>>>>>>>>>> -check-prefix=WIN64 -check-prefix=WIN64-18<br>
>>>>>>>>>>>>> +// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc<br>
>>>>>>>>>>>>> -emit-llvm<br>
>>>>>>>>>>>>> -o<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> %s -fms-compatibility -fms-compatibility-version=19 | FileCheck %s<br>
>>>>>>>>>>>>> -check-prefix=WIN64 -check-prefix=WIN64-19<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   namespace trivial {<br>
>>>>>>>>>>>>>   // Trivial structs should be passed directly.<br>
>>>>>>>>>>>>> @@ -52,12 +53,11 @@ void foo(A);<br>
>>>>>>>>>>>>>   void bar() {<br>
>>>>>>>>>>>>>     foo({});<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>> -// FIXME: The copy ctor is implicitly deleted.<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: define void @_ZN9move_ctor3barEv()<br>
>>>>>>>>>>>>> -// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-NOT: call<br>
>>>>>>>>>>>>> -// CHECK-DISABLED: call void<br>
>>>>>>>>>>>>> @_ZN9move_ctor3fooENS_1AE(%"<wbr>struct.move_ctor::A"* %{{.*}})<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: declare void<br>
>>>>>>>>>>>>> @_ZN9move_ctor3fooENS_1AE(%"<wbr>struct.move_ctor::A"*)<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define void @_ZN9move_ctor3barEv()<br>
>>>>>>>>>>>>> +// CHECK: call void @_Z{{.*}}C1Ev(<br>
>>>>>>>>>>>>> +// CHECK-NOT: call<br>
>>>>>>>>>>>>> +// CHECK: call void<br>
>>>>>>>>>>>>> @_ZN9move_ctor3fooENS_1AE(%"<wbr>struct.move_ctor::A"*<br>
>>>>>>>>>>>>> %{{.*}})<br>
>>>>>>>>>>>>> +// CHECK-LABEL: declare void<br>
>>>>>>>>>>>>> @_ZN9move_ctor3fooENS_1AE(%"<wbr>struct.move_ctor::A"*)<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   // WIN64-LABEL: declare void<br>
>>>>>>>>>>>>> @"\01?foo@move_ctor@@YAXUA@1@@<wbr>Z"(%"struct.move_ctor::A"*)<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>> @@ -73,12 +73,11 @@ void foo(A);<br>
>>>>>>>>>>>>>   void bar() {<br>
>>>>>>>>>>>>>     foo({});<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>> -// FIXME: The copy ctor is deleted.<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: define void @_ZN11all_deleted3barEv()<br>
>>>>>>>>>>>>> -// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-NOT: call<br>
>>>>>>>>>>>>> -// CHECK-DISABLED: call void<br>
>>>>>>>>>>>>> @_ZN11all_deleted3fooENS_1AE(%<wbr>"struct.all_deleted::A"* %{{.*}})<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: declare void<br>
>>>>>>>>>>>>> @_ZN11all_deleted3fooENS_1AE(%<wbr>"struct.all_deleted::A"*)<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define void @_ZN11all_deleted3barEv()<br>
>>>>>>>>>>>>> +// CHECK: call void @_Z{{.*}}C1Ev(<br>
>>>>>>>>>>>>> +// CHECK-NOT: call<br>
>>>>>>>>>>>>> +// CHECK: call void<br>
>>>>>>>>>>>>> @_ZN11all_deleted3fooENS_1AE(%<wbr>"struct.all_deleted::A"* %{{.*}})<br>
>>>>>>>>>>>>> +// CHECK-LABEL: declare void<br>
>>>>>>>>>>>>> @_ZN11all_deleted3fooENS_1AE(%<wbr>"struct.all_deleted::A"*)<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   // WIN64-LABEL: declare void<br>
>>>>>>>>>>>>> @"\01?foo@all_deleted@@YAXUA@1<wbr>@@Z"(%"struct.all_deleted::A"*<wbr>)<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>> @@ -93,14 +92,15 @@ void foo(A);<br>
>>>>>>>>>>>>>   void bar() {<br>
>>>>>>>>>>>>>     foo({});<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>> -// FIXME: The copy and move ctors are implicitly deleted.<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: define void<br>
>>>>>>>>>>>>> @_ZN18implicitly_<wbr>deleted3barEv()<br>
>>>>>>>>>>>>> -// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-NOT: call<br>
>>>>>>>>>>>>> -// CHECK-DISABLED: call void<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @_ZN18implicitly_<wbr>deleted3fooENS_1AE(%"struct.<wbr>implicitly_deleted::A"*<br>
>>>>>>>>>>>>> %{{.*}})<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: declare void<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @_ZN18implicitly_<wbr>deleted3fooENS_1AE(%"struct.<wbr>implicitly_deleted::A"*)<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> -// WIN64-LABEL: declare void<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @"\01?foo@implicitly_deleted@@<wbr>YAXUA@1@@Z"(%"struct.<wbr>implicitly_deleted::A"*)<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define void @_ZN18implicitly_<wbr>deleted3barEv()<br>
>>>>>>>>>>>>> +// CHECK: call void @_Z{{.*}}C1Ev(<br>
>>>>>>>>>>>>> +// CHECK-NOT: call<br>
>>>>>>>>>>>>> +// CHECK: call void<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @_ZN18implicitly_<wbr>deleted3fooENS_1AE(%"struct.<wbr>implicitly_deleted::A"*<br>
>>>>>>>>>>>>> %{{.*}})<br>
>>>>>>>>>>>>> +// CHECK-LABEL: declare void<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @_ZN18implicitly_<wbr>deleted3fooENS_1AE(%"struct.<wbr>implicitly_deleted::A"*)<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +// In MSVC 2013, the copy ctor is not deleted by a move<br>
>>>>>>>>>>>>> assignment.<br>
>>>>>>>>>>>>> In<br>
>>>>>>>>>>>>> MSVC 2015, it is.<br>
>>>>>>>>>>>>> +// WIN64-18-LABEL: declare void<br>
>>>>>>>>>>>>> @"\01?foo@implicitly_deleted@@<wbr>YAXUA@1@@Z"(i64<br>
>>>>>>>>>>>>> +// WIN64-19-LABEL: declare void<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @"\01?foo@implicitly_deleted@@<wbr>YAXUA@1@@Z"(%"struct.<wbr>implicitly_deleted::A"*)<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   namespace one_deleted {<br>
>>>>>>>>>>>>> @@ -113,12 +113,11 @@ void foo(A);<br>
>>>>>>>>>>>>>   void bar() {<br>
>>>>>>>>>>>>>     foo({});<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>> -// FIXME: The copy constructor is implicitly deleted.<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: define void @_ZN11one_deleted3barEv()<br>
>>>>>>>>>>>>> -// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-NOT: call<br>
>>>>>>>>>>>>> -// CHECK-DISABLED: call void<br>
>>>>>>>>>>>>> @_ZN11one_deleted3fooENS_1AE(%<wbr>"struct.one_deleted::A"* %{{.*}})<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: declare void<br>
>>>>>>>>>>>>> @_ZN11one_deleted3fooENS_1AE(%<wbr>"struct.one_deleted::A"*)<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define void @_ZN11one_deleted3barEv()<br>
>>>>>>>>>>>>> +// CHECK: call void @_Z{{.*}}C1Ev(<br>
>>>>>>>>>>>>> +// CHECK-NOT: call<br>
>>>>>>>>>>>>> +// CHECK: call void<br>
>>>>>>>>>>>>> @_ZN11one_deleted3fooENS_1AE(%<wbr>"struct.one_deleted::A"* %{{.*}})<br>
>>>>>>>>>>>>> +// CHECK-LABEL: declare void<br>
>>>>>>>>>>>>> @_ZN11one_deleted3fooENS_1AE(%<wbr>"struct.one_deleted::A"*)<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   // WIN64-LABEL: declare void<br>
>>>>>>>>>>>>> @"\01?foo@one_deleted@@YAXUA@1<wbr>@@Z"(%"struct.one_deleted::A"*<wbr>)<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>> @@ -195,12 +194,10 @@ void foo(B);<br>
>>>>>>>>>>>>>   void bar() {<br>
>>>>>>>>>>>>>     foo({});<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>> -// FIXME: This class has a non-trivial copy ctor and a trivial<br>
>>>>>>>>>>>>> copy<br>
>>>>>>>>>>>>> ctor.<br>
>>>>>>>>>>>>> It's<br>
>>>>>>>>>>>>> -// not clear whether we should pass by address or in registers.<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: define void @_ZN14two_copy_ctors3barEv()<br>
>>>>>>>>>>>>> -// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(<br>
>>>>>>>>>>>>> -// CHECK-DISABLED: call void<br>
>>>>>>>>>>>>> @_ZN14two_copy_ctors3fooENS_<wbr>1BE(%"struct.two_copy_ctors::<wbr>B"*<br>
>>>>>>>>>>>>> %{{.*}})<br>
>>>>>>>>>>>>> -// CHECK-DISABLED-LABEL: declare void<br>
>>>>>>>>>>>>> @_ZN14two_copy_ctors3fooENS_<wbr>1BE(%"struct.two_copy_ctors::<wbr>B"*)<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define void @_ZN14two_copy_ctors3barEv()<br>
>>>>>>>>>>>>> +// CHECK: call void @_Z{{.*}}C1Ev(<br>
>>>>>>>>>>>>> +// CHECK: call void<br>
>>>>>>>>>>>>> @_ZN14two_copy_ctors3fooENS_<wbr>1BE(%"struct.two_copy_ctors::<wbr>B"*<br>
>>>>>>>>>>>>> %{{.*}})<br>
>>>>>>>>>>>>> +// CHECK-LABEL: declare void<br>
>>>>>>>>>>>>> @_ZN14two_copy_ctors3fooENS_<wbr>1BE(%"struct.two_copy_ctors::<wbr>B"*)<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   // WIN64-LABEL: declare void<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @"\01?foo@two_copy_ctors@@<wbr>YAXUB@1@@Z"(%"struct.two_copy_<wbr>ctors::B"*)<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>> @@ -212,6 +209,7 @@ struct A {<br>
>>>>>>>>>>>>>     void *p;<br>
>>>>>>>>>>>>>   };<br>
>>>>>>>>>>>>>   void *foo(A a) { return a.p; }<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define i8*<br>
>>>>>>>>>>>>> @_ZN15definition_only3fooENS_<wbr>1AE(%"struct.definition_only::<wbr>A"*<br>
>>>>>>>>>>>>>   // WIN64-LABEL: define i8*<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @"\01?foo@definition_only@@<wbr>YAPEAXUA@1@@Z"(%"struct.<wbr>definition_only::A"*<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @@ -226,6 +224,7 @@ struct A {<br>
>>>>>>>>>>>>>     B b;<br>
>>>>>>>>>>>>>   };<br>
>>>>>>>>>>>>>   void *foo(A a) { return a.b.p; }<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define i8*<br>
>>>>>>>>>>>>> @_ZN17deleted_by_<wbr>member3fooENS_1AE(%"struct.<wbr>deleted_by_member::A"*<br>
>>>>>>>>>>>>>   // WIN64-LABEL: define i8*<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @"\01?foo@deleted_by_member@@<wbr>YAPEAXUA@1@@Z"(%"struct.<wbr>deleted_by_member::A"*<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @@ -239,6 +238,7 @@ struct A : B {<br>
>>>>>>>>>>>>>     A();<br>
>>>>>>>>>>>>>   };<br>
>>>>>>>>>>>>>   void *foo(A a) { return a.p; }<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define i8*<br>
>>>>>>>>>>>>> @_ZN15deleted_by_base3fooENS_<wbr>1AE(%"struct.deleted_by_base::<wbr>A"*<br>
>>>>>>>>>>>>>   // WIN64-LABEL: define i8*<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @"\01?foo@deleted_by_base@@<wbr>YAPEAXUA@1@@Z"(%"struct.<wbr>deleted_by_base::A"*<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @@ -253,6 +253,7 @@ struct A {<br>
>>>>>>>>>>>>>     B b;<br>
>>>>>>>>>>>>>   };<br>
>>>>>>>>>>>>>   void *foo(A a) { return a.b.p; }<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define i8*<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @_ZN22deleted_by_member_<wbr>copy3fooENS_1AE(%"struct.<wbr>deleted_by_member_copy::A"*<br>
>>>>>>>>>>>>>   // WIN64-LABEL: define i8*<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @"\01?foo@deleted_by_member_<wbr>copy@@YAPEAXUA@1@@Z"(%"struct.<wbr>deleted_by_member_copy::A"*<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @@ -266,6 +267,7 @@ struct A : B {<br>
>>>>>>>>>>>>>     A();<br>
>>>>>>>>>>>>>   };<br>
>>>>>>>>>>>>>   void *foo(A a) { return a.p; }<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define i8*<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @_ZN20deleted_by_base_<wbr>copy3fooENS_1AE(%"struct.<wbr>deleted_by_base_copy::A"*<br>
>>>>>>>>>>>>>   // WIN64-LABEL: define i8*<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @"\01?foo@deleted_by_base_copy<wbr>@@YAPEAXUA@1@@Z"(%"struct.<wbr>deleted_by_base_copy::A"*<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @@ -275,6 +277,75 @@ struct A {<br>
>>>>>>>>>>>>>     A(const A &o) = delete;<br>
>>>>>>>>>>>>>     void *p;<br>
>>>>>>>>>>>>>   };<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define i8*<br>
>>>>>>>>>>>>> @_ZN15explicit_delete3fooENS_<wbr>1AE(%"struct.explicit_delete::<wbr>A"*<br>
>>>>>>>>>>>>>   // WIN64-LABEL: define i8*<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @"\01?foo@explicit_delete@@<wbr>YAPEAXUA@1@@Z"(%"struct.<wbr>explicit_delete::A"*<br>
>>>>>>>>>>>>>   void *foo(A a) { return a.p; }<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +namespace implicitly_deleted_copy_ctor {<br>
>>>>>>>>>>>>> +struct A {<br>
>>>>>>>>>>>>> +  // No move ctor due to copy assignment.<br>
>>>>>>>>>>>>> +  A &operator=(const A&);<br>
>>>>>>>>>>>>> +  // Deleted copy ctor due to rvalue ref member.<br>
>>>>>>>>>>>>> +  int &&ref;<br>
>>>>>>>>>>>>> +};<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define {{.*}}<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @_ZN28implicitly_deleted_copy_<wbr>ctor3fooENS_1AE(%"struct.<wbr>implicitly_deleted_copy_ctor::<wbr>A"*<br>
>>>>>>>>>>>>> +// WIN64-LABEL: define {{.*}}<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @"\01?foo@implicitly_deleted_<wbr>copy_ctor@@YAAEAHUA@1@@Z"(%"<wbr>struct.implicitly_deleted_<wbr>copy_ctor::A"*<br>
>>>>>>>>>>>>> +int &foo(A a) { return a.ref; }<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +struct B {<br>
>>>>>>>>>>>>> +  // Passed direct: has non-deleted trivial copy ctor.<br>
>>>>>>>>>>>>> +  B &operator=(const B&);<br>
>>>>>>>>>>>>> +  int &ref;<br>
>>>>>>>>>>>>> +};<br>
>>>>>>>>>>>>> +int &foo(B b) { return b.ref; }<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define {{.*}}<br>
>>>>>>>>>>>>> @_ZN28implicitly_deleted_copy_<wbr>ctor3fooENS_1BE(i32*<br>
>>>>>>>>>>>>> +// WIN64-LABEL: define {{.*}}<br>
>>>>>>>>>>>>> @"\01?foo@implicitly_deleted_<wbr>copy_ctor@@YAAEAHUB@1@@Z"(i64<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +struct X { X(const X&); };<br>
>>>>>>>>>>>>> +struct Y { Y(const Y&) = default; };<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +union C {<br>
>>>>>>>>>>>>> +  C &operator=(const C&);<br>
>>>>>>>>>>>>> +  // Passed indirect: copy ctor deleted due to variant member<br>
>>>>>>>>>>>>> with<br>
>>>>>>>>>>>>> nontrivial copy ctor.<br>
>>>>>>>>>>>>> +  X x;<br>
>>>>>>>>>>>>> +  int n;<br>
>>>>>>>>>>>>> +};<br>
>>>>>>>>>>>>> +int foo(C c) { return c.n; }<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define {{.*}}<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @_ZN28implicitly_deleted_copy_<wbr>ctor3fooENS_1CE(%"union.<wbr>implicitly_deleted_copy_ctor::<wbr>C"*<br>
>>>>>>>>>>>>> +// WIN64-LABEL: define {{.*}}<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @"\01?foo@implicitly_deleted_<wbr>copy_ctor@@YAHTC@1@@Z"(%"<wbr>union.implicitly_deleted_copy_<wbr>ctor::C"*<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +struct D {<br>
>>>>>>>>>>>>> +  D &operator=(const D&);<br>
>>>>>>>>>>>>> +  // Passed indirect: copy ctor deleted due to variant member<br>
>>>>>>>>>>>>> with<br>
>>>>>>>>>>>>> nontrivial copy ctor.<br>
>>>>>>>>>>>>> +  union {<br>
>>>>>>>>>>>>> +    X x;<br>
>>>>>>>>>>>>> +    int n;<br>
>>>>>>>>>>>>> +  };<br>
>>>>>>>>>>>>> +};<br>
>>>>>>>>>>>>> +int foo(D d) { return d.n; }<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define {{.*}}<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @_ZN28implicitly_deleted_copy_<wbr>ctor3fooENS_1DE(%"struct.<wbr>implicitly_deleted_copy_ctor::<wbr>D"*<br>
>>>>>>>>>>>>> +// WIN64-LABEL: define {{.*}}<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> @"\01?foo@implicitly_deleted_<wbr>copy_ctor@@YAHUD@1@@Z"(%"<wbr>struct.implicitly_deleted_<wbr>copy_ctor::D"*<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +union E {<br>
>>>>>>>>>>>>> +  // Passed direct: has non-deleted trivial copy ctor.<br>
>>>>>>>>>>>>> +  E &operator=(const E&);<br>
>>>>>>>>>>>>> +  Y y;<br>
>>>>>>>>>>>>> +  int n;<br>
>>>>>>>>>>>>> +};<br>
>>>>>>>>>>>>> +int foo(E e) { return e.n; }<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define {{.*}}<br>
>>>>>>>>>>>>> @_ZN28implicitly_deleted_copy_<wbr>ctor3fooENS_1EE(i32<br>
>>>>>>>>>>>>> +// WIN64-LABEL: define {{.*}}<br>
>>>>>>>>>>>>> @"\01?foo@implicitly_deleted_<wbr>copy_ctor@@YAHTE@1@@Z"(i32<br>
>>>>>>>>>>>>> +<br>
>>>>>>>>>>>>> +struct F {<br>
>>>>>>>>>>>>> +  // Passed direct: has non-deleted trivial copy ctor.<br>
>>>>>>>>>>>>> +  F &operator=(const F&);<br>
>>>>>>>>>>>>> +  union {<br>
>>>>>>>>>>>>> +    Y y;<br>
>>>>>>>>>>>>> +    int n;<br>
>>>>>>>>>>>>> +  };<br>
>>>>>>>>>>>>> +};<br>
>>>>>>>>>>>>> +int foo(F f) { return f.n; }<br>
>>>>>>>>>>>>> +// CHECK-LABEL: define {{.*}}<br>
>>>>>>>>>>>>> @_ZN28implicitly_deleted_copy_<wbr>ctor3fooENS_1FE(i32<br>
>>>>>>>>>>>>> +// WIN64-LABEL: define {{.*}}<br>
>>>>>>>>>>>>> @"\01?foo@implicitly_deleted_<wbr>copy_ctor@@YAHUF@1@@Z"(i32<br>
>>>>>>>>>>>>> +}<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> Modified:<br>
>>>>>>>>>>>>> cfe/trunk/unittests/<wbr>ASTMatchers/<wbr>ASTMatchersNarrowingTest.cpp<br>
>>>>>>>>>>>>> URL:<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp?rev=310401&r1=310400&r2=310401&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/unittests/<wbr>ASTMatchers/<wbr>ASTMatchersNarrowingTest.cpp?<wbr>rev=310401&r1=310400&r2=<wbr>310401&view=diff</a><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> ==============================<wbr>==============================<wbr>==================<br>
>>>>>>>>>>>>> --- cfe/trunk/unittests/<wbr>ASTMatchers/<wbr>ASTMatchersNarrowingTest.cpp<br>
>>>>>>>>>>>>> (original)<br>
>>>>>>>>>>>>> +++ cfe/trunk/unittests/<wbr>ASTMatchers/<wbr>ASTMatchersNarrowingTest.cpp<br>
>>>>>>>>>>>>> Tue<br>
>>>>>>>>>>>>> Aug<br>
>>>>>>>>>>>>> 8 12:12:28 2017<br>
>>>>>>>>>>>>> @@ -1108,26 +1108,35 @@ TEST(ConstructorDeclaration, IsExplicit)<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   TEST(ConstructorDeclaration, Kinds) {<br>
>>>>>>>>>>>>> -  EXPECT_TRUE(matches("struct S { S(); };",<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> cxxConstructorDecl(<wbr>isDefaultConstructor())));<br>
>>>>>>>>>>>>> -  EXPECT_TRUE(notMatches("struct S { S(); };",<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> cxxConstructorDecl(<wbr>isCopyConstructor())));<br>
>>>>>>>>>>>>> -  EXPECT_TRUE(notMatches("struct S { S(); };",<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> cxxConstructorDecl(<wbr>isMoveConstructor())));<br>
>>>>>>>>>>>>> +  EXPECT_TRUE(matches(<br>
>>>>>>>>>>>>> +      "struct S { S(); };",<br>
>>>>>>>>>>>>> +      cxxConstructorDecl(<wbr>isDefaultConstructor(),<br>
>>>>>>>>>>>>> unless(isImplicit()))));<br>
>>>>>>>>>>>>> +  EXPECT_TRUE(notMatches(<br>
>>>>>>>>>>>>> +      "struct S { S(); };",<br>
>>>>>>>>>>>>> +      cxxConstructorDecl(<wbr>isCopyConstructor(),<br>
>>>>>>>>>>>>> unless(isImplicit()))));<br>
>>>>>>>>>>>>> +  EXPECT_TRUE(notMatches(<br>
>>>>>>>>>>>>> +      "struct S { S(); };",<br>
>>>>>>>>>>>>> +      cxxConstructorDecl(<wbr>isMoveConstructor(),<br>
>>>>>>>>>>>>> unless(isImplicit()))));<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> -  EXPECT_TRUE(notMatches("struct S { S(const S&); };",<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> cxxConstructorDecl(<wbr>isDefaultConstructor())));<br>
>>>>>>>>>>>>> -  EXPECT_TRUE(matches("struct S { S(const S&); };",<br>
>>>>>>>>>>>>> -                      cxxConstructorDecl(<wbr>isCopyConstructor())));<br>
>>>>>>>>>>>>> -  EXPECT_TRUE(notMatches("struct S { S(const S&); };",<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> cxxConstructorDecl(<wbr>isMoveConstructor())));<br>
>>>>>>>>>>>>> +  EXPECT_TRUE(notMatches(<br>
>>>>>>>>>>>>> +      "struct S { S(const S&); };",<br>
>>>>>>>>>>>>> +      cxxConstructorDecl(<wbr>isDefaultConstructor(),<br>
>>>>>>>>>>>>> unless(isImplicit()))));<br>
>>>>>>>>>>>>> +  EXPECT_TRUE(matches(<br>
>>>>>>>>>>>>> +      "struct S { S(const S&); };",<br>
>>>>>>>>>>>>> +      cxxConstructorDecl(<wbr>isCopyConstructor(),<br>
>>>>>>>>>>>>> unless(isImplicit()))));<br>
>>>>>>>>>>>>> +  EXPECT_TRUE(notMatches(<br>
>>>>>>>>>>>>> +      "struct S { S(const S&); };",<br>
>>>>>>>>>>>>> +      cxxConstructorDecl(<wbr>isMoveConstructor(),<br>
>>>>>>>>>>>>> unless(isImplicit()))));<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> -  EXPECT_TRUE(notMatches("struct S { S(S&&); };",<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> cxxConstructorDecl(<wbr>isDefaultConstructor())));<br>
>>>>>>>>>>>>> -  EXPECT_TRUE(notMatches("struct S { S(S&&); };",<br>
>>>>>>>>>>>>> -<br>
>>>>>>>>>>>>> cxxConstructorDecl(<wbr>isCopyConstructor())));<br>
>>>>>>>>>>>>> -  EXPECT_TRUE(matches("struct S { S(S&&); };",<br>
>>>>>>>>>>>>> -                      cxxConstructorDecl(<wbr>isMoveConstructor())));<br>
>>>>>>>>>>>>> +  EXPECT_TRUE(notMatches(<br>
>>>>>>>>>>>>> +      "struct S { S(S&&); };",<br>
>>>>>>>>>>>>> +      cxxConstructorDecl(<wbr>isDefaultConstructor(),<br>
>>>>>>>>>>>>> unless(isImplicit()))));<br>
>>>>>>>>>>>>> +  EXPECT_TRUE(notMatches(<br>
>>>>>>>>>>>>> +      "struct S { S(S&&); };",<br>
>>>>>>>>>>>>> +      cxxConstructorDecl(<wbr>isCopyConstructor(),<br>
>>>>>>>>>>>>> unless(isImplicit()))));<br>
>>>>>>>>>>>>> +  EXPECT_TRUE(matches(<br>
>>>>>>>>>>>>> +      "struct S { S(S&&); };",<br>
>>>>>>>>>>>>> +      cxxConstructorDecl(<wbr>isMoveConstructor(),<br>
>>>>>>>>>>>>> unless(isImplicit()))));<br>
>>>>>>>>>>>>>   }<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>>   TEST(ConstructorDeclaration, IsUserProvided) {<br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>><br>
>>>>>>>>>>>>> ______________________________<wbr>_________________<br>
>>>>>>>>>>>>> cfe-commits mailing list<br>
>>>>>>>>>>>>> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
>>>>>>>>>>>>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
>>>>>>>>>>>><br>
>>>>>>>>>>>><br>
>>>>>>>>>>>><br>
>>>>>>>>>>>> ______________________________<wbr>_________________<br>
>>>>>>>>>>>> cfe-commits mailing list<br>
>>>>>>>>>>>> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
>>>>>>>>>>>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
>>>>>>>>>>>><br>
>>>>>>>>>>> ______________________________<wbr>_________________<br>
>>>>>>>>>>> cfe-commits mailing list<br>
>>>>>>>>>>> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
>>>>>>>>>>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
>>>>>>>>>><br>
>>>>>>>>>><br>
>>>>>>>>>><br>
>>>>>>><br>
>>>>>> ______________________________<wbr>_________________<br>
>>>>>> cfe-commits mailing list<br>
>>>>>> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
>>>>>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
>>>>><br>
>>>>><br>
</div></div><br>______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div></div>