From 50d4b4b28071dd455139f45f8b48698d9f8f0326 Mon Sep 17 00:00:00 2001 From: Premanand M Rao Date: Tue, 17 Sep 2019 08:57:45 -0700 Subject: [PATCH] [SYCL] Diagnose violations from function object passed to the kernel Scan the body of the routine passed as a function object to the SYCL kernel. The call graph traversed previously to emit deferred diagnostics was missing the passed function object. Signed-off-by: Premanand M Rao --- clang/lib/Sema/Sema.cpp | 25 +++++++++++++++++++++++++ clang/lib/Sema/SemaSYCL.cpp | 12 ------------ clang/test/SemaSYCL/diag-fobj-call.cpp | 15 +++++++++++++++ clang/test/SemaSYCL/inline-asm.cpp | 1 + clang/test/SemaSYCL/sycl-restrict.cpp | 1 - 5 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 clang/test/SemaSYCL/diag-fobj-call.cpp diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 385c7064e1d3c..7f7c455b1f7e0 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1386,6 +1386,13 @@ Sema::Diag(SourceLocation Loc, const PartialDiagnostic& PD) { static void emitCallStackNotes(Sema &S, FunctionDecl *FD) { auto FnIt = S.DeviceKnownEmittedFns.find(FD); while (FnIt != S.DeviceKnownEmittedFns.end()) { + if (S.getLangOpts().SYCLIsDevice && + FnIt->second.FD->hasAttr()) { + // Skip over the routines with sycl_kernel attributes + // in the traceback as they are likely from SYCL headers. + FnIt = S.DeviceKnownEmittedFns.find(FnIt->second.FD); + continue; + } DiagnosticBuilder Builder( S.Diags.Report(FnIt->second.Loc, diag::note_called_by)); Builder << FnIt->second.FD; @@ -1533,6 +1540,24 @@ void Sema::markKnownEmitted( } } + // Function object calls are not walked above. + // Extract the call expression from the statement block. + FunctionDecl *FD = C.Callee->getDefinition(); + const CompoundStmt *CS = FD ? dyn_cast_or_null(FD->getBody()) + : nullptr; + if (CS) + for (auto *I : CS->body()) { + FunctionDecl *D = nullptr; + CallExpr *CE = dyn_cast(I); + if (CE) + D = dyn_cast_or_null(CE->getCalleeDecl()); + if (!D || Seen.count(D) || IsKnownEmitted(S, D)) + continue; + Seen.insert(D); + Worklist.push_back( + {/* Caller = */ C.Callee, /* Callee = */ D, CE->getBeginLoc()}); + } + // Add all functions called by Callee to our worklist. auto CGIt = S.DeviceCallGraph.find(C.Callee); if (CGIt == S.DeviceCallGraph.end()) diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index 09e66dcda9065..ff888da86cde3 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -354,18 +354,6 @@ class MarkDeviceFunction : public RecursiveASTVisitor { return true; } - bool VisitGCCAsmStmt(GCCAsmStmt *S) { - SemaRef.Diag(S->getBeginLoc(), diag::err_sycl_restrict) - << Sema::KernelUseAssembly; - return true; - } - - bool VisitMSAsmStmt(MSAsmStmt *S) { - SemaRef.Diag(S->getBeginLoc(), diag::err_sycl_restrict) - << Sema::KernelUseAssembly; - return true; - } - // The call graph for this translation unit. CallGraph SYCLCG; // The set of functions called by a kernel function. diff --git a/clang/test/SemaSYCL/diag-fobj-call.cpp b/clang/test/SemaSYCL/diag-fobj-call.cpp new file mode 100644 index 0000000000000..45b43ed427e0f --- /dev/null +++ b/clang/test/SemaSYCL/diag-fobj-call.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fcxx-exceptions -fsycl-is-device -fsyntax-only -verify %s + +void bar() { throw 5; } // expected-no-error +void foo() { throw 10; } // expected-error {{SYCL kernel cannot use exceptions}} + +template +__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) { + kernelFunc(); +} + +int main() { + // expected-note@+1 {{called by 'operator()'}} + kernel_single_task([]() { foo(); }); + bar(); +} diff --git a/clang/test/SemaSYCL/inline-asm.cpp b/clang/test/SemaSYCL/inline-asm.cpp index cab5ff20b2659..3cefa4f4ad393 100644 --- a/clang/test/SemaSYCL/inline-asm.cpp +++ b/clang/test/SemaSYCL/inline-asm.cpp @@ -26,6 +26,7 @@ __attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) { int main() { foo(); + // expected-note@+1 {{called by 'operator()'}} kernel_single_task([]() { bar(); }); return 0; } diff --git a/clang/test/SemaSYCL/sycl-restrict.cpp b/clang/test/SemaSYCL/sycl-restrict.cpp index 8c6fdb1ac7212..48cfd1b3e15a1 100644 --- a/clang/test/SemaSYCL/sycl-restrict.cpp +++ b/clang/test/SemaSYCL/sycl-restrict.cpp @@ -188,7 +188,6 @@ __attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) { kernelFunc(); a_type ab; a_type *p; - // expected-note@+1 {{called by 'kernel_single_task'}} use2(ab, p); }