[CUDA] Ignore uncallable functions when we check for usual deallocators.
Previously clang considered function variants from both sides of
compilation and that resulted in picking up wrong deallocation function.
Differential Revision: https://reviews.llvm.org/D51808
llvm-svn: 342749
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 1831430..dd5dfaa 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1448,11 +1448,33 @@
return Result;
}
+bool Sema::isUsualDeallocationFunction(const CXXMethodDecl *Method) {
+ // [CUDA] Ignore this function, if we can't call it.
+ const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext);
+ if (getLangOpts().CUDA &&
+ IdentifyCUDAPreference(Caller, Method) <= CFP_WrongSide)
+ return false;
+
+ SmallVector<const FunctionDecl*, 4> PreventedBy;
+ bool Result = Method->isUsualDeallocationFunction(PreventedBy);
+
+ if (Result || !getLangOpts().CUDA || PreventedBy.empty())
+ return Result;
+
+ // In case of CUDA, return true if none of the 1-argument deallocator
+ // functions are actually callable.
+ return llvm::none_of(PreventedBy, [&](const FunctionDecl *FD) {
+ assert(FD->getNumParams() == 1 &&
+ "Only single-operand functions should be in PreventedBy");
+ return IdentifyCUDAPreference(Caller, FD) >= CFP_HostDevice;
+ });
+}
+
/// Determine whether the given function is a non-placement
/// deallocation function.
static bool isNonPlacementDeallocationFunction(Sema &S, FunctionDecl *FD) {
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FD))
- return Method->isUsualDeallocationFunction();
+ return S.isUsualDeallocationFunction(Method);
if (FD->getOverloadedOperator() != OO_Delete &&
FD->getOverloadedOperator() != OO_Array_Delete)