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 | |
| 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')
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 24 |
2 files changed, 25 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 95ad45d4954..eb3a2fc0138 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -13183,7 +13183,8 @@ CheckOperatorDeleteDeclaration(Sema &SemaRef, FunctionDecl *FnDecl) { // C++ P0722: // A destroying operator delete shall be a usual deallocation function. if (MD && !MD->getParent()->isDependentContext() && - MD->isDestroyingOperatorDelete() && !MD->isUsualDeallocationFunction()) { + MD->isDestroyingOperatorDelete() && + !SemaRef.isUsualDeallocationFunction(MD)) { SemaRef.Diag(MD->getLocation(), diag::err_destroying_operator_delete_not_usual); return true; 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) |

