<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Hi Ilya,</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Thanks for the reproducer, I will have a look. Mind the fact that the revert was done after the v10 bump -- I'm not 100% of the implication so I prefer to mention it just in case. Because this is something that matters for C++ for OpenCL, I'll try to find at
 least a workaround for now.</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Cheers,<br>
Marco</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Ilya Biryukov <ibiryukov@google.com><br>
<b>Sent:</b> 18 July 2019 12:47<br>
<b>To:</b> Marco Antognini <Marco.Antognini@arm.com><br>
<b>Cc:</b> cfe-commits <cfe-commits@lists.llvm.org><br>
<b>Subject:</b> Re: r366422 - [OpenCL] Improve destructor support in C++ for OpenCL</font>
<div> </div>
</div>
<div>
<div dir="ltr">Hi Marco,
<div><br>
</div>
<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 style="color:rgb(80,0,80)">
</div>
</div>
<div>See the details in the following bug: <a href="https://bugs.llvm.org/show_bug.cgi?id=42665">https://bugs.llvm.org/show_bug.cgi?id=42665</a><br>
</div>
</div>
<br>
<div class="x_gmail_quote">
<div dir="ltr" class="x_gmail_attr">On Thu, Jul 18, 2019 at 1:42 PM Ilya Biryukov <<a href="mailto:ibiryukov@google.com">ibiryukov@google.com</a>> wrote:<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<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.</div>
<div><br>
</div>
<div>(Previous email seems to be in queue for moderation, it's probably too large)</div>
<div><br>
</div>
</div>
<br>
<div class="x_gmail_quote">
<div dir="ltr" class="x_gmail_attr">On Thu, Jul 18, 2019 at 1:39 PM Ilya Biryukov <<a href="mailto:ibiryukov@google.com" target="_blank">ibiryukov@google.com</a>> wrote:<br>
</div>
<blockquote class="x_gmail_quote" style="margin:0px 0px 0px 0.8ex; border-left:1px solid rgb(204,204,204); padding-left:1ex">
<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" target="_blank">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/" target="_blank">
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="x_gmail_quote">
<div dir="ltr" class="x_gmail_attr">On Thu, Jul 18, 2019 at 12:03 PM Marco Antognini via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br>
</div>
<blockquote class="x_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="x_gmail-m_6946003740007346744gmail-m_-7977194359407910471gmail_signature">
<div dir="ltr">
<div>
<div dir="ltr">
<div>Regards,</div>
<div>Ilya Biryukov</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
<br clear="all">
<div><br>
</div>
-- <br>
<div dir="ltr" class="x_gmail-m_6946003740007346744gmail_signature">
<div dir="ltr">
<div>
<div dir="ltr">
<div>Regards,</div>
<div>Ilya Biryukov</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
<br clear="all">
<div><br>
</div>
-- <br>
<div dir="ltr" class="x_gmail_signature">
<div dir="ltr">
<div>
<div dir="ltr">
<div>Regards,</div>
<div>Ilya Biryukov</div>
</div>
</div>
</div>
</div>
</div>
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose,
 or store or copy the information in any medium. Thank you.
</body>
</html>