Hi Marco, Your commit crashes clang when building the LLVM Support with libc++ library. I'll revert the commit to unbreak our integrate.
See the details in the following bug: https://bugs.llvm.org/show_bug.cgi?id=42665 On Thu, Jul 18, 2019 at 1:42 PM Ilya Biryukov <ibiryu...@google.com> wrote: > Hi Marco, > > Your commit crashes clang when building the LLVM Support with libc++ > library. > I'll revert the commit to unbreak our integrate. > > I've attached the repro with preprocessed files to this email. > > (Previous email seems to be in queue for moderation, it's probably too > large) > > > On Thu, Jul 18, 2019 at 1:39 PM Ilya Biryukov <ibiryu...@google.com> > wrote: > >> Hi Marco, >> >> Your commit crashes clang when building the LLVM Support with libc++ >> library. >> I'll revert the commit to unbreak our integrate. >> >> I've attached the repro with preprocessed files to this email. Here's the >> stacktrace too: >> >> clang-9: >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprCXX.cpp:98: >> clang::CodeGen::RValue >> clang::CodeGen::CodeGenFunction::EmitCXXDestructorCall(clang::GlobalDecl, >> const clang::CodeGen::CGCallee &, llvm::Value *, clang::QualType, >> llvm::Value *, clang::QualType, const clang::CallExpr *): Assertion >> `!ThisTy.isNull()' failed. >> Stack dump: >> 0. Program arguments: >> /usr/local/google/home/ibiryukov/projects/llvm/build-rel/bin/clang-9 -cc1 >> -triple x86_64-unknown-linux-gnu -emit-obj -disable-free -main-file-name >> BinaryStreamRef.cpp -mrelocation-model pic -pic-level 2 -mthread-model >> posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables >> -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb >> -ffunction-sections -fdata-sections -coverage-notes-file >> /usr/local/google/home/ibiryukov/projects/llvm/build-stage2-from-rel/lib/Support/CMakeFiles/LLVMSupport.dir/BinaryStreamRef.cpp.gcno >> -nostdinc++ -resource-dir >> /usr/local/google/home/ibiryukov/projects/llvm/build-rel/lib/clang/9.0.0 >> -dependency-file >> lib/Support/CMakeFiles/LLVMSupport.dir/BinaryStreamRef.cpp.o.d >> -sys-header-deps -MT >> lib/Support/CMakeFiles/LLVMSupport.dir/BinaryStreamRef.cpp.o -D >> GTEST_HAS_RTTI=0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D >> __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I lib/Support -I >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/lib/Support -I >> /usr/include/libxml2 -I include -I >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/include -I >> /usr/lib/libcxx-google/include/c++/v1/ -U NDEBUG -internal-isystem >> /usr/local/include -internal-isystem >> /usr/local/google/home/ibiryukov/projects/llvm/build-rel/lib/clang/9.0.0/include >> -internal-externc-isystem /usr/include/x86_64-linux-gnu >> -internal-externc-isystem /include -internal-externc-isystem /usr/include >> -O3 -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra >> -Wno-unused-parameter -Wwrite-strings -Wcast-qual >> -Wmissing-field-initializers -Wno-long-long -Wimplicit-fallthrough >> -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor >> -Wdelete-non-virtual-dtor -Wstring-conversion -pedantic -std=c++11 >> -fdeprecated-macro -fdebug-compilation-dir >> /usr/local/google/home/ibiryukov/projects/llvm/build-stage2-from-rel >> -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fno-rtti >> -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics >> -vectorize-loops -vectorize-slp -faddrsig -o >> lib/Support/CMakeFiles/LLVMSupport.dir/BinaryStreamRef.cpp.o -x c++ >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/lib/Support/BinaryStreamRef.cpp >> 1. <eof> parser at end of file >> 2. Per-file LLVM IR generation >> 3. /usr/lib/libcxx-google/include/c++/v1/memory:3698:18: Generating >> code for declaration 'std::__1::__shared_ptr_emplace<(anonymous >> namespace)::ArrayRefImpl, std::__1::allocator<(anonymous >> namespace)::ArrayRefImpl> >::__on_zero_shared' >> #0 0x00000000044ad294 PrintStackTrace >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/lib/Support/Unix/Signals.inc:533:13 >> #1 0x00000000044ad294 PrintStackTraceSignalHandler(void*) >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/lib/Support/Unix/Signals.inc:593:0 >> #2 0x00000000044aaf7e llvm::sys::RunSignalHandlers() >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/lib/Support/Signals.cpp:69:18 >> #3 0x00000000044ad6a8 SignalHandler(int) >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/lib/Support/Unix/Signals.inc:385:1 >> #4 0x00007f61992e93a0 __restore_rt >> (/lib/x86_64-linux-gnu/libpthread.so.0+0x123a0) >> #5 0x00007f6197ddacfb raise (/lib/x86_64-linux-gnu/libc.so.6+0x36cfb) >> #6 0x00007f6197dc58ad abort (/lib/x86_64-linux-gnu/libc.so.6+0x218ad) >> #7 0x00007f6197dc577f (/lib/x86_64-linux-gnu/libc.so.6+0x2177f) >> #8 0x00007f6197dd3542 (/lib/x86_64-linux-gnu/libc.so.6+0x2f542) >> #9 0x00000000048d660e doit >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Casting.h:105:5 >> #10 0x00000000048d660e doit >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Casting.h:132:0 >> #11 0x00000000048d660e doit >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Casting.h:122:0 >> #12 0x00000000048d660e isa<clang::CXXRecordDecl, const clang::DeclContext >> *> >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Casting.h:142:0 >> #13 0x00000000048d660e cast<clang::CXXRecordDecl, const >> clang::DeclContext> >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Casting.h:264:0 >> #14 0x00000000048d660e getParent >> /usr/local/google/home/ibiryukov/projects/llvm/clang/include/clang/AST/DeclCXX.h:2238:0 >> #15 0x00000000048d660e >> clang::CodeGen::CodeGenFunction::EmitCXXDestructorCall(clang::GlobalDecl, >> clang::CodeGen::CGCallee const&, llvm::Value*, clang::QualType, >> llvm::Value*, clang::QualType, clang::CallExpr const*) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprCXX.cpp:99:0 >> #16 0x00000000049a19da (anonymous >> namespace)::ItaniumCXXABI::EmitVirtualDestructorCall(clang::CodeGen::CodeGenFunction&, >> clang::CXXDestructorDecl const*, clang::CXXDtorType, >> clang::CodeGen::Address, llvm::PointerUnion<clang::CXXDeleteExpr const*, >> clang::CXXMemberCallExpr const*>) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/ItaniumCXXABI.cpp:1765:3 >> #17 0x00000000048d7e61 >> clang::CodeGen::CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(clang::CallExpr >> const*, clang::CXXMethodDecl const*, clang::CodeGen::ReturnValueSlot, bool, >> clang::NestedNameSpecifier*, bool, clang::Expr const*) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprCXX.cpp:0:23 >> #18 0x00000000048d6b54 >> clang::CodeGen::CodeGenFunction::EmitCXXMemberCallExpr(clang::CXXMemberCallExpr >> const*, clang::CodeGen::ReturnValueSlot) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprCXX.cpp:204:1 >> #19 0x000000000483cf65 >> clang::CodeGen::CodeGenFunction::EmitCallExpr(clang::CallExpr const*, >> clang::CodeGen::ReturnValueSlot) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExpr.cpp:4491:12 >> #20 0x00000000048ca744 (anonymous >> namespace)::ScalarExprEmitter::VisitCallExpr(clang::CallExpr const*) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprScalar.cpp:0:0 >> #21 0x00000000048ba6c5 Visit >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprScalar.cpp:424:52 >> #22 0x00000000048ba6c5 >> clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprScalar.cpp:4436:0 >> #23 0x0000000004820e10 >> clang::CodeGen::CodeGenFunction::EmitAnyExpr(clang::Expr const*, >> clang::CodeGen::AggValueSlot, bool) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExpr.cpp:199:24 >> #24 0x0000000004820db9 >> clang::CodeGen::CodeGenFunction::EmitIgnoredExpr(clang::Expr const*) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExpr.cpp:188:1 >> #25 0x000000000480bd9f GetInsertBlock >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/IR/IRBuilder.h:126:47 >> #26 0x000000000480bd9f >> clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*, >> llvm::ArrayRef<clang::Attr const*>) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGStmt.cpp:114:0 >> #27 0x0000000004816890 >> clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt >> const&, bool, clang::CodeGen::AggValueSlot) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGStmt.cpp:390:22 >> #28 0x00000000047edc7d getLangOpts >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenFunction.h:1630:51 >> #29 0x00000000047edc7d >> clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, >> llvm::Function*, clang::CodeGen::CGFunctionInfo const&) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenFunction.cpp:1208:0 >> #30 0x0000000004787623 >> clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, >> llvm::GlobalValue*) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:4320:3 >> #31 0x000000000477fd50 isVirtual >> /usr/local/google/home/ibiryukov/projects/llvm/clang/include/clang/AST/DeclCXX.h:2158:59 >> #32 0x000000000477fd50 >> clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, >> llvm::GlobalValue*) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2751:0 >> #33 0x0000000004774981 begin >> /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:708:45 >> #34 0x0000000004774981 empty >> /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:895:0 >> #35 0x0000000004774981 clang::CodeGen::CodeGenModule::EmitDeferred() >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2123:0 >> #36 0x00000000047749a9 begin >> /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:708:45 >> #37 0x00000000047749a9 empty >> /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:895:0 >> #38 0x00000000047749a9 clang::CodeGen::CodeGenModule::EmitDeferred() >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2125:0 >> #39 0x00000000047749a9 begin >> /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:708:45 >> #40 0x00000000047749a9 empty >> /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:895:0 >> #41 0x00000000047749a9 clang::CodeGen::CodeGenModule::EmitDeferred() >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2125:0 >> #42 0x00000000047749a9 begin >> /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:708:45 >> #43 0x00000000047749a9 empty >> /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:895:0 >> #44 0x00000000047749a9 clang::CodeGen::CodeGenModule::EmitDeferred() >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2125:0 >> #45 0x00000000047749a9 begin >> /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:708:45 >> #46 0x00000000047749a9 empty >> /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:895:0 >> #47 0x00000000047749a9 clang::CodeGen::CodeGenModule::EmitDeferred() >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2125:0 >> #48 0x00000000047738e9 clang::CodeGen::CodeGenModule::Release() >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:394:3 >> #49 0x0000000004d03644 (anonymous >> namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/ModuleBuilder.cpp:260:11 >> #50 0x0000000004d00dc6 >> clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenAction.cpp:240:13 >> #51 0x0000000005a6b323 __normal_iterator >> /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_iterator.h:781:20 >> #52 0x0000000005a6b323 begin >> /usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:699:0 >> #53 0x0000000005a6b323 >> finalize<std::vector<std::unique_ptr<clang::TemplateInstantiationCallback, >> std::default_delete<clang::TemplateInstantiationCallback> >, >> std::allocator<std::unique_ptr<clang::TemplateInstantiationCallback, >> std::default_delete<clang::TemplateInstantiationCallback> > > > > >> /usr/local/google/home/ibiryukov/projects/llvm/clang/include/clang/Sema/TemplateInstCallback.h:54:0 >> #54 0x0000000005a6b323 clang::ParseAST(clang::Sema&, bool, bool) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/Parse/ParseAST.cpp:178:0 >> #55 0x0000000004c5ef58 clang::FrontendAction::Execute() >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/Frontend/FrontendAction.cpp:938:10 >> #56 0x0000000004bc9328 getPtr >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Error.h:273:42 >> #57 0x0000000004bc9328 operator bool >> /usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Error.h:236:0 >> #58 0x0000000004bc9328 >> clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/Frontend/CompilerInstance.cpp:944:0 >> #59 0x0000000004cfb86d >> clang::ExecuteCompilerInvocation(clang::CompilerInstance*) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:291:25 >> #60 0x00000000028ea04a cc1_main(llvm::ArrayRef<char const*>, char const*, >> void*) >> /usr/local/google/home/ibiryukov/projects/llvm/clang/tools/driver/cc1_main.cpp:249:15 >> #61 0x00000000028e7d24 ExecuteCC1Tool >> /usr/local/google/home/ibiryukov/projects/llvm/clang/tools/driver/driver.cpp:309:12 >> #62 0x00000000028e7d24 main >> /usr/local/google/home/ibiryukov/projects/llvm/clang/tools/driver/driver.cpp:381:0 >> #63 0x00007f6197dc752b __libc_start_main >> (/lib/x86_64-linux-gnu/libc.so.6+0x2352b) >> #64 0x00000000028e502a _start >> (/usr/local/google/home/ibiryukov/projects/llvm/build-rel/bin/clang-9+0x28e502a) >> clang-9: error: unable to execute command: Aborted >> clang-9: error: clang frontend command failed due to signal (use -v to >> see invocation) >> clang version 9.0.0 (https://github.com/llvm/llvm-project >> 0cadf7bb2e78b9276421a44c0e1ad3cb4520050b) >> Target: x86_64-unknown-linux-gnu >> Thread model: posix >> InstalledDir: /usr/local/google/home/ibiryukov/projects/llvm/build-rel/bin >> clang-9: note: diagnostic msg: PLEASE submit a bug report to >> https://bugs.llvm.org/ and include the crash backtrace, preprocessed >> source, and associated run script. >> clang-9: note: diagnostic msg: >> ******************** >> >> PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT: >> Preprocessed source(s) and associated run script(s) are located at: >> clang-9: note: diagnostic msg: /tmp/BinaryStreamRef-f5e741.cpp >> clang-9: note: diagnostic msg: /tmp/BinaryStreamRef-f5e741.sh >> clang-9: note: diagnostic msg: >> >> ******************** >> >> On Thu, Jul 18, 2019 at 12:03 PM Marco Antognini via cfe-commits < >> cfe-commits@lists.llvm.org> wrote: >> >>> Author: mantognini >>> Date: Thu Jul 18 03:04:18 2019 >>> New Revision: 366422 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=366422&view=rev >>> Log: >>> [OpenCL] Improve destructor support in C++ for OpenCL >>> >>> Summary: >>> This patch does mainly three things: >>> 1. It fixes a false positive error detection in Sema that is similar to >>> D62156. The error happens when explicitly calling an overloaded >>> destructor for different address spaces. >>> 2. It selects the correct destructor when multiple overloads for >>> address spaces are available. >>> 3. It inserts the expected address space cast when invoking a >>> destructor, if needed, and therefore fixes a crash due to the unmet >>> assertion in llvm::CastInst::Create. >>> >>> The following is a reproducer of the three issues: >>> >>> struct MyType { >>> ~MyType() {} >>> ~MyType() __constant {} >>> }; >>> >>> __constant MyType myGlobal{}; >>> >>> kernel void foo() { >>> myGlobal.~MyType(); // 1 and 2. >>> // 1. error: cannot initialize object parameter of type >>> // '__generic MyType' with an expression of type '__constant >>> MyType' >>> // 2. error: no matching member function for call to '~MyType' >>> } >>> >>> kernel void bar() { >>> // 3. The implicit call to the destructor crashes due to: >>> // Assertion `castIsValid(op, S, Ty) && "Invalid cast!"' failed. >>> // in llvm::CastInst::Create. >>> MyType myLocal; >>> } >>> >>> The added test depends on D62413 and covers a few more things than the >>> above reproducer. >>> >>> Subscribers: yaxunl, Anastasia, cfe-commits >>> >>> Tags: #clang >>> >>> Differential Revision: https://reviews.llvm.org/D64569 >>> >>> Added: >>> cfe/trunk/test/CodeGenOpenCLCXX/addrspace-with-class.cl >>> Removed: >>> cfe/trunk/test/CodeGenOpenCLCXX/addrspace-ctor.cl >>> Modified: >>> cfe/trunk/include/clang/AST/DeclCXX.h >>> cfe/trunk/lib/AST/DeclCXX.cpp >>> cfe/trunk/lib/CodeGen/CGCXXABI.h >>> cfe/trunk/lib/CodeGen/CGCall.cpp >>> cfe/trunk/lib/CodeGen/CGClass.cpp >>> cfe/trunk/lib/CodeGen/CGDecl.cpp >>> cfe/trunk/lib/CodeGen/CGExprCXX.cpp >>> cfe/trunk/lib/CodeGen/CodeGenFunction.h >>> cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp >>> cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp >>> cfe/trunk/lib/Sema/SemaDeclCXX.cpp >>> cfe/trunk/lib/Sema/SemaOverload.cpp >>> >>> Modified: cfe/trunk/include/clang/AST/DeclCXX.h >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=366422&r1=366421&r2=366422&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/include/clang/AST/DeclCXX.h (original) >>> +++ cfe/trunk/include/clang/AST/DeclCXX.h Thu Jul 18 03:04:18 2019 >>> @@ -2232,20 +2232,20 @@ public: >>> >>> overridden_method_range overridden_methods() const; >>> >>> - /// Returns the parent of this method declaration, which >>> + /// Return the parent of this method declaration, which >>> /// is the class in which this method is defined. >>> const CXXRecordDecl *getParent() const { >>> return cast<CXXRecordDecl>(FunctionDecl::getParent()); >>> } >>> >>> - /// Returns the parent of this method declaration, which >>> + /// Return the parent of this method declaration, which >>> /// is the class in which this method is defined. >>> CXXRecordDecl *getParent() { >>> return const_cast<CXXRecordDecl *>( >>> cast<CXXRecordDecl>(FunctionDecl::getParent())); >>> } >>> >>> - /// Returns the type of the \c this pointer. >>> + /// Return the type of the \c this pointer. >>> /// >>> /// Should only be called for instance (i.e., non-static) methods. >>> Note >>> /// that for the call operator of a lambda closure type, this returns >>> the >>> @@ -2253,9 +2253,17 @@ public: >>> /// 'this' type. >>> QualType getThisType() const; >>> >>> + /// Return the type of the object pointed by \c this. >>> + /// >>> + /// See getThisType() for usage restriction. >>> + QualType getThisObjectType() const; >>> + >>> static QualType getThisType(const FunctionProtoType *FPT, >>> const CXXRecordDecl *Decl); >>> >>> + static QualType getThisObjectType(const FunctionProtoType *FPT, >>> + const CXXRecordDecl *Decl); >>> + >>> Qualifiers getMethodQualifiers() const { >>> return getType()->getAs<FunctionProtoType>()->getMethodQuals(); >>> } >>> >>> Modified: cfe/trunk/lib/AST/DeclCXX.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=366422&r1=366421&r2=366422&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/AST/DeclCXX.cpp (original) >>> +++ cfe/trunk/lib/AST/DeclCXX.cpp Thu Jul 18 03:04:18 2019 >>> @@ -2253,12 +2253,23 @@ CXXMethodDecl::overridden_methods() cons >>> return getASTContext().overridden_methods(this); >>> } >>> >>> +static QualType getThisObjectType(ASTContext &C, const >>> FunctionProtoType *FPT, >>> + const CXXRecordDecl *Decl) { >>> + QualType ClassTy = C.getTypeDeclType(Decl); >>> + return C.getQualifiedType(ClassTy, FPT->getMethodQuals()); >>> +} >>> + >>> QualType CXXMethodDecl::getThisType(const FunctionProtoType *FPT, >>> const CXXRecordDecl *Decl) { >>> ASTContext &C = Decl->getASTContext(); >>> - QualType ClassTy = C.getTypeDeclType(Decl); >>> - ClassTy = C.getQualifiedType(ClassTy, FPT->getMethodQuals()); >>> - return C.getPointerType(ClassTy); >>> + QualType ObjectTy = ::getThisObjectType(C, FPT, Decl); >>> + return C.getPointerType(ObjectTy); >>> +} >>> + >>> +QualType CXXMethodDecl::getThisObjectType(const FunctionProtoType *FPT, >>> + const CXXRecordDecl *Decl) { >>> + ASTContext &C = Decl->getASTContext(); >>> + return ::getThisObjectType(C, FPT, Decl); >>> } >>> >>> QualType CXXMethodDecl::getThisType() const { >>> @@ -2273,6 +2284,14 @@ QualType CXXMethodDecl::getThisType() co >>> getParent()); >>> } >>> >>> +QualType CXXMethodDecl::getThisObjectType() const { >>> + // Ditto getThisType. >>> + assert(isInstance() && "No 'this' for static methods!"); >>> + >>> + return >>> CXXMethodDecl::getThisObjectType(getType()->getAs<FunctionProtoType>(), >>> + getParent()); >>> +} >>> + >>> bool CXXMethodDecl::hasInlineBody() const { >>> // If this function is a template instantiation, look at the template >>> from >>> // which it was instantiated. >>> >>> Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=366422&r1=366421&r2=366422&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/CodeGen/CGCXXABI.h (original) >>> +++ cfe/trunk/lib/CodeGen/CGCXXABI.h Thu Jul 18 03:04:18 2019 >>> @@ -378,7 +378,7 @@ public: >>> virtual void EmitDestructorCall(CodeGenFunction &CGF, >>> const CXXDestructorDecl *DD, >>> CXXDtorType Type, >>> bool ForVirtualBase, bool Delegating, >>> - Address This) = 0; >>> + Address This, QualType ThisTy) = 0; >>> >>> /// Emits the VTable definitions required for the given record type. >>> virtual void emitVTableDefinitions(CodeGenVTables &CGVT, >>> @@ -421,11 +421,15 @@ public: >>> llvm::Type *Ty, >>> SourceLocation Loc) = 0; >>> >>> + using DeleteOrMemberCallExpr = >>> + llvm::PointerUnion<const CXXDeleteExpr *, const CXXMemberCallExpr >>> *>; >>> + >>> /// Emit the ABI-specific virtual destructor call. >>> - virtual llvm::Value * >>> - EmitVirtualDestructorCall(CodeGenFunction &CGF, const >>> CXXDestructorDecl *Dtor, >>> - CXXDtorType DtorType, Address This, >>> - const CXXMemberCallExpr *CE) = 0; >>> + virtual llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF, >>> + const >>> CXXDestructorDecl *Dtor, >>> + CXXDtorType DtorType, >>> + Address This, >>> + DeleteOrMemberCallExpr >>> E) = 0; >>> >>> virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, >>> GlobalDecl GD, >>> >>> Modified: cfe/trunk/lib/CodeGen/CGCall.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=366422&r1=366421&r2=366422&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/CodeGen/CGCall.cpp (original) >>> +++ cfe/trunk/lib/CodeGen/CGCall.cpp Thu Jul 18 03:04:18 2019 >>> @@ -3502,7 +3502,7 @@ struct DestroyUnpassedArg final : EHScop >>> const CXXDestructorDecl *Dtor = >>> Ty->getAsCXXRecordDecl()->getDestructor(); >>> assert(!Dtor->isTrivial()); >>> CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*for vbase*/ >>> false, >>> - /*Delegating=*/false, Addr); >>> + /*Delegating=*/false, Addr, Ty); >>> } else { >>> CGF.callCStructDestructor(CGF.MakeAddrLValue(Addr, Ty)); >>> } >>> >>> Modified: cfe/trunk/lib/CodeGen/CGClass.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=366422&r1=366421&r2=366422&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/CodeGen/CGClass.cpp (original) >>> +++ cfe/trunk/lib/CodeGen/CGClass.cpp Thu Jul 18 03:04:18 2019 >>> @@ -491,12 +491,15 @@ namespace { >>> cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent(); >>> >>> const CXXDestructorDecl *D = BaseClass->getDestructor(); >>> + // We are already inside a destructor, so presumably the object >>> being >>> + // destroyed should have the expected type. >>> + QualType ThisTy = D->getThisObjectType(); >>> Address Addr = >>> >>> CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThisAddress(), >>> DerivedClass, >>> BaseClass, >>> BaseIsVirtual); >>> CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual, >>> - /*Delegating=*/false, Addr); >>> + /*Delegating=*/false, Addr, ThisTy); >>> } >>> }; >>> >>> @@ -1440,9 +1443,11 @@ void CodeGenFunction::EmitDestructorBody >>> if (DtorType == Dtor_Deleting) { >>> RunCleanupsScope DtorEpilogue(*this); >>> EnterDtorCleanups(Dtor, Dtor_Deleting); >>> - if (HaveInsertPoint()) >>> + if (HaveInsertPoint()) { >>> + QualType ThisTy = Dtor->getThisObjectType(); >>> EmitCXXDestructorCall(Dtor, Dtor_Complete, >>> /*ForVirtualBase=*/false, >>> - /*Delegating=*/false, LoadCXXThisAddress()); >>> + /*Delegating=*/false, LoadCXXThisAddress(), >>> ThisTy); >>> + } >>> return; >>> } >>> >>> @@ -1473,8 +1478,9 @@ void CodeGenFunction::EmitDestructorBody >>> EnterDtorCleanups(Dtor, Dtor_Complete); >>> >>> if (!isTryBody) { >>> + QualType ThisTy = Dtor->getThisObjectType(); >>> EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false, >>> - /*Delegating=*/false, LoadCXXThisAddress()); >>> + /*Delegating=*/false, LoadCXXThisAddress(), >>> ThisTy); >>> break; >>> } >>> >>> @@ -2013,7 +2019,7 @@ void CodeGenFunction::destroyCXXObject(C >>> const CXXDestructorDecl *dtor = record->getDestructor(); >>> assert(!dtor->isTrivial()); >>> CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false, >>> - /*Delegating=*/false, addr); >>> + /*Delegating=*/false, addr, type); >>> } >>> >>> void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl >>> *D, >>> @@ -2363,8 +2369,11 @@ namespace { >>> : Dtor(D), Addr(Addr), Type(Type) {} >>> >>> void Emit(CodeGenFunction &CGF, Flags flags) override { >>> + // We are calling the destructor from within the constructor. >>> + // Therefore, "this" should have the expected type. >>> + QualType ThisTy = Dtor->getThisObjectType(); >>> CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false, >>> - /*Delegating=*/true, Addr); >>> + /*Delegating=*/true, Addr, ThisTy); >>> } >>> }; >>> } // end anonymous namespace >>> @@ -2402,31 +2411,32 @@ CodeGenFunction::EmitDelegatingCXXConstr >>> void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD, >>> CXXDtorType Type, >>> bool ForVirtualBase, >>> - bool Delegating, >>> - Address This) { >>> + bool Delegating, Address >>> This, >>> + QualType ThisTy) { >>> CGM.getCXXABI().EmitDestructorCall(*this, DD, Type, ForVirtualBase, >>> - Delegating, This); >>> + Delegating, This, ThisTy); >>> } >>> >>> namespace { >>> struct CallLocalDtor final : EHScopeStack::Cleanup { >>> const CXXDestructorDecl *Dtor; >>> Address Addr; >>> + QualType Ty; >>> >>> - CallLocalDtor(const CXXDestructorDecl *D, Address Addr) >>> - : Dtor(D), Addr(Addr) {} >>> + CallLocalDtor(const CXXDestructorDecl *D, Address Addr, QualType Ty) >>> + : Dtor(D), Addr(Addr), Ty(Ty) {} >>> >>> void Emit(CodeGenFunction &CGF, Flags flags) override { >>> CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, >>> /*ForVirtualBase=*/false, >>> - /*Delegating=*/false, Addr); >>> + /*Delegating=*/false, Addr, Ty); >>> } >>> }; >>> } // end anonymous namespace >>> >>> void CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D, >>> - Address Addr) { >>> - EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr); >>> + QualType T, Address Addr) { >>> + EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr, T); >>> } >>> >>> void CodeGenFunction::PushDestructorCleanup(QualType T, Address Addr) { >>> @@ -2436,7 +2446,7 @@ void CodeGenFunction::PushDestructorClea >>> >>> const CXXDestructorDecl *D = ClassDecl->getDestructor(); >>> assert(D && D->isUsed() && "destructor not marked as used!"); >>> - PushDestructorCleanup(D, Addr); >>> + PushDestructorCleanup(D, T, Addr); >>> } >>> >>> void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) { >>> >>> Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=366422&r1=366421&r2=366422&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original) >>> +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Thu Jul 18 03:04:18 2019 >>> @@ -480,11 +480,12 @@ namespace { >>> >>> template <class Derived> >>> struct DestroyNRVOVariable : EHScopeStack::Cleanup { >>> - DestroyNRVOVariable(Address addr, llvm::Value *NRVOFlag) >>> - : NRVOFlag(NRVOFlag), Loc(addr) {} >>> + DestroyNRVOVariable(Address addr, QualType type, llvm::Value >>> *NRVOFlag) >>> + : NRVOFlag(NRVOFlag), Loc(addr), Ty(type) {} >>> >>> llvm::Value *NRVOFlag; >>> Address Loc; >>> + QualType Ty; >>> >>> void Emit(CodeGenFunction &CGF, Flags flags) override { >>> // Along the exceptions path we always execute the dtor. >>> @@ -511,26 +512,24 @@ namespace { >>> >>> struct DestroyNRVOVariableCXX final >>> : DestroyNRVOVariable<DestroyNRVOVariableCXX> { >>> - DestroyNRVOVariableCXX(Address addr, const CXXDestructorDecl *Dtor, >>> - llvm::Value *NRVOFlag) >>> - : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr, NRVOFlag), >>> - Dtor(Dtor) {} >>> + DestroyNRVOVariableCXX(Address addr, QualType type, >>> + const CXXDestructorDecl *Dtor, llvm::Value >>> *NRVOFlag) >>> + : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr, type, >>> NRVOFlag), >>> + Dtor(Dtor) {} >>> >>> const CXXDestructorDecl *Dtor; >>> >>> void emitDestructorCall(CodeGenFunction &CGF) { >>> CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, >>> /*ForVirtualBase=*/false, >>> - /*Delegating=*/false, Loc); >>> + /*Delegating=*/false, Loc, Ty); >>> } >>> }; >>> >>> struct DestroyNRVOVariableC final >>> : DestroyNRVOVariable<DestroyNRVOVariableC> { >>> DestroyNRVOVariableC(Address addr, llvm::Value *NRVOFlag, QualType >>> Ty) >>> - : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, NRVOFlag), >>> Ty(Ty) {} >>> - >>> - QualType Ty; >>> + : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, Ty, NRVOFlag) >>> {} >>> >>> void emitDestructorCall(CodeGenFunction &CGF) { >>> CGF.destroyNonTrivialCStruct(CGF, Loc, Ty); >>> @@ -1940,7 +1939,7 @@ void CodeGenFunction::emitAutoVarTypeCle >>> if (emission.NRVOFlag) { >>> assert(!type->isArrayType()); >>> CXXDestructorDecl *dtor = >>> type->getAsCXXRecordDecl()->getDestructor(); >>> - EHStack.pushCleanup<DestroyNRVOVariableCXX>(cleanupKind, addr, >>> dtor, >>> + EHStack.pushCleanup<DestroyNRVOVariableCXX>(cleanupKind, addr, >>> type, dtor, >>> emission.NRVOFlag); >>> return; >>> } >>> >>> Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=366422&r1=366421&r2=366422&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original) >>> +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Thu Jul 18 03:04:18 2019 >>> @@ -10,12 +10,13 @@ >>> // >>> >>> >>> //===----------------------------------------------------------------------===// >>> >>> -#include "CodeGenFunction.h" >>> #include "CGCUDARuntime.h" >>> #include "CGCXXABI.h" >>> #include "CGDebugInfo.h" >>> #include "CGObjCRuntime.h" >>> +#include "CodeGenFunction.h" >>> #include "ConstantEmitter.h" >>> +#include "TargetInfo.h" >>> #include "clang/Basic/CodeGenOptions.h" >>> #include "clang/CodeGen/CGFunctionInfo.h" >>> #include "llvm/IR/Intrinsics.h" >>> @@ -90,12 +91,26 @@ RValue CodeGenFunction::EmitCXXMemberOrO >>> } >>> >>> RValue CodeGenFunction::EmitCXXDestructorCall( >>> - GlobalDecl Dtor, const CGCallee &Callee, llvm::Value *This, >>> + GlobalDecl Dtor, const CGCallee &Callee, llvm::Value *This, >>> QualType ThisTy, >>> llvm::Value *ImplicitParam, QualType ImplicitParamTy, const >>> CallExpr *CE) { >>> + const CXXMethodDecl *DtorDecl = cast<CXXMethodDecl>(Dtor.getDecl()); >>> + >>> + assert(!ThisTy.isNull()); >>> + assert(ThisTy->getAsCXXRecordDecl() == DtorDecl->getParent() && >>> + "Pointer/Object mixup"); >>> + >>> + LangAS SrcAS = ThisTy.getAddressSpace(); >>> + LangAS DstAS = DtorDecl->getMethodQualifiers().getAddressSpace(); >>> + if (SrcAS != DstAS) { >>> + QualType DstTy = DtorDecl->getThisType(); >>> + llvm::Type *NewType = CGM.getTypes().ConvertType(DstTy); >>> + This = getTargetHooks().performAddrSpaceCast(*this, This, SrcAS, >>> DstAS, >>> + NewType); >>> + } >>> + >>> CallArgList Args; >>> - commonEmitCXXMemberOrOperatorCall(*this, >>> cast<CXXMethodDecl>(Dtor.getDecl()), >>> - This, ImplicitParam, >>> ImplicitParamTy, CE, >>> - Args, nullptr); >>> + commonEmitCXXMemberOrOperatorCall(*this, DtorDecl, This, >>> ImplicitParam, >>> + ImplicitParamTy, CE, Args, nullptr); >>> return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(Dtor), >>> Callee, >>> ReturnValueSlot(), Args); >>> } >>> @@ -345,7 +360,9 @@ RValue CodeGenFunction::EmitCXXMemberOrO >>> Callee = CGCallee::forDirect(CGM.GetAddrOfFunction(GD, Ty), GD); >>> } >>> >>> - EmitCXXDestructorCall(GD, Callee, This.getPointer(), >>> + QualType ThisTy = >>> + IsArrow ? Base->getType()->getPointeeType() : Base->getType(); >>> + EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, >>> /*ImplicitParam=*/nullptr, >>> /*ImplicitParamTy=*/QualType(), nullptr); >>> } >>> @@ -1883,7 +1900,7 @@ static void EmitObjectDelete(CodeGenFunc >>> CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, >>> /*ForVirtualBase=*/false, >>> /*Delegating=*/false, >>> - Ptr); >>> + Ptr, ElementType); >>> else if (auto Lifetime = ElementType.getObjCLifetime()) { >>> switch (Lifetime) { >>> case Qualifiers::OCL_None: >>> >>> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=366422&r1=366421&r2=366422&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original) >>> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Jul 18 03:04:18 2019 >>> @@ -675,7 +675,8 @@ public: >>> /// PushDestructorCleanup - Push a cleanup to call the >>> /// complete-object variant of the given destructor on the object at >>> /// the given address. >>> - void PushDestructorCleanup(const CXXDestructorDecl *Dtor, Address >>> Addr); >>> + void PushDestructorCleanup(const CXXDestructorDecl *Dtor, QualType T, >>> + Address Addr); >>> >>> /// PopCleanupBlock - Will pop the cleanup entry on the stack and >>> /// process all branch fixups. >>> @@ -2554,8 +2555,8 @@ public: >>> static Destroyer destroyCXXObject; >>> >>> void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType >>> Type, >>> - bool ForVirtualBase, bool Delegating, >>> - Address This); >>> + bool ForVirtualBase, bool Delegating, >>> Address This, >>> + QualType ThisTy); >>> >>> void EmitNewArrayInitializer(const CXXNewExpr *E, QualType >>> elementType, >>> llvm::Type *ElementTy, Address NewPtr, >>> @@ -3677,9 +3678,9 @@ public: >>> llvm::Value *ImplicitParam, >>> QualType ImplicitParamTy, const CallExpr >>> *E, >>> CallArgList *RtlArgs); >>> - RValue EmitCXXDestructorCall(GlobalDecl Dtor, >>> - const CGCallee &Callee, >>> - llvm::Value *This, llvm::Value >>> *ImplicitParam, >>> + RValue EmitCXXDestructorCall(GlobalDecl Dtor, const CGCallee &Callee, >>> + llvm::Value *This, QualType ThisTy, >>> + llvm::Value *ImplicitParam, >>> QualType ImplicitParamTy, const CallExpr >>> *E); >>> RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E, >>> ReturnValueSlot ReturnValue); >>> >>> Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=366422&r1=366421&r2=366422&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original) >>> +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Thu Jul 18 03:04:18 2019 >>> @@ -224,7 +224,8 @@ public: >>> >>> void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl >>> *DD, >>> CXXDtorType Type, bool ForVirtualBase, >>> - bool Delegating, Address This) override; >>> + bool Delegating, Address This, >>> + QualType ThisTy) override; >>> >>> void emitVTableDefinitions(CodeGenVTables &CGVT, >>> const CXXRecordDecl *RD) override; >>> @@ -261,9 +262,8 @@ public: >>> >>> llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF, >>> const CXXDestructorDecl *Dtor, >>> - CXXDtorType DtorType, >>> - Address This, >>> - const CXXMemberCallExpr *CE) >>> override; >>> + CXXDtorType DtorType, Address >>> This, >>> + DeleteOrMemberCallExpr E) >>> override; >>> >>> void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override; >>> >>> @@ -1128,7 +1128,7 @@ void ItaniumCXXABI::emitVirtualObjectDel >>> // FIXME: Provide a source location here even though there's no >>> // CXXMemberCallExpr for dtor call. >>> CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : >>> Dtor_Deleting; >>> - EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, /*CE=*/nullptr); >>> + EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE); >>> >>> if (UseGlobalDelete) >>> CGF.PopCleanupBlock(); >>> @@ -1539,7 +1539,8 @@ CGCXXABI::AddedStructorArgs ItaniumCXXAB >>> void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF, >>> const CXXDestructorDecl *DD, >>> CXXDtorType Type, bool >>> ForVirtualBase, >>> - bool Delegating, Address This) { >>> + bool Delegating, Address This, >>> + QualType ThisTy) { >>> GlobalDecl GD(DD, Type); >>> llvm::Value *VTT = CGF.GetVTTParameter(GD, ForVirtualBase, >>> Delegating); >>> QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy); >>> @@ -1551,7 +1552,8 @@ void ItaniumCXXABI::EmitDestructorCall(C >>> else >>> Callee = CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD), GD); >>> >>> - CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), VTT, VTTTy, >>> nullptr); >>> + CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, VTT, >>> VTTTy, >>> + nullptr); >>> } >>> >>> void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, >>> @@ -1739,7 +1741,10 @@ CGCallee ItaniumCXXABI::getVirtualFuncti >>> >>> llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall( >>> CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType >>> DtorType, >>> - Address This, const CXXMemberCallExpr *CE) { >>> + Address This, DeleteOrMemberCallExpr E) { >>> + auto *CE = E.dyn_cast<const CXXMemberCallExpr *>(); >>> + auto *D = E.dyn_cast<const CXXDeleteExpr *>(); >>> + assert((CE != nullptr) ^ (D != nullptr)); >>> assert(CE == nullptr || CE->arg_begin() == CE->arg_end()); >>> assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); >>> >>> @@ -1749,8 +1754,14 @@ llvm::Value *ItaniumCXXABI::EmitVirtualD >>> llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo); >>> CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty); >>> >>> - CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), nullptr, >>> QualType(), >>> - nullptr); >>> + QualType ThisTy; >>> + if (CE) >>> + ThisTy = >>> CE->getImplicitObjectArgument()->getType()->getPointeeType(); >>> + else >>> + ThisTy = D->getDestroyedType(); >>> + >>> + CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, >>> nullptr, >>> + QualType(), nullptr); >>> return nullptr; >>> } >>> >>> >>> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=366422&r1=366421&r2=366422&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original) >>> +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Thu Jul 18 03:04:18 2019 >>> @@ -258,7 +258,8 @@ public: >>> >>> void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl >>> *DD, >>> CXXDtorType Type, bool ForVirtualBase, >>> - bool Delegating, Address This) override; >>> + bool Delegating, Address This, >>> + QualType ThisTy) override; >>> >>> void emitVTableTypeMetadata(const VPtrInfo &Info, const CXXRecordDecl >>> *RD, >>> llvm::GlobalVariable *VTable); >>> @@ -296,9 +297,8 @@ public: >>> >>> llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF, >>> const CXXDestructorDecl *Dtor, >>> - CXXDtorType DtorType, >>> - Address This, >>> - const CXXMemberCallExpr *CE) >>> override; >>> + CXXDtorType DtorType, Address >>> This, >>> + DeleteOrMemberCallExpr E) >>> override; >>> >>> void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, >>> GlobalDecl GD, >>> CallArgList &CallArgs) override >>> { >>> @@ -844,8 +844,7 @@ void MicrosoftCXXABI::emitVirtualObjectD >>> // CXXMemberCallExpr for dtor call. >>> bool UseGlobalDelete = DE->isGlobalDelete(); >>> CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : >>> Dtor_Deleting; >>> - llvm::Value *MDThis = >>> - EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, >>> /*CE=*/nullptr); >>> + llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, >>> Ptr, DE); >>> if (UseGlobalDelete) >>> CGF.EmitDeleteCall(DE->getOperatorDelete(), MDThis, ElementType); >>> } >>> @@ -1569,7 +1568,8 @@ CGCXXABI::AddedStructorArgs MicrosoftCXX >>> void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF, >>> const CXXDestructorDecl *DD, >>> CXXDtorType Type, bool >>> ForVirtualBase, >>> - bool Delegating, Address This) >>> { >>> + bool Delegating, Address This, >>> + QualType ThisTy) { >>> // Use the base destructor variant in place of the complete >>> destructor variant >>> // if the class has no virtual bases. This effectively implements >>> some of the >>> // -mconstructor-aliases optimization, but as part of the MS C++ ABI. >>> @@ -1591,7 +1591,7 @@ void MicrosoftCXXABI::EmitDestructorCall >>> BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF); >>> } >>> >>> - CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), >>> + CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, >>> /*ImplicitParam=*/nullptr, >>> /*ImplicitParamTy=*/QualType(), nullptr); >>> if (BaseDtorEndBB) { >>> @@ -1900,7 +1900,10 @@ CGCallee MicrosoftCXXABI::getVirtualFunc >>> >>> llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall( >>> CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType >>> DtorType, >>> - Address This, const CXXMemberCallExpr *CE) { >>> + Address This, DeleteOrMemberCallExpr E) { >>> + auto *CE = E.dyn_cast<const CXXMemberCallExpr *>(); >>> + auto *D = E.dyn_cast<const CXXDeleteExpr *>(); >>> + assert((CE != nullptr) ^ (D != nullptr)); >>> assert(CE == nullptr || CE->arg_begin() == CE->arg_end()); >>> assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete); >>> >>> @@ -1917,8 +1920,14 @@ llvm::Value *MicrosoftCXXABI::EmitVirtua >>> llvm::IntegerType::getInt32Ty(CGF.getLLVMContext()), >>> DtorType == Dtor_Deleting); >>> >>> + QualType ThisTy; >>> + if (CE) >>> + ThisTy = >>> CE->getImplicitObjectArgument()->getType()->getPointeeType(); >>> + else >>> + ThisTy = D->getDestroyedType(); >>> + >>> This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true); >>> - RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), >>> + RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), >>> ThisTy, >>> ImplicitParam, Context.IntTy, >>> CE); >>> return RV.getScalarVal(); >>> } >>> >>> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=366422&r1=366421&r2=366422&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) >>> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jul 18 03:04:18 2019 >>> @@ -8190,6 +8190,27 @@ void Sema::ActOnFinishDelayedCXXMethodDe >>> CheckCXXDefaultArguments(Method); >>> } >>> >>> +// Emit the given diagnostic for each non-address-space qualifier. >>> +// Common part of CheckConstructorDeclarator and >>> CheckDestructorDeclarator. >>> +static void checkMethodTypeQualifiers(Sema &S, Declarator &D, unsigned >>> DiagID) { >>> + const DeclaratorChunk::FunctionTypeInfo &FTI = >>> D.getFunctionTypeInfo(); >>> + if (FTI.hasMethodTypeQualifiers() && !D.isInvalidType()) { >>> + bool DiagOccured = false; >>> + FTI.MethodQualifiers->forEachQualifier( >>> + [DiagID, &S, &DiagOccured](DeclSpec::TQ, StringRef QualName, >>> + SourceLocation SL) { >>> + // This diagnostic should be emitted on any qualifier except >>> an addr >>> + // space qualifier. However, forEachQualifier currently >>> doesn't visit >>> + // addr space qualifiers, so there's no way to write this >>> condition >>> + // right now; we just diagnose on everything. >>> + S.Diag(SL, DiagID) << QualName << SourceRange(SL); >>> + DiagOccured = true; >>> + }); >>> + if (DiagOccured) >>> + D.setInvalidType(); >>> + } >>> +} >>> + >>> /// CheckConstructorDeclarator - Called by ActOnDeclarator to check >>> /// the well-formedness of the constructor declarator @p D with type @p >>> /// R. If there are any errors in the declarator, this routine will >>> @@ -8230,25 +8251,11 @@ QualType Sema::CheckConstructorDeclarato >>> D.setInvalidType(); >>> } >>> >>> - DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); >>> - if (FTI.hasMethodTypeQualifiers()) { >>> - bool DiagOccured = false; >>> - FTI.MethodQualifiers->forEachQualifier( >>> - [&](DeclSpec::TQ TypeQual, StringRef QualName, SourceLocation >>> SL) { >>> - // This diagnostic should be emitted on any qualifier except >>> an addr >>> - // space qualifier. However, forEachQualifier currently >>> doesn't visit >>> - // addr space qualifiers, so there's no way to write this >>> condition >>> - // right now; we just diagnose on everything. >>> - Diag(SL, diag::err_invalid_qualified_constructor) >>> - << QualName << SourceRange(SL); >>> - DiagOccured = true; >>> - }); >>> - if (DiagOccured) >>> - D.setInvalidType(); >>> - } >>> + checkMethodTypeQualifiers(*this, D, >>> diag::err_invalid_qualified_constructor); >>> >>> // C++0x [class.ctor]p4: >>> // A constructor shall not be declared with a ref-qualifier. >>> + DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); >>> if (FTI.hasRefQualifier()) { >>> Diag(FTI.getRefQualifierLoc(), diag::err_ref_qualifier_constructor) >>> << FTI.RefQualifierIsLValueRef >>> @@ -8423,18 +8430,11 @@ QualType Sema::CheckDestructorDeclarator >>> } >>> } >>> >>> - DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); >>> - if (FTI.hasMethodTypeQualifiers() && !D.isInvalidType()) { >>> - FTI.MethodQualifiers->forEachQualifier( >>> - [&](DeclSpec::TQ TypeQual, StringRef QualName, SourceLocation >>> SL) { >>> - Diag(SL, diag::err_invalid_qualified_destructor) >>> - << QualName << SourceRange(SL); >>> - }); >>> - D.setInvalidType(); >>> - } >>> + checkMethodTypeQualifiers(*this, D, >>> diag::err_invalid_qualified_destructor); >>> >>> // C++0x [class.dtor]p2: >>> // A destructor shall not be declared with a ref-qualifier. >>> + DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); >>> if (FTI.hasRefQualifier()) { >>> Diag(FTI.getRefQualifierLoc(), diag::err_ref_qualifier_destructor) >>> << FTI.RefQualifierIsLValueRef >>> >>> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=366422&r1=366421&r2=366422&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) >>> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Jul 18 03:04:18 2019 >>> @@ -5093,12 +5093,10 @@ TryObjectArgumentInitialization(Sema &S, >>> QualType ClassType = S.Context.getTypeDeclType(ActingContext); >>> // [class.dtor]p2: A destructor can be invoked for a const, volatile >>> or >>> // const volatile object. >>> - Qualifiers Quals; >>> + Qualifiers Quals = Method->getMethodQualifiers(); >>> if (isa<CXXDestructorDecl>(Method)) { >>> Quals.addConst(); >>> Quals.addVolatile(); >>> - } else { >>> - Quals = Method->getMethodQualifiers(); >>> } >>> >>> QualType ImplicitParamType = S.Context.getQualifiedType(ClassType, >>> Quals); >>> >>> Removed: cfe/trunk/test/CodeGenOpenCLCXX/addrspace-ctor.cl >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCLCXX/addrspace-ctor.cl?rev=366421&view=auto >>> >>> ============================================================================== >>> --- cfe/trunk/test/CodeGenOpenCLCXX/addrspace-ctor.cl (original) >>> +++ cfe/trunk/test/CodeGenOpenCLCXX/addrspace-ctor.cl (removed) >>> @@ -1,14 +0,0 @@ >>> -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ >>> -emit-llvm -O0 -o - | FileCheck %s >>> - >>> -struct MyType { >>> - MyType(int i) : i(i) {} >>> - MyType(int i) __constant : i(i) {} >>> - int i; >>> -}; >>> - >>> -//CHECK: call void @_ZNU3AS26MyTypeC1Ei(%struct.MyType addrspace(2)* >>> @const1, i32 1) >>> -__constant MyType const1 = 1; >>> -//CHECK: call void @_ZNU3AS26MyTypeC1Ei(%struct.MyType addrspace(2)* >>> @const2, i32 2) >>> -__constant MyType const2(2); >>> -//CHECK: call void @_ZNU3AS46MyTypeC1Ei(%struct.MyType addrspace(4)* >>> addrspacecast (%struct.MyType addrspace(1)* @glob to %struct.MyType >>> addrspace(4)*), i32 1) >>> -MyType glob(1); >>> >>> Added: cfe/trunk/test/CodeGenOpenCLCXX/addrspace-with-class.cl >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCLCXX/addrspace-with-class.cl?rev=366422&view=auto >>> >>> ============================================================================== >>> --- cfe/trunk/test/CodeGenOpenCLCXX/addrspace-with-class.cl (added) >>> +++ cfe/trunk/test/CodeGenOpenCLCXX/addrspace-with-class.cl Thu Jul 18 >>> 03:04:18 2019 >>> @@ -0,0 +1,59 @@ >>> +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ >>> -emit-llvm -O0 -o - | FileCheck %s >>> +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ >>> -emit-llvm -O0 -o - | FileCheck %s --check-prefix=CHECK-DEFINITIONS >>> + >>> +// This test ensures the proper address spaces and address space cast >>> are used >>> +// for constructors, member functions and destructors. >>> +// See also atexit.cl and global_init.cl for other specific tests. >>> + >>> +// CHECK: %struct.MyType = type { i32 } >>> +struct MyType { >>> + MyType(int i) : i(i) {} >>> + MyType(int i) __constant : i(i) {} >>> + ~MyType() {} >>> + ~MyType() __constant {} >>> + int bar() { return i + 2; } >>> + int bar() __constant { return i + 1; } >>> + int i; >>> +}; >>> + >>> +// CHECK: @const1 = addrspace(2) global %struct.MyType zeroinitializer >>> +__constant MyType const1 = 1; >>> +// CHECK: @const2 = addrspace(2) global %struct.MyType zeroinitializer >>> +__constant MyType const2(2); >>> +// CHECK: @glob = addrspace(1) global %struct.MyType zeroinitializer >>> +MyType glob(1); >>> + >>> +// CHECK: call void @_ZNU3AS26MyTypeC1Ei(%struct.MyType addrspace(2)* >>> @const1, i32 1) >>> +// CHECK: call void @_ZNU3AS26MyTypeC1Ei(%struct.MyType addrspace(2)* >>> @const2, i32 2) >>> +// CHECK: call void @_ZNU3AS46MyTypeC1Ei(%struct.MyType addrspace(4)* >>> addrspacecast (%struct.MyType addrspace(1)* @glob to %struct.MyType >>> addrspace(4)*), i32 1) >>> + >>> +// CHECK-LABEL: define spir_kernel void @fooGlobal() >>> +kernel void fooGlobal() { >>> + // CHECK: call i32 @_ZNU3AS46MyType3barEv(%struct.MyType >>> addrspace(4)* addrspacecast (%struct.MyType addrspace(1)* @glob to >>> %struct.MyType addrspace(4)*)) >>> + glob.bar(); >>> + // CHECK: call i32 @_ZNU3AS26MyType3barEv(%struct.MyType >>> addrspace(2)* @const1) >>> + const1.bar(); >>> + // CHECK: call void @_ZNU3AS26MyTypeD1Ev(%struct.MyType addrspace(2)* >>> @const1) >>> + const1.~MyType(); >>> +} >>> + >>> +// CHECK-LABEL: define spir_kernel void @fooLocal() >>> +kernel void fooLocal() { >>> + // CHECK: [[VAR:%.*]] = alloca %struct.MyType >>> + // CHECK: [[REG:%.*]] = addrspacecast %struct.MyType* [[VAR]] to >>> %struct.MyType addrspace(4)* >>> + // CHECK: call void @_ZNU3AS46MyTypeC1Ei(%struct.MyType addrspace(4)* >>> [[REG]], i32 3) >>> + MyType myLocal(3); >>> + // CHECK: [[REG:%.*]] = addrspacecast %struct.MyType* [[VAR]] to >>> %struct.MyType addrspace(4)* >>> + // CHECK: call i32 @_ZNU3AS46MyType3barEv(%struct.MyType >>> addrspace(4)* [[REG]]) >>> + myLocal.bar(); >>> + // CHECK: [[REG:%.*]] = addrspacecast %struct.MyType* [[VAR]] to >>> %struct.MyType addrspace(4)* >>> + // CHECK: call void @_ZNU3AS46MyTypeD1Ev(%struct.MyType addrspace(4)* >>> [[REG]]) >>> +} >>> + >>> +// Ensure all members are defined for all the required address spaces. >>> +// CHECK-DEFINITIONS-DAG: define linkonce_odr void >>> @_ZNU3AS26MyTypeC1Ei(%struct.MyType addrspace(2)* %this, i32 %i) >>> +// CHECK-DEFINITIONS-DAG: define linkonce_odr void >>> @_ZNU3AS46MyTypeC1Ei(%struct.MyType addrspace(4)* %this, i32 %i) >>> +// CHECK-DEFINITIONS-DAG: define linkonce_odr void >>> @_ZNU3AS26MyTypeD1Ev(%struct.MyType addrspace(2)* %this) >>> +// CHECK-DEFINITIONS-DAG: define linkonce_odr void >>> @_ZNU3AS46MyTypeD1Ev(%struct.MyType addrspace(4)* %this) >>> +// CHECK-DEFINITIONS-DAG: define linkonce_odr i32 >>> @_ZNU3AS26MyType3barEv(%struct.MyType addrspace(2)* %this) >>> +// CHECK-DEFINITIONS-DAG: define linkonce_odr i32 >>> @_ZNU3AS46MyType3barEv(%struct.MyType addrspace(4)* %this) >>> >>> >>> _______________________________________________ >>> cfe-commits mailing list >>> cfe-commits@lists.llvm.org >>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>> >> >> >> -- >> Regards, >> Ilya Biryukov >> > > > -- > Regards, > Ilya Biryukov > -- Regards, Ilya Biryukov
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits