On 14 August 2017 at 16:59, Diana Picus <diana.pi...@linaro.org> 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 > > Why would it contain gtest.cc? It seems to contain gtest.h and a bunch > of other internal gtest headers... >
In particular, gtest.cc is included into gtest_all.cc, which compiled to ASAN_INST_TEST_OBJECTS.gtest_all.cc.armhf-with-calls.o and then added to the link line, which looks like this: build/./bin/clang ASAN_INST_TEST_OBJECTS.gtest-all.cc.armhf-with-calls.o ASAN_INST_TEST_OBJECTS.asan_asm_test.cc.armhf-with-calls.o ASAN_INST_TEST_OBJECTS.asan_globals_test.cc.armhf-with-calls.o ASAN_INST_TEST_OBJECTS.asan_interface_test.cc.armhf-with-calls.o ASAN_INST_TEST_OBJECTS.asan_internal_interface_test.cc.armhf-with-calls.o ASAN_INST_TEST_OBJECTS.asan_test.cc.armhf-with-calls.o ASAN_INST_TEST_OBJECTS.asan_oob_test.cc.armhf-with-calls.o ASAN_INST_TEST_OBJECTS.asan_mem_test.cc.armhf-with-calls.o ASAN_INST_TEST_OBJECTS.asan_str_test.cc.armhf-with-calls.o ASAN_INST_TEST_OBJECTS.asan_test_main.cc.armhf-with-calls.o -o build/projects/compiler-rt/lib/asan/tests/default/Asan-armhf-with-calls-Test -Wl,-allow-shlib-undefined -g --driver-mode=g++ -fsanitize=address -march=armv7-a -mfloat-abi=hard > > 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