Hi, I didn't manage to reproduce this at -O0. Yes, I think the version in 1.8.0, slightly modified (see llvm/utils/unittest/googletest/README.LLVM)
On 14 August 2017 at 17:06, Vassil Vassilev <v.g.vassi...@gmail.com> wrote: > On 14/08/17 15:59, Diana Picus wrote: >> >> No, the buildbots don't build with -O0 (at least not the ones that broke). >> >> The command line for that particular object is: >> build/./bin/clang -fPIC -fvisibility-inlines-hidden -Werror=date-time >> -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual >> -Wmissing-field-initializers -pedantic -Wno-long-long >> -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor >> -Wstring-conversion -fcolor-diagnostics -ffunction-sections >> -fdata-sections -Wall -std=c++11 -Wno-unused-parameter >> -Wno-unknown-warning-option -Wno-covered-switch-default >> -DGTEST_NO_LLVM_RAW_OSTREAM=1 -DGTEST_HAS_RTTI=0 >> -I$LLVM_SRC/llvm/utils/unittest/googletest/include >> -I/home/diana.picus/linaro-scripts/bisect/llvm/utils/unittest/googletest >> -I$LLVM_SRC/llvm/projects/compiler-rt/include >> -I$LLVM_SRC/llvm/projects/compiler-rt/lib >> -I$LLVM_SRC/llvm/projects/compiler-rt/lib/asan >> -I$LLVM_SRC/llvm/projects/compiler-rt/lib/sanitizer_common/tests >> -fno-rtti -O2 -Wno-format -Werror=sign-compare -Wno-non-virtual-dtor >> -Wno-variadic-macros -gline-tables-only -DASAN_HAS_BLACKLIST=1 >> -DASAN_HAS_EXCEPTIONS=1 -DASAN_UAR=0 -fsanitize=address >> >> -fsanitize-blacklist=$LLVM_SRC/llvm/projects/compiler-rt/lib/asan/tests/asan_test.ignore >> -mllvm -asan-instrumentation-with-call-threshold=0 -march=armv7-a >> -mfloat-abi=hard -c -o >> ASAN_INST_TEST_OBJECTS.asan_test.cc.armhf-with-calls.o >> $LLVM_SRC/compiler-rt/lib/asan/tests/asan_test.cc > > Could you try to reproduce the issue with O0? This would rule out the > optimizer. Could you resend the O0 ll file, maybe I could find something > out. IIUC, the gtest version is 1.8.0? > >> >> Why would it contain gtest.cc? It seems to contain gtest.h and a bunch >> of other internal gtest headers... >> >> >> On 14 August 2017 at 16:51, Vassil Vassilev <v.g.vassi...@gmail.com> >> wrote: >>> >>> On 14/08/17 15:08, Vassil Vassilev wrote: >>>> >>>> On 14/08/17 13:04, Diana Picus wrote: >>>>> >>>>> See attached. >>>> >>>> Thanks! It looks like asan_test.i doesn't have gtest.cc which appears in >>>> the stack trace. Am I missing something? >>> >>> Could you paste the compiler invocation. Are we building with -O0 (I >>> see >>> quite a lot of things inline). Could it be an optimizer problem? >>> >>>>> On 14 August 2017 at 13:30, Vassil Vassilev <v.g.vassi...@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.pi...@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.vassi...@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.pi...@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.pi...@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 >>>>>>>>>>>> <rich...@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@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.vassi...@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.pi...@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.vassi...@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@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@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@move_ctor@@YAXUA@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@all_deleted@@YAXUA@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@implicitly_deleted@@YAXUA@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@implicitly_deleted@@YAXUA@1@@Z"(i64 >>>>>>>>>>>>>>>>>>>> +// WIN64-19-LABEL: declare void >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> @"\01?foo@implicitly_deleted@@YAXUA@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@one_deleted@@YAXUA@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@two_copy_ctors@@YAXUB@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@definition_only@@YAPEAXUA@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@deleted_by_member@@YAPEAXUA@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@deleted_by_base@@YAPEAXUA@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@deleted_by_member_copy@@YAPEAXUA@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@deleted_by_base_copy@@YAPEAXUA@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@explicit_delete@@YAPEAXUA@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@implicitly_deleted_copy_ctor@@YAAEAHUA@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@implicitly_deleted_copy_ctor@@YAAEAHUB@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@implicitly_deleted_copy_ctor@@YAHTC@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@implicitly_deleted_copy_ctor@@YAHUD@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@implicitly_deleted_copy_ctor@@YAHTE@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@implicitly_deleted_copy_ctor@@YAHUF@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@lists.llvm.org >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>>>>> cfe-commits mailing list >>>>>>>>>>>>>>>>>>> cfe-commits@lists.llvm.org >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>>>> cfe-commits mailing list >>>>>>>>>>>>>>>>>> cfe-commits@lists.llvm.org >>>>>>>>>>>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>> cfe-commits mailing list >>>>>>>>>>>>> cfe-commits@lists.llvm.org >>>>>>>>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>>>>>>>>>> >>>>>>>>>>>> > _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits