r366422 - [OpenCL] Improve destructor support in C++ for OpenCL

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 18 04:42:04 PDT 2019


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 <ibiryukov at 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 at 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 at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>
>
> --
> Regards,
> Ilya Biryukov
>


-- 
Regards,
Ilya Biryukov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190718/f182fb03/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bugreport.tgz
Type: application/x-compressed-tar
Size: 576572 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190718/f182fb03/attachment-0001.bin>


More information about the cfe-commits mailing list