diff options
author | Artem Belevich <tra@google.com> | 2018-09-21 17:29:33 +0000 |
---|---|---|
committer | Artem Belevich <tra@google.com> | 2018-09-21 17:29:33 +0000 |
commit | 78929efb4dcbb2c8aeba46eee912a614d4ecebb9 (patch) | |
tree | d8ae6e44b0267bf826d68a01e9ad339e984d9cc0 /clang/lib/Sema/SemaExprCXX.cpp | |
parent | a3d0f409647a2051c1cd1546c48369f9f9ce3f27 (diff) | |
download | bcm5719-llvm-78929efb4dcbb2c8aeba46eee912a614d4ecebb9.tar.gz bcm5719-llvm-78929efb4dcbb2c8aeba46eee912a614d4ecebb9.zip |
[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
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 1831430ad12..dd5dfaacf24 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1448,11 +1448,33 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, 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) |