[PATCH] D51808: [CUDA] Ignore uncallable functions when we check for usual deallocators.
This revision was automatically updated to reflect the committed changes. Closed by commit rL342749: [CUDA] Ignore uncallable functions when we check for usual deallocators. (authored by tra, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D51808?vs=166053&id=166504#toc Repository: rL LLVM https://reviews.llvm.org/D51808 Files: cfe/trunk/include/clang/AST/DeclCXX.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/AST/DeclCXX.cpp cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/lib/Sema/SemaExprCXX.cpp cfe/trunk/test/CodeGenCUDA/usual-deallocators.cu cfe/trunk/test/SemaCUDA/call-host-fn-from-device.cu cfe/trunk/test/SemaCUDA/usual-deallocators.cu Index: cfe/trunk/include/clang/AST/DeclCXX.h === --- cfe/trunk/include/clang/AST/DeclCXX.h +++ cfe/trunk/include/clang/AST/DeclCXX.h @@ -2109,10 +2109,15 @@ Base, IsAppleKext); } - /// Determine whether this is a usual deallocation function - /// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded - /// delete or delete[] operator with a particular signature. - bool isUsualDeallocationFunction() const; + /// Determine whether this is a usual deallocation function (C++ + /// [basic.stc.dynamic.deallocation]p2), which is an overloaded delete or + /// delete[] operator with a particular signature. Populates \p PreventedBy + /// with the declarations of the functions of the same kind if they were the + /// reason for this function returning false. This is used by + /// Sema::isUsualDeallocationFunction to reconsider the answer based on the + /// context. + bool isUsualDeallocationFunction( + SmallVectorImpl &PreventedBy) const; /// Determine whether this is a copy-assignment operator, regardless /// of whether it was declared implicitly or explicitly. Index: cfe/trunk/include/clang/Sema/Sema.h === --- cfe/trunk/include/clang/Sema/Sema.h +++ cfe/trunk/include/clang/Sema/Sema.h @@ -1619,6 +1619,8 @@ SourceLocation Loc, const NamedDecl *D, ArrayRef Equiv); + bool isUsualDeallocationFunction(const CXXMethodDecl *FD); + bool isCompleteType(SourceLocation Loc, QualType T) { return !RequireCompleteTypeImpl(Loc, T, nullptr); } Index: cfe/trunk/test/CodeGenCUDA/usual-deallocators.cu === --- cfe/trunk/test/CodeGenCUDA/usual-deallocators.cu +++ cfe/trunk/test/CodeGenCUDA/usual-deallocators.cu @@ -0,0 +1,133 @@ +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=COMMON,DEVICE +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown \ +// RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=COMMON,HOST +// RUN: %clang_cc1 %s --std=c++17 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=COMMON,DEVICE +// RUN: %clang_cc1 %s --std=c++17 -triple nvptx-unknown-unknown \ +// RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=COMMON,HOST + +#include "Inputs/cuda.h" +extern "C" __host__ void host_fn(); +extern "C" __device__ void dev_fn(); +extern "C" __host__ __device__ void hd_fn(); + +struct H1D1 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H2D1 { + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H2D2 { + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1D1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1H2D1 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H1H2D2 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1H2D1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + + +template +__host__ __device__ void test_hd(void *p) { + T *t = (T *)p; + delete t; +}
[PATCH] D51808: [CUDA] Ignore uncallable functions when we check for usual deallocators.
tra updated this revision to Diff 166053. tra added a comment. Renamed last instance of 'Matches' -> 'PreventedBy'. https://reviews.llvm.org/D51808 Files: clang/include/clang/AST/DeclCXX.h clang/include/clang/Sema/Sema.h clang/lib/AST/DeclCXX.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExprCXX.cpp clang/test/CodeGenCUDA/usual-deallocators.cu clang/test/SemaCUDA/call-host-fn-from-device.cu clang/test/SemaCUDA/usual-deallocators.cu Index: clang/test/SemaCUDA/usual-deallocators.cu === --- /dev/null +++ clang/test/SemaCUDA/usual-deallocators.cu @@ -0,0 +1,95 @@ +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emit-llvm -o /dev/null -verify=device +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown \ +// RUN: -emit-llvm -o /dev/null -verify=host +// RUN: %clang_cc1 %s --std=c++17 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emit-llvm -o /dev/null -verify=device +// RUN: %clang_cc1 %s --std=c++17 -triple nvptx-unknown-unknown \ +// RUN: -emit-llvm -o /dev/null -verify=host + +#include "Inputs/cuda.h" +extern __host__ void host_fn(); +extern __device__ void dev_fn(); +extern __host__ __device__ void hd_fn(); + +struct H1D1 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct h1D1 { + __host__ void operator delete(void *) = delete; + // host-note@-1 {{'operator delete' has been explicitly marked deleted here}} + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H1d1 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) = delete; + // device-note@-1 {{'operator delete' has been explicitly marked deleted here}} +}; + +struct H1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H2D1 { + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H2D2 { + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1D1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1H2D1 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H1H2D2 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1H2D1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + + +template +__host__ __device__ void test_hd(void *p) { + T *t = (T *)p; + delete t; + // host-error@-1 {{attempt to use a deleted function}} + // device-error@-2 {{attempt to use a deleted function}} +} + +__host__ __device__ void tests_hd(void *t) { + test_hd(t); + test_hd(t); + // host-note@-1 {{in instantiation of function template specialization 'test_hd' requested here}} + test_hd(t); + // device-note@-1 {{in instantiation of function template specialization 'test_hd' requested here}} + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); +} Index: clang/test/SemaCUDA/call-host-fn-from-device.cu === --- clang/test/SemaCUDA/call-host-fn-from-device.cu +++ clang/test/SemaCUDA/call-host-fn-from-device.cu @@ -41,12 +41,12 @@ operator Dummy() { return Dummy(); } // expected-note@-1 {{'operator Dummy' declared here}} - __host__ void operator delete(void*); - __device__ void operator delete(void*, size_t); + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void*, __SIZE_TYPE__); }; struct U { - __device__ void operator delete(void*, size_t) = delete; + __device__ void operator delete(void*, __SIZE_TYPE__) = delete; __host__ __device__ void operator delete(void*); }; Index: clang/test/CodeGenCUDA/usual-deallocators.cu === --- /dev/null +++ clang/test/CodeGenCUDA/usual-deallocators.cu @@ -0,0 +1,133 @@ +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=COMMON,DEVIC
[PATCH] D51808: [CUDA] Ignore uncallable functions when we check for usual deallocators.
tra updated this revision to Diff 166050. tra marked an inline comment as done. tra added a comment. Updated assertion message. https://reviews.llvm.org/D51808 Files: clang/include/clang/AST/DeclCXX.h clang/include/clang/Sema/Sema.h clang/lib/AST/DeclCXX.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExprCXX.cpp clang/test/CodeGenCUDA/usual-deallocators.cu clang/test/SemaCUDA/call-host-fn-from-device.cu clang/test/SemaCUDA/usual-deallocators.cu Index: clang/test/SemaCUDA/usual-deallocators.cu === --- /dev/null +++ clang/test/SemaCUDA/usual-deallocators.cu @@ -0,0 +1,95 @@ +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emit-llvm -o /dev/null -verify=device +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown \ +// RUN: -emit-llvm -o /dev/null -verify=host +// RUN: %clang_cc1 %s --std=c++17 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emit-llvm -o /dev/null -verify=device +// RUN: %clang_cc1 %s --std=c++17 -triple nvptx-unknown-unknown \ +// RUN: -emit-llvm -o /dev/null -verify=host + +#include "Inputs/cuda.h" +extern __host__ void host_fn(); +extern __device__ void dev_fn(); +extern __host__ __device__ void hd_fn(); + +struct H1D1 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct h1D1 { + __host__ void operator delete(void *) = delete; + // host-note@-1 {{'operator delete' has been explicitly marked deleted here}} + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H1d1 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) = delete; + // device-note@-1 {{'operator delete' has been explicitly marked deleted here}} +}; + +struct H1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H2D1 { + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H2D2 { + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1D1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1H2D1 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H1H2D2 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1H2D1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + + +template +__host__ __device__ void test_hd(void *p) { + T *t = (T *)p; + delete t; + // host-error@-1 {{attempt to use a deleted function}} + // device-error@-2 {{attempt to use a deleted function}} +} + +__host__ __device__ void tests_hd(void *t) { + test_hd(t); + test_hd(t); + // host-note@-1 {{in instantiation of function template specialization 'test_hd' requested here}} + test_hd(t); + // device-note@-1 {{in instantiation of function template specialization 'test_hd' requested here}} + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); +} Index: clang/test/SemaCUDA/call-host-fn-from-device.cu === --- clang/test/SemaCUDA/call-host-fn-from-device.cu +++ clang/test/SemaCUDA/call-host-fn-from-device.cu @@ -41,12 +41,12 @@ operator Dummy() { return Dummy(); } // expected-note@-1 {{'operator Dummy' declared here}} - __host__ void operator delete(void*); - __device__ void operator delete(void*, size_t); + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void*, __SIZE_TYPE__); }; struct U { - __device__ void operator delete(void*, size_t) = delete; + __device__ void operator delete(void*, __SIZE_TYPE__) = delete; __host__ __device__ void operator delete(void*); }; Index: clang/test/CodeGenCUDA/usual-deallocators.cu === --- /dev/null +++ clang/test/CodeGenCUDA/usual-deallocators.cu @@ -0,0 +1,133 @@ +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emit-llvm -o - | FileCheck %s --check-prefixes=
[PATCH] D51808: [CUDA] Ignore uncallable functions when we check for usual deallocators.
tra updated this revision to Diff 165794. tra added a comment. Addressed Richard's comments. Moved clang-tidy changes into separate review https://reviews.llvm.org/D52179. https://reviews.llvm.org/D51808 Files: clang/include/clang/AST/DeclCXX.h clang/include/clang/Sema/Sema.h clang/lib/AST/DeclCXX.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExprCXX.cpp clang/test/CodeGenCUDA/usual-deallocators.cu clang/test/SemaCUDA/call-host-fn-from-device.cu clang/test/SemaCUDA/usual-deallocators.cu Index: clang/test/SemaCUDA/usual-deallocators.cu === --- /dev/null +++ clang/test/SemaCUDA/usual-deallocators.cu @@ -0,0 +1,95 @@ +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emit-llvm -o /dev/null -verify=device +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown \ +// RUN: -emit-llvm -o /dev/null -verify=host +// RUN: %clang_cc1 %s --std=c++17 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emit-llvm -o /dev/null -verify=device +// RUN: %clang_cc1 %s --std=c++17 -triple nvptx-unknown-unknown \ +// RUN: -emit-llvm -o /dev/null -verify=host + +#include "Inputs/cuda.h" +extern __host__ void host_fn(); +extern __device__ void dev_fn(); +extern __host__ __device__ void hd_fn(); + +struct H1D1 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct h1D1 { + __host__ void operator delete(void *) = delete; + // host-note@-1 {{'operator delete' has been explicitly marked deleted here}} + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H1d1 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) = delete; + // device-note@-1 {{'operator delete' has been explicitly marked deleted here}} +}; + +struct H1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H2D1 { + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H2D2 { + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1D1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1H2D1 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H1H2D2 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1H2D1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + + +template +__host__ __device__ void test_hd(void *p) { + T *t = (T *)p; + delete t; + // host-error@-1 {{attempt to use a deleted function}} + // device-error@-2 {{attempt to use a deleted function}} +} + +__host__ __device__ void tests_hd(void *t) { + test_hd(t); + test_hd(t); + // host-note@-1 {{in instantiation of function template specialization 'test_hd' requested here}} + test_hd(t); + // device-note@-1 {{in instantiation of function template specialization 'test_hd' requested here}} + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); +} Index: clang/test/SemaCUDA/call-host-fn-from-device.cu === --- clang/test/SemaCUDA/call-host-fn-from-device.cu +++ clang/test/SemaCUDA/call-host-fn-from-device.cu @@ -41,12 +41,12 @@ operator Dummy() { return Dummy(); } // expected-note@-1 {{'operator Dummy' declared here}} - __host__ void operator delete(void*); - __device__ void operator delete(void*, size_t); + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void*, __SIZE_TYPE__); }; struct U { - __device__ void operator delete(void*, size_t) = delete; + __device__ void operator delete(void*, __SIZE_TYPE__) = delete; __host__ __device__ void operator delete(void*); }; Index: clang/test/CodeGenCUDA/usual-deallocators.cu === --- /dev/null +++ clang/test/CodeGenCUDA/usual-deallocators.cu @@ -0,0 +1,133 @@ +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emi
[PATCH] D51808: [CUDA] Ignore uncallable functions when we check for usual deallocators.
rsmith added inline comments. Comment at: clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp:551 if (Decl->isMain() || !Decl->isUserProvided() || -Decl->isUsualDeallocationFunction() || -Decl->isCopyAssignmentOperator() || Decl->isMoveAssignmentOperator() || -Decl->size_overridden_methods() > 0) +Decl->isOverloadedOperator() || Decl->size_overridden_methods() > 0) return SK_Invalid; I believe the `isOverloadedOperator` check here is redundant. The caller already checked that the name is an identifier. If you want to keep some check of this kind, I'd suggest checking `D->getIdentifier()` at the start of this function and removing the check here. (Note that `CXXMethodDecl` is not the only `Decl` subclass that can have a non-identifier name.) Comment at: clang/lib/AST/DeclCXX.cpp:2068-2076 + bool Result = true; + for (const auto *D : R) { +if (const auto *FD = dyn_cast(D)) { + Matches.push_back(FD); if (FD->getNumParams() == 1) -return false; +Result = false; +} I think it would make more sense to put only the 1-parameter functions into `Matches`, and rename it to `PreventedBy` or something: then it's the list of single-parameter usual deallocation functions that prevent this one being a usual deallocation function. https://reviews.llvm.org/D51808 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D51808: [CUDA] Ignore uncallable functions when we check for usual deallocators.
tra added a comment. @rsmith ping. https://reviews.llvm.org/D51808 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D51808: [CUDA] Ignore uncallable functions when we check for usual deallocators.
tra created this revision. tra added a reviewer: rsmith. Herald added subscribers: bixia, jlebar, sanjoy. Previously clang considered function variants from both sides of compilation and that sometimes resulted in picking up wrong deallocation function. https://reviews.llvm.org/D51808 Files: clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp clang/include/clang/AST/DeclCXX.h clang/include/clang/Sema/Sema.h clang/lib/AST/DeclCXX.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExprCXX.cpp clang/test/CodeGenCUDA/usual-deallocators.cu clang/test/SemaCUDA/call-host-fn-from-device.cu clang/test/SemaCUDA/usual-deallocators.cu Index: clang/test/SemaCUDA/usual-deallocators.cu === --- /dev/null +++ clang/test/SemaCUDA/usual-deallocators.cu @@ -0,0 +1,95 @@ +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emit-llvm -o /dev/null -verify=device +// RUN: %clang_cc1 %s --std=c++11 -triple nvptx-unknown-unknown \ +// RUN: -emit-llvm -o /dev/null -verify=host +// RUN: %clang_cc1 %s --std=c++17 -triple nvptx-unknown-unknown -fcuda-is-device \ +// RUN: -emit-llvm -o /dev/null -verify=device +// RUN: %clang_cc1 %s --std=c++17 -triple nvptx-unknown-unknown \ +// RUN: -emit-llvm -o /dev/null -verify=host + +#include "Inputs/cuda.h" +extern __host__ void host_fn(); +extern __device__ void dev_fn(); +extern __host__ __device__ void hd_fn(); + +struct H1D1 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct h1D1 { + __host__ void operator delete(void *) = delete; + // host-note@-1 {{'operator delete' has been explicitly marked deleted here}} + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H1d1 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) = delete; + // device-note@-1 {{'operator delete' has been explicitly marked deleted here}} +}; + +struct H1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H2D1 { + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H2D2 { + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1D1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1H2D1 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; +}; + +struct H1H2D2 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + +struct H1H2D1D2 { + __host__ void operator delete(void *) { host_fn(); }; + __host__ void operator delete(void *, __SIZE_TYPE__) { host_fn(); }; + __device__ void operator delete(void *) { dev_fn(); }; + __device__ void operator delete(void *, __SIZE_TYPE__) { dev_fn(); }; +}; + + +template +__host__ __device__ void test_hd(void *p) { + T *t = (T *)p; + delete t; + // host-error@-1 {{attempt to use a deleted function}} + // device-error@-2 {{attempt to use a deleted function}} +} + +__host__ __device__ void tests_hd(void *t) { + test_hd(t); + test_hd(t); + // host-note@-1 {{in instantiation of function template specialization 'test_hd' requested here}} + test_hd(t); + // device-note@-1 {{in instantiation of function template specialization 'test_hd' requested here}} + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); + test_hd(t); +} Index: clang/test/SemaCUDA/call-host-fn-from-device.cu === --- clang/test/SemaCUDA/call-host-fn-from-device.cu +++ clang/test/SemaCUDA/call-host-fn-from-device.cu @@ -41,12 +41,12 @@ operator Dummy() { return Dummy(); } // expected-note@-1 {{'operator Dummy' declared here}} - __host__ void operator delete(void*); - __device__ void operator delete(void*, size_t); + __host__ void operator delete(void *) { host_fn(); }; + __device__ void operator delete(void*, __SIZE_TYPE__); }; struct U { - __device__ void operator delete(void*, size_t) = delete; + __device__ void operator delete(void*, __SIZE_TYPE__) = delete; __host__ __device__ void operator delete(void*); }; Index: clang/test/CodeGenCUDA/usual-deallocators.cu === --- /dev/null +++ clang/test