-
Notifications
You must be signed in to change notification settings - Fork 770
[SYCL] Move variadic call diagnostics to delayed diagnostics, fixes. #998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -184,7 +184,7 @@ static bool IsSyclMathFunc(unsigned BuiltinID) { | |
return true; | ||
} | ||
|
||
static bool isKnownGoodDecl(const Decl *D) { | ||
bool Sema::isKnownGoodSYCLDecl(const Decl *D) { | ||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { | ||
const IdentifierInfo *II = FD->getIdentifier(); | ||
const DeclContext *DC = FD->getDeclContext(); | ||
|
@@ -326,7 +326,7 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> { | |
|
||
bool VisitDeclRefExpr(DeclRefExpr *E) { | ||
Decl* D = E->getDecl(); | ||
if (isKnownGoodDecl(D)) | ||
if (SemaRef.isKnownGoodSYCLDecl(D)) | ||
return true; | ||
|
||
CheckSYCLType(E->getType(), E->getSourceRange()); | ||
|
@@ -372,18 +372,6 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> { | |
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Were these dead code and safe to remove? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They were not, but are now :) When This is the case in the commit message where we had done 2 versions of diagnostics for the inline assembly, but bugs in each made them not cover all cases, but combined, they seemed to. My fix to the delayed diagnostics made the assembly error handling in normal 'Sema' cover the cases that this caught. |
||
CallGraph SYCLCG; | ||
// The set of functions called by a kernel function. | ||
|
@@ -549,9 +537,6 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> { | |
} | ||
} | ||
} else if (const auto *FPTy = dyn_cast<FunctionProtoType>(Ty)) { | ||
if (FPTy->isVariadic() && SemaRef.getLangOpts().SYCLIsDevice) | ||
SemaRef.SYCLDiagIfDeviceCode(Loc.getBegin(), diag::err_sycl_restrict) | ||
<< Sema::KernelCallVariadicFunction; | ||
for (const auto &ParamTy : FPTy->param_types()) | ||
if (!CheckSYCLType(ParamTy, Loc, Visited)) | ||
return false; | ||
|
@@ -1308,8 +1293,10 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc, | |
// in different translation units. | ||
OpenCLKernel->setImplicitlyInline(KernelCallerFunc->isInlined()); | ||
|
||
ConstructingOpenCLKernel = true; | ||
CompoundStmt *OpenCLKernelBody = | ||
CreateOpenCLKernelBody(*this, KernelCallerFunc, OpenCLKernel); | ||
ConstructingOpenCLKernel = false; | ||
OpenCLKernel->setBody(OpenCLKernelBody); | ||
addSyclDeviceDecl(OpenCLKernel); | ||
} | ||
|
@@ -1404,13 +1391,13 @@ static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { | |
if (!FD) | ||
return true; // Seen in LIT testing | ||
|
||
if (FD->hasAttr<SYCLDeviceAttr>() || FD->hasAttr<SYCLKernelAttr>()) | ||
Fznamznon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return true; | ||
|
||
// Templates are emitted when they're instantiated. | ||
if (FD->isDependentContext()) | ||
return false; | ||
|
||
if (FD->hasAttr<SYCLDeviceAttr>() || FD->hasAttr<SYCLKernelAttr>()) | ||
return true; | ||
|
||
// Otherwise, the function is known-emitted if it's in our set of | ||
// known-emitted functions. | ||
return S.DeviceKnownEmittedFns.count(FD) > 0; | ||
|
@@ -1420,18 +1407,20 @@ Sema::DeviceDiagBuilder Sema::SYCLDiagIfDeviceCode(SourceLocation Loc, | |
unsigned DiagID) { | ||
assert(getLangOpts().SYCLIsDevice && | ||
"Should only be called during SYCL compilation"); | ||
DeviceDiagBuilder::Kind DiagKind = [this] { | ||
if (isKnownEmitted(*this, dyn_cast<FunctionDecl>(CurContext))) | ||
FunctionDecl *FD = dyn_cast<FunctionDecl>(getCurLexicalContext()); | ||
DeviceDiagBuilder::Kind DiagKind = [this, FD] { | ||
if (ConstructingOpenCLKernel || (FD && FD->isDependentContext())) | ||
return DeviceDiagBuilder::K_Nop; | ||
else if (isKnownEmitted(*this, FD)) | ||
return DeviceDiagBuilder::K_ImmediateWithCallStack; | ||
return DeviceDiagBuilder::K_Deferred; | ||
}(); | ||
return DeviceDiagBuilder(DiagKind, Loc, DiagID, | ||
dyn_cast<FunctionDecl>(CurContext), *this); | ||
return DeviceDiagBuilder(DiagKind, Loc, DiagID, FD, *this); | ||
} | ||
|
||
bool Sema::CheckSYCLCall(SourceLocation Loc, FunctionDecl *Callee) { | ||
assert(Callee && "Callee may not be null."); | ||
FunctionDecl *Caller = getCurFunctionDecl(); | ||
FunctionDecl *Caller = dyn_cast<FunctionDecl>(getCurLexicalContext()); | ||
|
||
// If the caller is known-emitted, mark the callee as known-emitted. | ||
// Otherwise, mark the call in our call graph so we can traverse it later. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// RUN: %clang_cc1 -triple spir64-unknown-unknown -fsycl-is-device -fsyntax-only -verify %s | ||
|
||
void variadic(int, ...); | ||
namespace NS { | ||
void variadic(int, ...); | ||
} | ||
|
||
struct S { | ||
S(int, ...); | ||
void operator()(int, ...); | ||
}; | ||
|
||
void foo() { | ||
auto x = [](int, ...) {}; | ||
x(5, 10); //expected-error{{SYCL kernel cannot call a variadic function}} | ||
} | ||
|
||
void overloaded(int, int); | ||
void overloaded(int, ...); | ||
template <typename, typename Func> | ||
__attribute__((sycl_kernel)) void task(Func KF) { | ||
KF(); // expected-note 2 {{called by 'task}} | ||
} | ||
|
||
int main() { | ||
task<class FK>([]() { | ||
variadic(5); //expected-error{{SYCL kernel cannot call a variadic function}} | ||
variadic(5, 2); //expected-error{{SYCL kernel cannot call a variadic function}} | ||
NS::variadic(5, 3); //expected-error{{SYCL kernel cannot call a variadic function}} | ||
S s(5, 4); //expected-error{{SYCL kernel cannot call a variadic function}} | ||
S s2(5); //expected-error{{SYCL kernel cannot call a variadic function}} | ||
s(5, 5); //expected-error{{SYCL kernel cannot call a variadic function}} | ||
s2(5); //expected-error{{SYCL kernel cannot call a variadic function}} | ||
foo(); //expected-note{{called by 'operator()'}} | ||
overloaded(5, 6); //expected-no-error | ||
overloaded(5, s); //expected-error{{SYCL kernel cannot call a variadic function}} | ||
overloaded(5); //expected-error{{SYCL kernel cannot call a variadic function}} | ||
}); | ||
} |
Uh oh!
There was an error while loading. Please reload this page.