summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaCUDA.cpp
diff options
context:
space:
mode:
authorYaxun Liu <Yaxun.Liu@amd.com>2019-03-05 18:19:35 +0000
committerYaxun Liu <Yaxun.Liu@amd.com>2019-03-05 18:19:35 +0000
commit0b750519479c910492068af7de1e2aef2cbc5071 (patch)
tree81a112da30b9977cf12a3cc1529e6a66b420128f /lib/Sema/SemaCUDA.cpp
parenta73ceaf4aed15d968b17fafbd1b1606ccbd986e5 (diff)
downloadclang-0b750519479c910492068af7de1e2aef2cbc5071.tar.gz
[CUDA][HIP][Sema] Fix template kernel with function as template parameter
If a kernel template has a function as its template parameter, a device function should be allowed as template argument since a kernel can call a device function. However, currently if the kernel template is instantiated in a host function, clang will emit an error message saying the device function is an invalid candidate for the template parameter. This happens because clang checks the reference to the device function during parsing the template arguments. At this point, the template is not instantiated yet. Clang incorrectly assumes the device function is called by the host function and emits the error message. This patch fixes the issue by disabling checking of device function during parsing template arguments and deferring the check to the instantion of the template. At that point, the template decl is already available, therefore the check can be done against the instantiated function template decl. Differential Revision: https://reviews.llvm.org/D56411 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@355421 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCUDA.cpp')
-rw-r--r--lib/Sema/SemaCUDA.cpp5
1 files changed, 5 insertions, 0 deletions
diff --git a/lib/Sema/SemaCUDA.cpp b/lib/Sema/SemaCUDA.cpp
index 5aa788eda2..d062e8b201 100644
--- a/lib/Sema/SemaCUDA.cpp
+++ b/lib/Sema/SemaCUDA.cpp
@@ -675,6 +675,11 @@ Sema::DeviceDiagBuilder Sema::CUDADiagIfHostCode(SourceLocation Loc,
bool Sema::CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee) {
assert(getLangOpts().CUDA && "Should only be called during CUDA compilation");
assert(Callee && "Callee may not be null.");
+
+ auto &ExprEvalCtx = ExprEvalContexts.back();
+ if (ExprEvalCtx.isUnevaluated() || ExprEvalCtx.isConstantEvaluated())
+ return true;
+
// FIXME: Is bailing out early correct here? Should we instead assume that
// the caller is a global initializer?
FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext);