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

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 18 04:47:22 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.

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


-- 
Regards,
Ilya Biryukov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190718/8c68a131/attachment-0001.html>


More information about the cfe-commits mailing list