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