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