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
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