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

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


Hi Marco,

Your commit crashes clang when building the LLVM Support with libc++
library.
I'll revert the commit to unbreak our integrate.

I've attached the repro with preprocessed files to this email. Here's the
stacktrace too:

clang-9:
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprCXX.cpp:98:
clang::CodeGen::RValue
clang::CodeGen::CodeGenFunction::EmitCXXDestructorCall(clang::GlobalDecl,
const clang::CodeGen::CGCallee &, llvm::Value *, clang::QualType,
llvm::Value *, clang::QualType, const clang::CallExpr *): Assertion
`!ThisTy.isNull()' failed.
Stack dump:
0.      Program arguments:
/usr/local/google/home/ibiryukov/projects/llvm/build-rel/bin/clang-9 -cc1
-triple x86_64-unknown-linux-gnu -emit-obj -disable-free -main-file-name
BinaryStreamRef.cpp -mrelocation-model pic -pic-level 2 -mthread-model
posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables
-fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb
-ffunction-sections -fdata-sections -coverage-notes-file
/usr/local/google/home/ibiryukov/projects/llvm/build-stage2-from-rel/lib/Support/CMakeFiles/LLVMSupport.dir/BinaryStreamRef.cpp.gcno
-nostdinc++ -resource-dir
/usr/local/google/home/ibiryukov/projects/llvm/build-rel/lib/clang/9.0.0
-dependency-file
lib/Support/CMakeFiles/LLVMSupport.dir/BinaryStreamRef.cpp.o.d
-sys-header-deps -MT
lib/Support/CMakeFiles/LLVMSupport.dir/BinaryStreamRef.cpp.o -D
GTEST_HAS_RTTI=0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D
__STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I lib/Support -I
/usr/local/google/home/ibiryukov/projects/llvm/llvm/lib/Support -I
/usr/include/libxml2 -I include -I
/usr/local/google/home/ibiryukov/projects/llvm/llvm/include -I
/usr/lib/libcxx-google/include/c++/v1/ -U NDEBUG -internal-isystem
/usr/local/include -internal-isystem
/usr/local/google/home/ibiryukov/projects/llvm/build-rel/lib/clang/9.0.0/include
-internal-externc-isystem /usr/include/x86_64-linux-gnu
-internal-externc-isystem /include -internal-externc-isystem /usr/include
-O3 -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra
-Wno-unused-parameter -Wwrite-strings -Wcast-qual
-Wmissing-field-initializers -Wno-long-long -Wimplicit-fallthrough
-Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor
-Wdelete-non-virtual-dtor -Wstring-conversion -pedantic -std=c++11
-fdeprecated-macro -fdebug-compilation-dir
/usr/local/google/home/ibiryukov/projects/llvm/build-stage2-from-rel
-ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fno-rtti
-fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics
-vectorize-loops -vectorize-slp -faddrsig -o
lib/Support/CMakeFiles/LLVMSupport.dir/BinaryStreamRef.cpp.o -x c++
/usr/local/google/home/ibiryukov/projects/llvm/llvm/lib/Support/BinaryStreamRef.cpp
1.      <eof> parser at end of file
2.      Per-file LLVM IR generation
3.      /usr/lib/libcxx-google/include/c++/v1/memory:3698:18: Generating
code for declaration 'std::__1::__shared_ptr_emplace<(anonymous
namespace)::ArrayRefImpl, std::__1::allocator<(anonymous
namespace)::ArrayRefImpl> >::__on_zero_shared'
 #0 0x00000000044ad294 PrintStackTrace
/usr/local/google/home/ibiryukov/projects/llvm/llvm/lib/Support/Unix/Signals.inc:533:13
 #1 0x00000000044ad294 PrintStackTraceSignalHandler(void*)
/usr/local/google/home/ibiryukov/projects/llvm/llvm/lib/Support/Unix/Signals.inc:593:0
 #2 0x00000000044aaf7e llvm::sys::RunSignalHandlers()
/usr/local/google/home/ibiryukov/projects/llvm/llvm/lib/Support/Signals.cpp:69:18
 #3 0x00000000044ad6a8 SignalHandler(int)
/usr/local/google/home/ibiryukov/projects/llvm/llvm/lib/Support/Unix/Signals.inc:385:1
 #4 0x00007f61992e93a0 __restore_rt
(/lib/x86_64-linux-gnu/libpthread.so.0+0x123a0)
 #5 0x00007f6197ddacfb raise (/lib/x86_64-linux-gnu/libc.so.6+0x36cfb)
 #6 0x00007f6197dc58ad abort (/lib/x86_64-linux-gnu/libc.so.6+0x218ad)
 #7 0x00007f6197dc577f (/lib/x86_64-linux-gnu/libc.so.6+0x2177f)
 #8 0x00007f6197dd3542 (/lib/x86_64-linux-gnu/libc.so.6+0x2f542)
 #9 0x00000000048d660e doit
/usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Casting.h:105:5
#10 0x00000000048d660e doit
/usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Casting.h:132:0
#11 0x00000000048d660e doit
/usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Casting.h:122:0
#12 0x00000000048d660e isa<clang::CXXRecordDecl, const clang::DeclContext
*>
/usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Casting.h:142:0
#13 0x00000000048d660e cast<clang::CXXRecordDecl, const clang::DeclContext>
/usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Casting.h:264:0
#14 0x00000000048d660e getParent
/usr/local/google/home/ibiryukov/projects/llvm/clang/include/clang/AST/DeclCXX.h:2238:0
#15 0x00000000048d660e
clang::CodeGen::CodeGenFunction::EmitCXXDestructorCall(clang::GlobalDecl,
clang::CodeGen::CGCallee const&, llvm::Value*, clang::QualType,
llvm::Value*, clang::QualType, clang::CallExpr const*)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprCXX.cpp:99:0
#16 0x00000000049a19da (anonymous
namespace)::ItaniumCXXABI::EmitVirtualDestructorCall(clang::CodeGen::CodeGenFunction&,
clang::CXXDestructorDecl const*, clang::CXXDtorType,
clang::CodeGen::Address, llvm::PointerUnion<clang::CXXDeleteExpr const*,
clang::CXXMemberCallExpr const*>)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/ItaniumCXXABI.cpp:1765:3
#17 0x00000000048d7e61
clang::CodeGen::CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(clang::CallExpr
const*, clang::CXXMethodDecl const*, clang::CodeGen::ReturnValueSlot, bool,
clang::NestedNameSpecifier*, bool, clang::Expr const*)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprCXX.cpp:0:23
#18 0x00000000048d6b54
clang::CodeGen::CodeGenFunction::EmitCXXMemberCallExpr(clang::CXXMemberCallExpr
const*, clang::CodeGen::ReturnValueSlot)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprCXX.cpp:204:1
#19 0x000000000483cf65
clang::CodeGen::CodeGenFunction::EmitCallExpr(clang::CallExpr const*,
clang::CodeGen::ReturnValueSlot)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExpr.cpp:4491:12
#20 0x00000000048ca744 (anonymous
namespace)::ScalarExprEmitter::VisitCallExpr(clang::CallExpr const*)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprScalar.cpp:0:0
#21 0x00000000048ba6c5 Visit
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprScalar.cpp:424:52
#22 0x00000000048ba6c5
clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExprScalar.cpp:4436:0
#23 0x0000000004820e10
clang::CodeGen::CodeGenFunction::EmitAnyExpr(clang::Expr const*,
clang::CodeGen::AggValueSlot, bool)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExpr.cpp:199:24
#24 0x0000000004820db9
clang::CodeGen::CodeGenFunction::EmitIgnoredExpr(clang::Expr const*)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGExpr.cpp:188:1
#25 0x000000000480bd9f GetInsertBlock
/usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/IR/IRBuilder.h:126:47
#26 0x000000000480bd9f
clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*,
llvm::ArrayRef<clang::Attr const*>)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGStmt.cpp:114:0
#27 0x0000000004816890
clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt
const&, bool, clang::CodeGen::AggValueSlot)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CGStmt.cpp:390:22
#28 0x00000000047edc7d getLangOpts
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenFunction.h:1630:51
#29 0x00000000047edc7d
clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl,
llvm::Function*, clang::CodeGen::CGFunctionInfo const&)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenFunction.cpp:1208:0
#30 0x0000000004787623
clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl,
llvm::GlobalValue*)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:4320:3
#31 0x000000000477fd50 isVirtual
/usr/local/google/home/ibiryukov/projects/llvm/clang/include/clang/AST/DeclCXX.h:2158:59
#32 0x000000000477fd50
clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl,
llvm::GlobalValue*)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2751:0
#33 0x0000000004774981 begin
/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:708:45
#34 0x0000000004774981 empty
/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:895:0
#35 0x0000000004774981 clang::CodeGen::CodeGenModule::EmitDeferred()
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2123:0
#36 0x00000000047749a9 begin
/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:708:45
#37 0x00000000047749a9 empty
/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:895:0
#38 0x00000000047749a9 clang::CodeGen::CodeGenModule::EmitDeferred()
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2125:0
#39 0x00000000047749a9 begin
/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:708:45
#40 0x00000000047749a9 empty
/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:895:0
#41 0x00000000047749a9 clang::CodeGen::CodeGenModule::EmitDeferred()
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2125:0
#42 0x00000000047749a9 begin
/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:708:45
#43 0x00000000047749a9 empty
/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:895:0
#44 0x00000000047749a9 clang::CodeGen::CodeGenModule::EmitDeferred()
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2125:0
#45 0x00000000047749a9 begin
/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:708:45
#46 0x00000000047749a9 empty
/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:895:0
#47 0x00000000047749a9 clang::CodeGen::CodeGenModule::EmitDeferred()
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:2125:0
#48 0x00000000047738e9 clang::CodeGen::CodeGenModule::Release()
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenModule.cpp:394:3
#49 0x0000000004d03644 (anonymous
namespace)::CodeGeneratorImpl::HandleTranslationUnit(clang::ASTContext&)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/ModuleBuilder.cpp:260:11
#50 0x0000000004d00dc6
clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/CodeGen/CodeGenAction.cpp:240:13
#51 0x0000000005a6b323 __normal_iterator
/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_iterator.h:781:20
#52 0x0000000005a6b323 begin
/usr/bin/../lib/gcc/x86_64-linux-gnu/8.0.1/../../../../include/c++/8.0.1/bits/stl_vector.h:699:0
#53 0x0000000005a6b323
finalize<std::vector<std::unique_ptr<clang::TemplateInstantiationCallback,
std::default_delete<clang::TemplateInstantiationCallback> >,
std::allocator<std::unique_ptr<clang::TemplateInstantiationCallback,
std::default_delete<clang::TemplateInstantiationCallback> > > > >
/usr/local/google/home/ibiryukov/projects/llvm/clang/include/clang/Sema/TemplateInstCallback.h:54:0
#54 0x0000000005a6b323 clang::ParseAST(clang::Sema&, bool, bool)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/Parse/ParseAST.cpp:178:0
#55 0x0000000004c5ef58 clang::FrontendAction::Execute()
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/Frontend/FrontendAction.cpp:938:10
#56 0x0000000004bc9328 getPtr
/usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Error.h:273:42
#57 0x0000000004bc9328 operator bool
/usr/local/google/home/ibiryukov/projects/llvm/llvm/include/llvm/Support/Error.h:236:0
#58 0x0000000004bc9328
clang::CompilerInstance::ExecuteAction(clang::FrontendAction&)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/Frontend/CompilerInstance.cpp:944:0
#59 0x0000000004cfb86d
clang::ExecuteCompilerInvocation(clang::CompilerInstance*)
/usr/local/google/home/ibiryukov/projects/llvm/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:291:25
#60 0x00000000028ea04a cc1_main(llvm::ArrayRef<char const*>, char const*,
void*)
/usr/local/google/home/ibiryukov/projects/llvm/clang/tools/driver/cc1_main.cpp:249:15
#61 0x00000000028e7d24 ExecuteCC1Tool
/usr/local/google/home/ibiryukov/projects/llvm/clang/tools/driver/driver.cpp:309:12
#62 0x00000000028e7d24 main
/usr/local/google/home/ibiryukov/projects/llvm/clang/tools/driver/driver.cpp:381:0
#63 0x00007f6197dc752b __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x2352b)
#64 0x00000000028e502a _start
(/usr/local/google/home/ibiryukov/projects/llvm/build-rel/bin/clang-9+0x28e502a)
clang-9: error: unable to execute command: Aborted
clang-9: error: clang frontend command failed due to signal (use -v to see
invocation)
clang version 9.0.0 (https://github.com/llvm/llvm-project
0cadf7bb2e78b9276421a44c0e1ad3cb4520050b)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/google/home/ibiryukov/projects/llvm/build-rel/bin
clang-9: note: diagnostic msg: PLEASE submit a bug report to
https://bugs.llvm.org/ and include the crash backtrace, preprocessed
source, and associated run script.
clang-9: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-9: note: diagnostic msg: /tmp/BinaryStreamRef-f5e741.cpp
clang-9: note: diagnostic msg: /tmp/BinaryStreamRef-f5e741.sh
clang-9: note: diagnostic msg:

********************

On Thu, Jul 18, 2019 at 12:03 PM Marco Antognini via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: mantognini
> Date: Thu Jul 18 03:04:18 2019
> New Revision: 366422
>
> URL: http://llvm.org/viewvc/llvm-project?rev=366422&view=rev
> Log:
> [OpenCL] Improve destructor support in C++ for OpenCL
>
> Summary:
> This patch does mainly three things:
>  1. It fixes a false positive error detection in Sema that is similar to
>     D62156. The error happens when explicitly calling an overloaded
>     destructor for different address spaces.
>  2. It selects the correct destructor when multiple overloads for
>     address spaces are available.
>  3. It inserts the expected address space cast when invoking a
>     destructor, if needed, and therefore fixes a crash due to the unmet
>     assertion in llvm::CastInst::Create.
>
> The following is a reproducer of the three issues:
>
>     struct MyType {
>       ~MyType() {}
>       ~MyType() __constant {}
>     };
>
>     __constant MyType myGlobal{};
>
>     kernel void foo() {
>       myGlobal.~MyType(); // 1 and 2.
>       // 1. error: cannot initialize object parameter of type
>       //    '__generic MyType' with an expression of type '__constant
> MyType'
>       // 2. error: no matching member function for call to '~MyType'
>     }
>
>     kernel void bar() {
>       // 3. The implicit call to the destructor crashes due to:
>       //    Assertion `castIsValid(op, S, Ty) && "Invalid cast!"' failed.
>       //    in llvm::CastInst::Create.
>       MyType myLocal;
>     }
>
> The added test depends on D62413 and covers a few more things than the
> above reproducer.
>
> Subscribers: yaxunl, Anastasia, cfe-commits
>
> Tags: #clang
>
> Differential Revision: https://reviews.llvm.org/D64569
>
> Added:
>     cfe/trunk/test/CodeGenOpenCLCXX/addrspace-with-class.cl
> Removed:
>     cfe/trunk/test/CodeGenOpenCLCXX/addrspace-ctor.cl
> Modified:
>     cfe/trunk/include/clang/AST/DeclCXX.h
>     cfe/trunk/lib/AST/DeclCXX.cpp
>     cfe/trunk/lib/CodeGen/CGCXXABI.h
>     cfe/trunk/lib/CodeGen/CGCall.cpp
>     cfe/trunk/lib/CodeGen/CGClass.cpp
>     cfe/trunk/lib/CodeGen/CGDecl.cpp
>     cfe/trunk/lib/CodeGen/CGExprCXX.cpp
>     cfe/trunk/lib/CodeGen/CodeGenFunction.h
>     cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
>     cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
>     cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>     cfe/trunk/lib/Sema/SemaOverload.cpp
>
> Modified: cfe/trunk/include/clang/AST/DeclCXX.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=366422&r1=366421&r2=366422&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/DeclCXX.h (original)
> +++ cfe/trunk/include/clang/AST/DeclCXX.h Thu Jul 18 03:04:18 2019
> @@ -2232,20 +2232,20 @@ public:
>
>    overridden_method_range overridden_methods() const;
>
> -  /// Returns the parent of this method declaration, which
> +  /// Return the parent of this method declaration, which
>    /// is the class in which this method is defined.
>    const CXXRecordDecl *getParent() const {
>      return cast<CXXRecordDecl>(FunctionDecl::getParent());
>    }
>
> -  /// Returns the parent of this method declaration, which
> +  /// Return the parent of this method declaration, which
>    /// is the class in which this method is defined.
>    CXXRecordDecl *getParent() {
>      return const_cast<CXXRecordDecl *>(
>               cast<CXXRecordDecl>(FunctionDecl::getParent()));
>    }
>
> -  /// Returns the type of the \c this pointer.
> +  /// Return the type of the \c this pointer.
>    ///
>    /// Should only be called for instance (i.e., non-static) methods. Note
>    /// that for the call operator of a lambda closure type, this returns
> the
> @@ -2253,9 +2253,17 @@ public:
>    /// 'this' type.
>    QualType getThisType() const;
>
> +  /// Return the type of the object pointed by \c this.
> +  ///
> +  /// See getThisType() for usage restriction.
> +  QualType getThisObjectType() const;
> +
>    static QualType getThisType(const FunctionProtoType *FPT,
>                                const CXXRecordDecl *Decl);
>
> +  static QualType getThisObjectType(const FunctionProtoType *FPT,
> +                                    const CXXRecordDecl *Decl);
> +
>    Qualifiers getMethodQualifiers() const {
>      return getType()->getAs<FunctionProtoType>()->getMethodQuals();
>    }
>
> Modified: cfe/trunk/lib/AST/DeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=366422&r1=366421&r2=366422&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/DeclCXX.cpp (original)
> +++ cfe/trunk/lib/AST/DeclCXX.cpp Thu Jul 18 03:04:18 2019
> @@ -2253,12 +2253,23 @@ CXXMethodDecl::overridden_methods() cons
>    return getASTContext().overridden_methods(this);
>  }
>
> +static QualType getThisObjectType(ASTContext &C, const FunctionProtoType
> *FPT,
> +                                  const CXXRecordDecl *Decl) {
> +  QualType ClassTy = C.getTypeDeclType(Decl);
> +  return C.getQualifiedType(ClassTy, FPT->getMethodQuals());
> +}
> +
>  QualType CXXMethodDecl::getThisType(const FunctionProtoType *FPT,
>                                      const CXXRecordDecl *Decl) {
>    ASTContext &C = Decl->getASTContext();
> -  QualType ClassTy = C.getTypeDeclType(Decl);
> -  ClassTy = C.getQualifiedType(ClassTy, FPT->getMethodQuals());
> -  return C.getPointerType(ClassTy);
> +  QualType ObjectTy = ::getThisObjectType(C, FPT, Decl);
> +  return C.getPointerType(ObjectTy);
> +}
> +
> +QualType CXXMethodDecl::getThisObjectType(const FunctionProtoType *FPT,
> +                                          const CXXRecordDecl *Decl) {
> +  ASTContext &C = Decl->getASTContext();
> +  return ::getThisObjectType(C, FPT, Decl);
>  }
>
>  QualType CXXMethodDecl::getThisType() const {
> @@ -2273,6 +2284,14 @@ QualType CXXMethodDecl::getThisType() co
>                                      getParent());
>  }
>
> +QualType CXXMethodDecl::getThisObjectType() const {
> +  // Ditto getThisType.
> +  assert(isInstance() && "No 'this' for static methods!");
> +
> +  return
> CXXMethodDecl::getThisObjectType(getType()->getAs<FunctionProtoType>(),
> +                                          getParent());
> +}
> +
>  bool CXXMethodDecl::hasInlineBody() const {
>    // If this function is a template instantiation, look at the template
> from
>    // which it was instantiated.
>
> Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=366422&r1=366421&r2=366422&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
> +++ cfe/trunk/lib/CodeGen/CGCXXABI.h Thu Jul 18 03:04:18 2019
> @@ -378,7 +378,7 @@ public:
>    virtual void EmitDestructorCall(CodeGenFunction &CGF,
>                                    const CXXDestructorDecl *DD,
> CXXDtorType Type,
>                                    bool ForVirtualBase, bool Delegating,
> -                                  Address This) = 0;
> +                                  Address This, QualType ThisTy) = 0;
>
>    /// Emits the VTable definitions required for the given record type.
>    virtual void emitVTableDefinitions(CodeGenVTables &CGVT,
> @@ -421,11 +421,15 @@ public:
>                                               llvm::Type *Ty,
>                                               SourceLocation Loc) = 0;
>
> +  using DeleteOrMemberCallExpr =
> +      llvm::PointerUnion<const CXXDeleteExpr *, const CXXMemberCallExpr
> *>;
> +
>    /// Emit the ABI-specific virtual destructor call.
> -  virtual llvm::Value *
> -  EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl
> *Dtor,
> -                            CXXDtorType DtorType, Address This,
> -                            const CXXMemberCallExpr *CE) = 0;
> +  virtual llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
> +                                                 const CXXDestructorDecl
> *Dtor,
> +                                                 CXXDtorType DtorType,
> +                                                 Address This,
> +                                                 DeleteOrMemberCallExpr
> E) = 0;
>
>    virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF,
>                                                  GlobalDecl GD,
>
> Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=366422&r1=366421&r2=366422&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGCall.cpp Thu Jul 18 03:04:18 2019
> @@ -3502,7 +3502,7 @@ struct DestroyUnpassedArg final : EHScop
>        const CXXDestructorDecl *Dtor =
> Ty->getAsCXXRecordDecl()->getDestructor();
>        assert(!Dtor->isTrivial());
>        CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*for vbase*/ false,
> -                                /*Delegating=*/false, Addr);
> +                                /*Delegating=*/false, Addr, Ty);
>      } else {
>        CGF.callCStructDestructor(CGF.MakeAddrLValue(Addr, Ty));
>      }
>
> Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=366422&r1=366421&r2=366422&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGClass.cpp Thu Jul 18 03:04:18 2019
> @@ -491,12 +491,15 @@ namespace {
>          cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent();
>
>        const CXXDestructorDecl *D = BaseClass->getDestructor();
> +      // We are already inside a destructor, so presumably the object
> being
> +      // destroyed should have the expected type.
> +      QualType ThisTy = D->getThisObjectType();
>        Address Addr =
>
>  CGF.GetAddressOfDirectBaseInCompleteClass(CGF.LoadCXXThisAddress(),
>                                                    DerivedClass, BaseClass,
>                                                    BaseIsVirtual);
>        CGF.EmitCXXDestructorCall(D, Dtor_Base, BaseIsVirtual,
> -                                /*Delegating=*/false, Addr);
> +                                /*Delegating=*/false, Addr, ThisTy);
>      }
>    };
>
> @@ -1440,9 +1443,11 @@ void CodeGenFunction::EmitDestructorBody
>    if (DtorType == Dtor_Deleting) {
>      RunCleanupsScope DtorEpilogue(*this);
>      EnterDtorCleanups(Dtor, Dtor_Deleting);
> -    if (HaveInsertPoint())
> +    if (HaveInsertPoint()) {
> +      QualType ThisTy = Dtor->getThisObjectType();
>        EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
> -                            /*Delegating=*/false, LoadCXXThisAddress());
> +                            /*Delegating=*/false, LoadCXXThisAddress(),
> ThisTy);
> +    }
>      return;
>    }
>
> @@ -1473,8 +1478,9 @@ void CodeGenFunction::EmitDestructorBody
>      EnterDtorCleanups(Dtor, Dtor_Complete);
>
>      if (!isTryBody) {
> +      QualType ThisTy = Dtor->getThisObjectType();
>        EmitCXXDestructorCall(Dtor, Dtor_Base, /*ForVirtualBase=*/false,
> -                            /*Delegating=*/false, LoadCXXThisAddress());
> +                            /*Delegating=*/false, LoadCXXThisAddress(),
> ThisTy);
>        break;
>      }
>
> @@ -2013,7 +2019,7 @@ void CodeGenFunction::destroyCXXObject(C
>    const CXXDestructorDecl *dtor = record->getDestructor();
>    assert(!dtor->isTrivial());
>    CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false,
> -                            /*Delegating=*/false, addr);
> +                            /*Delegating=*/false, addr, type);
>  }
>
>  void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
> @@ -2363,8 +2369,11 @@ namespace {
>        : Dtor(D), Addr(Addr), Type(Type) {}
>
>      void Emit(CodeGenFunction &CGF, Flags flags) override {
> +      // We are calling the destructor from within the constructor.
> +      // Therefore, "this" should have the expected type.
> +      QualType ThisTy = Dtor->getThisObjectType();
>        CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false,
> -                                /*Delegating=*/true, Addr);
> +                                /*Delegating=*/true, Addr, ThisTy);
>      }
>    };
>  } // end anonymous namespace
> @@ -2402,31 +2411,32 @@ CodeGenFunction::EmitDelegatingCXXConstr
>  void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
>                                              CXXDtorType Type,
>                                              bool ForVirtualBase,
> -                                            bool Delegating,
> -                                            Address This) {
> +                                            bool Delegating, Address This,
> +                                            QualType ThisTy) {
>    CGM.getCXXABI().EmitDestructorCall(*this, DD, Type, ForVirtualBase,
> -                                     Delegating, This);
> +                                     Delegating, This, ThisTy);
>  }
>
>  namespace {
>    struct CallLocalDtor final : EHScopeStack::Cleanup {
>      const CXXDestructorDecl *Dtor;
>      Address Addr;
> +    QualType Ty;
>
> -    CallLocalDtor(const CXXDestructorDecl *D, Address Addr)
> -      : Dtor(D), Addr(Addr) {}
> +    CallLocalDtor(const CXXDestructorDecl *D, Address Addr, QualType Ty)
> +        : Dtor(D), Addr(Addr), Ty(Ty) {}
>
>      void Emit(CodeGenFunction &CGF, Flags flags) override {
>        CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
>                                  /*ForVirtualBase=*/false,
> -                                /*Delegating=*/false, Addr);
> +                                /*Delegating=*/false, Addr, Ty);
>      }
>    };
>  } // end anonymous namespace
>
>  void CodeGenFunction::PushDestructorCleanup(const CXXDestructorDecl *D,
> -                                            Address Addr) {
> -  EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr);
> +                                            QualType T, Address Addr) {
> +  EHStack.pushCleanup<CallLocalDtor>(NormalAndEHCleanup, D, Addr, T);
>  }
>
>  void CodeGenFunction::PushDestructorCleanup(QualType T, Address Addr) {
> @@ -2436,7 +2446,7 @@ void CodeGenFunction::PushDestructorClea
>
>    const CXXDestructorDecl *D = ClassDecl->getDestructor();
>    assert(D && D->isUsed() && "destructor not marked as used!");
> -  PushDestructorCleanup(D, Addr);
> +  PushDestructorCleanup(D, T, Addr);
>  }
>
>  void CodeGenFunction::InitializeVTablePointer(const VPtr &Vptr) {
>
> Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=366422&r1=366421&r2=366422&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Thu Jul 18 03:04:18 2019
> @@ -480,11 +480,12 @@ namespace {
>
>    template <class Derived>
>    struct DestroyNRVOVariable : EHScopeStack::Cleanup {
> -    DestroyNRVOVariable(Address addr, llvm::Value *NRVOFlag)
> -        : NRVOFlag(NRVOFlag), Loc(addr) {}
> +    DestroyNRVOVariable(Address addr, QualType type, llvm::Value
> *NRVOFlag)
> +        : NRVOFlag(NRVOFlag), Loc(addr), Ty(type) {}
>
>      llvm::Value *NRVOFlag;
>      Address Loc;
> +    QualType Ty;
>
>      void Emit(CodeGenFunction &CGF, Flags flags) override {
>        // Along the exceptions path we always execute the dtor.
> @@ -511,26 +512,24 @@ namespace {
>
>    struct DestroyNRVOVariableCXX final
>        : DestroyNRVOVariable<DestroyNRVOVariableCXX> {
> -    DestroyNRVOVariableCXX(Address addr, const CXXDestructorDecl *Dtor,
> -                           llvm::Value *NRVOFlag)
> -      : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr, NRVOFlag),
> -        Dtor(Dtor) {}
> +    DestroyNRVOVariableCXX(Address addr, QualType type,
> +                           const CXXDestructorDecl *Dtor, llvm::Value
> *NRVOFlag)
> +        : DestroyNRVOVariable<DestroyNRVOVariableCXX>(addr, type,
> NRVOFlag),
> +          Dtor(Dtor) {}
>
>      const CXXDestructorDecl *Dtor;
>
>      void emitDestructorCall(CodeGenFunction &CGF) {
>        CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
>                                  /*ForVirtualBase=*/false,
> -                                /*Delegating=*/false, Loc);
> +                                /*Delegating=*/false, Loc, Ty);
>      }
>    };
>
>    struct DestroyNRVOVariableC final
>        : DestroyNRVOVariable<DestroyNRVOVariableC> {
>      DestroyNRVOVariableC(Address addr, llvm::Value *NRVOFlag, QualType Ty)
> -        : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, NRVOFlag),
> Ty(Ty) {}
> -
> -    QualType Ty;
> +        : DestroyNRVOVariable<DestroyNRVOVariableC>(addr, Ty, NRVOFlag) {}
>
>      void emitDestructorCall(CodeGenFunction &CGF) {
>        CGF.destroyNonTrivialCStruct(CGF, Loc, Ty);
> @@ -1940,7 +1939,7 @@ void CodeGenFunction::emitAutoVarTypeCle
>      if (emission.NRVOFlag) {
>        assert(!type->isArrayType());
>        CXXDestructorDecl *dtor =
> type->getAsCXXRecordDecl()->getDestructor();
> -      EHStack.pushCleanup<DestroyNRVOVariableCXX>(cleanupKind, addr, dtor,
> +      EHStack.pushCleanup<DestroyNRVOVariableCXX>(cleanupKind, addr,
> type, dtor,
>                                                    emission.NRVOFlag);
>        return;
>      }
>
> Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=366422&r1=366421&r2=366422&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Thu Jul 18 03:04:18 2019
> @@ -10,12 +10,13 @@
>  //
>
>  //===----------------------------------------------------------------------===//
>
> -#include "CodeGenFunction.h"
>  #include "CGCUDARuntime.h"
>  #include "CGCXXABI.h"
>  #include "CGDebugInfo.h"
>  #include "CGObjCRuntime.h"
> +#include "CodeGenFunction.h"
>  #include "ConstantEmitter.h"
> +#include "TargetInfo.h"
>  #include "clang/Basic/CodeGenOptions.h"
>  #include "clang/CodeGen/CGFunctionInfo.h"
>  #include "llvm/IR/Intrinsics.h"
> @@ -90,12 +91,26 @@ RValue CodeGenFunction::EmitCXXMemberOrO
>  }
>
>  RValue CodeGenFunction::EmitCXXDestructorCall(
> -    GlobalDecl Dtor, const CGCallee &Callee, llvm::Value *This,
> +    GlobalDecl Dtor, const CGCallee &Callee, llvm::Value *This, QualType
> ThisTy,
>      llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr
> *CE) {
> +  const CXXMethodDecl *DtorDecl = cast<CXXMethodDecl>(Dtor.getDecl());
> +
> +  assert(!ThisTy.isNull());
> +  assert(ThisTy->getAsCXXRecordDecl() == DtorDecl->getParent() &&
> +         "Pointer/Object mixup");
> +
> +  LangAS SrcAS = ThisTy.getAddressSpace();
> +  LangAS DstAS = DtorDecl->getMethodQualifiers().getAddressSpace();
> +  if (SrcAS != DstAS) {
> +    QualType DstTy = DtorDecl->getThisType();
> +    llvm::Type *NewType = CGM.getTypes().ConvertType(DstTy);
> +    This = getTargetHooks().performAddrSpaceCast(*this, This, SrcAS,
> DstAS,
> +                                                 NewType);
> +  }
> +
>    CallArgList Args;
> -  commonEmitCXXMemberOrOperatorCall(*this,
> cast<CXXMethodDecl>(Dtor.getDecl()),
> -                                    This, ImplicitParam, ImplicitParamTy,
> CE,
> -                                    Args, nullptr);
> +  commonEmitCXXMemberOrOperatorCall(*this, DtorDecl, This, ImplicitParam,
> +                                    ImplicitParamTy, CE, Args, nullptr);
>    return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(Dtor),
> Callee,
>                    ReturnValueSlot(), Args);
>  }
> @@ -345,7 +360,9 @@ RValue CodeGenFunction::EmitCXXMemberOrO
>          Callee = CGCallee::forDirect(CGM.GetAddrOfFunction(GD, Ty), GD);
>        }
>
> -      EmitCXXDestructorCall(GD, Callee, This.getPointer(),
> +      QualType ThisTy =
> +          IsArrow ? Base->getType()->getPointeeType() : Base->getType();
> +      EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy,
>                              /*ImplicitParam=*/nullptr,
>                              /*ImplicitParamTy=*/QualType(), nullptr);
>      }
> @@ -1883,7 +1900,7 @@ static void EmitObjectDelete(CodeGenFunc
>      CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
>                                /*ForVirtualBase=*/false,
>                                /*Delegating=*/false,
> -                              Ptr);
> +                              Ptr, ElementType);
>    else if (auto Lifetime = ElementType.getObjCLifetime()) {
>      switch (Lifetime) {
>      case Qualifiers::OCL_None:
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=366422&r1=366421&r2=366422&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Jul 18 03:04:18 2019
> @@ -675,7 +675,8 @@ public:
>    /// PushDestructorCleanup - Push a cleanup to call the
>    /// complete-object variant of the given destructor on the object at
>    /// the given address.
> -  void PushDestructorCleanup(const CXXDestructorDecl *Dtor, Address Addr);
> +  void PushDestructorCleanup(const CXXDestructorDecl *Dtor, QualType T,
> +                             Address Addr);
>
>    /// PopCleanupBlock - Will pop the cleanup entry on the stack and
>    /// process all branch fixups.
> @@ -2554,8 +2555,8 @@ public:
>    static Destroyer destroyCXXObject;
>
>    void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type,
> -                             bool ForVirtualBase, bool Delegating,
> -                             Address This);
> +                             bool ForVirtualBase, bool Delegating,
> Address This,
> +                             QualType ThisTy);
>
>    void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType,
>                                 llvm::Type *ElementTy, Address NewPtr,
> @@ -3677,9 +3678,9 @@ public:
>                                llvm::Value *ImplicitParam,
>                                QualType ImplicitParamTy, const CallExpr *E,
>                                CallArgList *RtlArgs);
> -  RValue EmitCXXDestructorCall(GlobalDecl Dtor,
> -                               const CGCallee &Callee,
> -                               llvm::Value *This, llvm::Value
> *ImplicitParam,
> +  RValue EmitCXXDestructorCall(GlobalDecl Dtor, const CGCallee &Callee,
> +                               llvm::Value *This, QualType ThisTy,
> +                               llvm::Value *ImplicitParam,
>                                 QualType ImplicitParamTy, const CallExpr
> *E);
>    RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E,
>                                 ReturnValueSlot ReturnValue);
>
> Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=366422&r1=366421&r2=366422&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
> +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Thu Jul 18 03:04:18 2019
> @@ -224,7 +224,8 @@ public:
>
>    void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl
> *DD,
>                            CXXDtorType Type, bool ForVirtualBase,
> -                          bool Delegating, Address This) override;
> +                          bool Delegating, Address This,
> +                          QualType ThisTy) override;
>
>    void emitVTableDefinitions(CodeGenVTables &CGVT,
>                               const CXXRecordDecl *RD) override;
> @@ -261,9 +262,8 @@ public:
>
>    llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
>                                           const CXXDestructorDecl *Dtor,
> -                                         CXXDtorType DtorType,
> -                                         Address This,
> -                                         const CXXMemberCallExpr *CE)
> override;
> +                                         CXXDtorType DtorType, Address
> This,
> +                                         DeleteOrMemberCallExpr E)
> override;
>
>    void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;
>
> @@ -1128,7 +1128,7 @@ void ItaniumCXXABI::emitVirtualObjectDel
>    // FIXME: Provide a source location here even though there's no
>    // CXXMemberCallExpr for dtor call.
>    CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
> -  EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, /*CE=*/nullptr);
> +  EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
>
>    if (UseGlobalDelete)
>      CGF.PopCleanupBlock();
> @@ -1539,7 +1539,8 @@ CGCXXABI::AddedStructorArgs ItaniumCXXAB
>  void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
>                                         const CXXDestructorDecl *DD,
>                                         CXXDtorType Type, bool
> ForVirtualBase,
> -                                       bool Delegating, Address This) {
> +                                       bool Delegating, Address This,
> +                                       QualType ThisTy) {
>    GlobalDecl GD(DD, Type);
>    llvm::Value *VTT = CGF.GetVTTParameter(GD, ForVirtualBase, Delegating);
>    QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
> @@ -1551,7 +1552,8 @@ void ItaniumCXXABI::EmitDestructorCall(C
>    else
>      Callee = CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD), GD);
>
> -  CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), VTT, VTTTy,
> nullptr);
> +  CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, VTT,
> VTTTy,
> +                            nullptr);
>  }
>
>  void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
> @@ -1739,7 +1741,10 @@ CGCallee ItaniumCXXABI::getVirtualFuncti
>
>  llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
>      CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType
> DtorType,
> -    Address This, const CXXMemberCallExpr *CE) {
> +    Address This, DeleteOrMemberCallExpr E) {
> +  auto *CE = E.dyn_cast<const CXXMemberCallExpr *>();
> +  auto *D = E.dyn_cast<const CXXDeleteExpr *>();
> +  assert((CE != nullptr) ^ (D != nullptr));
>    assert(CE == nullptr || CE->arg_begin() == CE->arg_end());
>    assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
>
> @@ -1749,8 +1754,14 @@ llvm::Value *ItaniumCXXABI::EmitVirtualD
>    llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
>    CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty);
>
> -  CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), nullptr,
> QualType(),
> -                            nullptr);
> +  QualType ThisTy;
> +  if (CE)
> +    ThisTy = CE->getImplicitObjectArgument()->getType()->getPointeeType();
> +  else
> +    ThisTy = D->getDestroyedType();
> +
> +  CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy,
> nullptr,
> +                            QualType(), nullptr);
>    return nullptr;
>  }
>
>
> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=366422&r1=366421&r2=366422&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
> +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Thu Jul 18 03:04:18 2019
> @@ -258,7 +258,8 @@ public:
>
>    void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl
> *DD,
>                            CXXDtorType Type, bool ForVirtualBase,
> -                          bool Delegating, Address This) override;
> +                          bool Delegating, Address This,
> +                          QualType ThisTy) override;
>
>    void emitVTableTypeMetadata(const VPtrInfo &Info, const CXXRecordDecl
> *RD,
>                                llvm::GlobalVariable *VTable);
> @@ -296,9 +297,8 @@ public:
>
>    llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
>                                           const CXXDestructorDecl *Dtor,
> -                                         CXXDtorType DtorType,
> -                                         Address This,
> -                                         const CXXMemberCallExpr *CE)
> override;
> +                                         CXXDtorType DtorType, Address
> This,
> +                                         DeleteOrMemberCallExpr E)
> override;
>
>    void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl
> GD,
>                                          CallArgList &CallArgs) override {
> @@ -844,8 +844,7 @@ void MicrosoftCXXABI::emitVirtualObjectD
>    // CXXMemberCallExpr for dtor call.
>    bool UseGlobalDelete = DE->isGlobalDelete();
>    CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
> -  llvm::Value *MDThis =
> -      EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, /*CE=*/nullptr);
> +  llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType,
> Ptr, DE);
>    if (UseGlobalDelete)
>      CGF.EmitDeleteCall(DE->getOperatorDelete(), MDThis, ElementType);
>  }
> @@ -1569,7 +1568,8 @@ CGCXXABI::AddedStructorArgs MicrosoftCXX
>  void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
>                                           const CXXDestructorDecl *DD,
>                                           CXXDtorType Type, bool
> ForVirtualBase,
> -                                         bool Delegating, Address This) {
> +                                         bool Delegating, Address This,
> +                                         QualType ThisTy) {
>    // Use the base destructor variant in place of the complete destructor
> variant
>    // if the class has no virtual bases. This effectively implements some
> of the
>    // -mconstructor-aliases optimization, but as part of the MS C++ ABI.
> @@ -1591,7 +1591,7 @@ void MicrosoftCXXABI::EmitDestructorCall
>      BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
>    }
>
> -  CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(),
> +  CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy,
>                              /*ImplicitParam=*/nullptr,
>                              /*ImplicitParamTy=*/QualType(), nullptr);
>    if (BaseDtorEndBB) {
> @@ -1900,7 +1900,10 @@ CGCallee MicrosoftCXXABI::getVirtualFunc
>
>  llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
>      CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType
> DtorType,
> -    Address This, const CXXMemberCallExpr *CE) {
> +    Address This, DeleteOrMemberCallExpr E) {
> +  auto *CE = E.dyn_cast<const CXXMemberCallExpr *>();
> +  auto *D = E.dyn_cast<const CXXDeleteExpr *>();
> +  assert((CE != nullptr) ^ (D != nullptr));
>    assert(CE == nullptr || CE->arg_begin() == CE->arg_end());
>    assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
>
> @@ -1917,8 +1920,14 @@ llvm::Value *MicrosoftCXXABI::EmitVirtua
>        llvm::IntegerType::getInt32Ty(CGF.getLLVMContext()),
>        DtorType == Dtor_Deleting);
>
> +  QualType ThisTy;
> +  if (CE)
> +    ThisTy = CE->getImplicitObjectArgument()->getType()->getPointeeType();
> +  else
> +    ThisTy = D->getDestroyedType();
> +
>    This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true);
> -  RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(),
> +  RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(),
> ThisTy,
>                                          ImplicitParam, Context.IntTy, CE);
>    return RV.getScalarVal();
>  }
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=366422&r1=366421&r2=366422&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jul 18 03:04:18 2019
> @@ -8190,6 +8190,27 @@ void Sema::ActOnFinishDelayedCXXMethodDe
>      CheckCXXDefaultArguments(Method);
>  }
>
> +// Emit the given diagnostic for each non-address-space qualifier.
> +// Common part of CheckConstructorDeclarator and
> CheckDestructorDeclarator.
> +static void checkMethodTypeQualifiers(Sema &S, Declarator &D, unsigned
> DiagID) {
> +  const DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
> +  if (FTI.hasMethodTypeQualifiers() && !D.isInvalidType()) {
> +    bool DiagOccured = false;
> +    FTI.MethodQualifiers->forEachQualifier(
> +        [DiagID, &S, &DiagOccured](DeclSpec::TQ, StringRef QualName,
> +                                   SourceLocation SL) {
> +          // This diagnostic should be emitted on any qualifier except an
> addr
> +          // space qualifier. However, forEachQualifier currently doesn't
> visit
> +          // addr space qualifiers, so there's no way to write this
> condition
> +          // right now; we just diagnose on everything.
> +          S.Diag(SL, DiagID) << QualName << SourceRange(SL);
> +          DiagOccured = true;
> +        });
> +    if (DiagOccured)
> +      D.setInvalidType();
> +  }
> +}
> +
>  /// CheckConstructorDeclarator - Called by ActOnDeclarator to check
>  /// the well-formedness of the constructor declarator @p D with type @p
>  /// R. If there are any errors in the declarator, this routine will
> @@ -8230,25 +8251,11 @@ QualType Sema::CheckConstructorDeclarato
>      D.setInvalidType();
>    }
>
> -  DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
> -  if (FTI.hasMethodTypeQualifiers()) {
> -    bool DiagOccured = false;
> -    FTI.MethodQualifiers->forEachQualifier(
> -        [&](DeclSpec::TQ TypeQual, StringRef QualName, SourceLocation SL)
> {
> -          // This diagnostic should be emitted on any qualifier except an
> addr
> -          // space qualifier. However, forEachQualifier currently doesn't
> visit
> -          // addr space qualifiers, so there's no way to write this
> condition
> -          // right now; we just diagnose on everything.
> -          Diag(SL, diag::err_invalid_qualified_constructor)
> -              << QualName << SourceRange(SL);
> -          DiagOccured = true;
> -        });
> -    if (DiagOccured)
> -      D.setInvalidType();
> -  }
> +  checkMethodTypeQualifiers(*this, D,
> diag::err_invalid_qualified_constructor);
>
>    // C++0x [class.ctor]p4:
>    //   A constructor shall not be declared with a ref-qualifier.
> +  DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
>    if (FTI.hasRefQualifier()) {
>      Diag(FTI.getRefQualifierLoc(), diag::err_ref_qualifier_constructor)
>        << FTI.RefQualifierIsLValueRef
> @@ -8423,18 +8430,11 @@ QualType Sema::CheckDestructorDeclarator
>      }
>    }
>
> -  DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
> -  if (FTI.hasMethodTypeQualifiers() && !D.isInvalidType()) {
> -    FTI.MethodQualifiers->forEachQualifier(
> -        [&](DeclSpec::TQ TypeQual, StringRef QualName, SourceLocation SL)
> {
> -          Diag(SL, diag::err_invalid_qualified_destructor)
> -              << QualName << SourceRange(SL);
> -        });
> -    D.setInvalidType();
> -  }
> +  checkMethodTypeQualifiers(*this, D,
> diag::err_invalid_qualified_destructor);
>
>    // C++0x [class.dtor]p2:
>    //   A destructor shall not be declared with a ref-qualifier.
> +  DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
>    if (FTI.hasRefQualifier()) {
>      Diag(FTI.getRefQualifierLoc(), diag::err_ref_qualifier_destructor)
>        << FTI.RefQualifierIsLValueRef
>
> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=366422&r1=366421&r2=366422&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Jul 18 03:04:18 2019
> @@ -5093,12 +5093,10 @@ TryObjectArgumentInitialization(Sema &S,
>    QualType ClassType = S.Context.getTypeDeclType(ActingContext);
>    // [class.dtor]p2: A destructor can be invoked for a const, volatile or
>    //                 const volatile object.
> -  Qualifiers Quals;
> +  Qualifiers Quals = Method->getMethodQualifiers();
>    if (isa<CXXDestructorDecl>(Method)) {
>      Quals.addConst();
>      Quals.addVolatile();
> -  } else {
> -    Quals = Method->getMethodQualifiers();
>    }
>
>    QualType ImplicitParamType = S.Context.getQualifiedType(ClassType,
> Quals);
>
> Removed: cfe/trunk/test/CodeGenOpenCLCXX/addrspace-ctor.cl
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCLCXX/addrspace-ctor.cl?rev=366421&view=auto
>
> ==============================================================================
> --- cfe/trunk/test/CodeGenOpenCLCXX/addrspace-ctor.cl (original)
> +++ cfe/trunk/test/CodeGenOpenCLCXX/addrspace-ctor.cl (removed)
> @@ -1,14 +0,0 @@
> -// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm
> -O0 -o - | FileCheck %s
> -
> -struct MyType {
> -  MyType(int i) : i(i) {}
> -  MyType(int i) __constant : i(i) {}
> -  int i;
> -};
> -
> -//CHECK: call void @_ZNU3AS26MyTypeC1Ei(%struct.MyType addrspace(2)*
> @const1, i32 1)
> -__constant MyType const1 = 1;
> -//CHECK: call void @_ZNU3AS26MyTypeC1Ei(%struct.MyType addrspace(2)*
> @const2, i32 2)
> -__constant MyType const2(2);
> -//CHECK: call void @_ZNU3AS46MyTypeC1Ei(%struct.MyType addrspace(4)*
> addrspacecast (%struct.MyType addrspace(1)* @glob to %struct.MyType
> addrspace(4)*), i32 1)
> -MyType glob(1);
>
> Added: cfe/trunk/test/CodeGenOpenCLCXX/addrspace-with-class.cl
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCLCXX/addrspace-with-class.cl?rev=366422&view=auto
>
> ==============================================================================
> --- cfe/trunk/test/CodeGenOpenCLCXX/addrspace-with-class.cl (added)
> +++ cfe/trunk/test/CodeGenOpenCLCXX/addrspace-with-class.cl Thu Jul 18
> 03:04:18 2019
> @@ -0,0 +1,59 @@
> +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm
> -O0 -o - | FileCheck %s
> +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm
> -O0 -o - | FileCheck %s --check-prefix=CHECK-DEFINITIONS
> +
> +// This test ensures the proper address spaces and address space cast are
> used
> +// for constructors, member functions and destructors.
> +// See also atexit.cl and global_init.cl for other specific tests.
> +
> +// CHECK: %struct.MyType = type { i32 }
> +struct MyType {
> +  MyType(int i) : i(i) {}
> +  MyType(int i) __constant : i(i) {}
> +  ~MyType() {}
> +  ~MyType() __constant {}
> +  int bar() { return i + 2; }
> +  int bar() __constant { return i + 1; }
> +  int i;
> +};
> +
> +// CHECK: @const1 = addrspace(2) global %struct.MyType zeroinitializer
> +__constant MyType const1 = 1;
> +// CHECK: @const2 = addrspace(2) global %struct.MyType zeroinitializer
> +__constant MyType const2(2);
> +// CHECK: @glob = addrspace(1) global %struct.MyType zeroinitializer
> +MyType glob(1);
> +
> +// CHECK: call void @_ZNU3AS26MyTypeC1Ei(%struct.MyType addrspace(2)*
> @const1, i32 1)
> +// CHECK: call void @_ZNU3AS26MyTypeC1Ei(%struct.MyType addrspace(2)*
> @const2, i32 2)
> +// CHECK: call void @_ZNU3AS46MyTypeC1Ei(%struct.MyType addrspace(4)*
> addrspacecast (%struct.MyType addrspace(1)* @glob to %struct.MyType
> addrspace(4)*), i32 1)
> +
> +// CHECK-LABEL: define spir_kernel void @fooGlobal()
> +kernel void fooGlobal() {
> +  // CHECK: call i32 @_ZNU3AS46MyType3barEv(%struct.MyType addrspace(4)*
> addrspacecast (%struct.MyType addrspace(1)* @glob to %struct.MyType
> addrspace(4)*))
> +  glob.bar();
> +  // CHECK: call i32 @_ZNU3AS26MyType3barEv(%struct.MyType addrspace(2)*
> @const1)
> +  const1.bar();
> +  // CHECK: call void @_ZNU3AS26MyTypeD1Ev(%struct.MyType addrspace(2)*
> @const1)
> +  const1.~MyType();
> +}
> +
> +// CHECK-LABEL: define spir_kernel void @fooLocal()
> +kernel void fooLocal() {
> +  // CHECK: [[VAR:%.*]] = alloca %struct.MyType
> +  // CHECK: [[REG:%.*]] = addrspacecast %struct.MyType* [[VAR]] to
> %struct.MyType addrspace(4)*
> +  // CHECK: call void @_ZNU3AS46MyTypeC1Ei(%struct.MyType addrspace(4)*
> [[REG]], i32 3)
> +  MyType myLocal(3);
> +  // CHECK: [[REG:%.*]] = addrspacecast %struct.MyType* [[VAR]] to
> %struct.MyType addrspace(4)*
> +  // CHECK: call i32 @_ZNU3AS46MyType3barEv(%struct.MyType addrspace(4)*
> [[REG]])
> +  myLocal.bar();
> +  // CHECK: [[REG:%.*]] = addrspacecast %struct.MyType* [[VAR]] to
> %struct.MyType addrspace(4)*
> +  // CHECK: call void @_ZNU3AS46MyTypeD1Ev(%struct.MyType addrspace(4)*
> [[REG]])
> +}
> +
> +// Ensure all members are defined for all the required address spaces.
> +// CHECK-DEFINITIONS-DAG: define linkonce_odr void
> @_ZNU3AS26MyTypeC1Ei(%struct.MyType addrspace(2)* %this, i32 %i)
> +// CHECK-DEFINITIONS-DAG: define linkonce_odr void
> @_ZNU3AS46MyTypeC1Ei(%struct.MyType addrspace(4)* %this, i32 %i)
> +// CHECK-DEFINITIONS-DAG: define linkonce_odr void
> @_ZNU3AS26MyTypeD1Ev(%struct.MyType addrspace(2)* %this)
> +// CHECK-DEFINITIONS-DAG: define linkonce_odr void
> @_ZNU3AS46MyTypeD1Ev(%struct.MyType addrspace(4)* %this)
> +// CHECK-DEFINITIONS-DAG: define linkonce_odr i32
> @_ZNU3AS26MyType3barEv(%struct.MyType addrspace(2)* %this)
> +// CHECK-DEFINITIONS-DAG: define linkonce_odr i32
> @_ZNU3AS46MyType3barEv(%struct.MyType addrspace(4)* %this)
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>


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


More information about the cfe-commits mailing list