From b2aec3b939d28cfa6a91cd90b0c911d4a68ed943 Mon Sep 17 00:00:00 2001 From: Premanand M Rao Date: Tue, 25 Jun 2019 12:06:30 -0700 Subject: [PATCH] [SYCL] Deferred diagnostics for SYCL Device Signed-off-by: Premanand M Rao --- .../clang/Basic/DiagnosticSemaKinds.td | 5 +- clang/include/clang/Sema/Sema.h | 14 ++ clang/lib/Sema/SemaDeclCXX.cpp | 2 + clang/lib/Sema/SemaExpr.cpp | 15 +- clang/lib/Sema/SemaExprCXX.cpp | 10 ++ clang/lib/Sema/SemaOverload.cpp | 6 + clang/lib/Sema/SemaSYCL.cpp | 130 ++++++++++-------- clang/lib/Sema/SemaStmt.cpp | 10 ++ clang/lib/Sema/SemaStmtAsm.cpp | 5 + clang/lib/Sema/SemaType.cpp | 8 +- clang/test/SemaSYCL/forward-decl.cpp | 2 +- clang/test/SemaSYCL/inline-asm.cpp | 4 +- clang/test/SemaSYCL/no-vtables2.cpp | 2 +- clang/test/SemaSYCL/no-vtables3.cpp | 2 +- clang/test/SemaSYCL/no-vtables4.cpp | 2 +- clang/test/SemaSYCL/sycl-restrict.cpp | 42 +++--- 16 files changed, 178 insertions(+), 81 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 533aa7e8051d3..02bab16a34aab 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9721,11 +9721,12 @@ def err_sycl_restrict : Error< "|use rtti" "|use a non-const static data variable" "|call a virtual function" + "|use exceptions" "|call a recursive function" "|call through a function pointer" "|allocate storage" - "|use exceptions" - "|use inline assembly}0">; + "|use inline assembly" + "|have a class with a virtual function table}0">; def err_sycl_virtual_types : Error< "No class with a vtable can be used in a SYCL kernel or any code included in the kernel">; def note_sycl_used_here : Note<"used here">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 49070aee9015f..8926aff922cb8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11275,8 +11275,22 @@ class Sema { return *SyclIntHeader.get(); } + enum SYCLRestrictKind { + KernelGlobalVariable, + KernelRTTI, + KernelNonConstStaticDataVariable, + KernelCallVirtualFunction, + KernelUseExceptions, + KernelCallRecursiveFunction, + KernelCallFunctionPointer, + KernelAllocateStorage, + KernelUseAssembly, + KernelHavePolymorphicClass + }; + DeviceDiagBuilder SYCLDiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); void ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc); void MarkDevice(void); + bool CheckSYCLCall(SourceLocation Loc, FunctionDecl *Callee); }; /// RAII object that enters a new expression evaluation context. diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index b3920ff01bdff..a2c40dcb929f6 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -13031,6 +13031,8 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, MarkFunctionReferenced(ConstructLoc, Constructor); if (getLangOpts().CUDA && !CheckCUDACall(ConstructLoc, Constructor)) return ExprError(); + if (getLangOpts().SYCLIsDevice) + CheckSYCLCall(ConstructLoc, Constructor); return CXXConstructExpr::Create( Context, DeclInitType, ConstructLoc, Constructor, Elidable, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4e97122cd553c..ef6979287024b 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -271,6 +271,9 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef Locs, if (getLangOpts().CUDA && !CheckCUDACall(Loc, FD)) return true; + + if (getLangOpts().SYCLIsDevice) + CheckSYCLCall(Loc, FD); } if (auto *MD = dyn_cast(D)) { @@ -14903,6 +14906,8 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, if (getLangOpts().CUDA) CheckCUDACall(Loc, Func); + if (getLangOpts().SYCLIsDevice) + CheckSYCLCall(Loc, Func); // If we don't need to mark the function as used, and we don't need to // try to provide a definition, there's nothing more to do. @@ -16124,7 +16129,15 @@ namespace { } void VisitCXXNewExpr(CXXNewExpr *E) { - if (E->getOperatorNew()) + FunctionDecl *FD = E->getOperatorNew(); + if (FD && S.getLangOpts().SYCLIsDevice) { + if (FD->isReplaceableGlobalAllocationFunction()) + S.SYCLDiagIfDeviceCode(E->getExprLoc(), diag::err_sycl_restrict) + << S.KernelAllocateStorage; + else if (FunctionDecl *Def = FD->getDefinition()) + S.CheckSYCLCall(E->getExprLoc(), Def); + } + if (FD) S.MarkFunctionReferenced(E->getBeginLoc(), E->getOperatorNew()); if (E->getOperatorDelete()) S.MarkFunctionReferenced(E->getBeginLoc(), E->getOperatorDelete()); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 87dc3a9a54a9a..8d868fb344deb 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -760,6 +760,11 @@ ExprResult Sema::BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, CUDADiagIfDeviceCode(OpLoc, diag::err_cuda_device_exceptions) << "throw" << CurrentCUDATarget(); + // Exceptions aren't allowed in SYCL device code. + if (getLangOpts().SYCLIsDevice) + SYCLDiagIfDeviceCode(OpLoc, diag::err_sycl_restrict) + << Sema::KernelUseExceptions; + if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope()) Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw"; @@ -2193,11 +2198,16 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, if (DiagnoseUseOfDecl(OperatorNew, StartLoc)) return ExprError(); MarkFunctionReferenced(StartLoc, OperatorNew); + if (getLangOpts().SYCLIsDevice) { + CheckSYCLCall(StartLoc, OperatorNew); + } } if (OperatorDelete) { if (DiagnoseUseOfDecl(OperatorDelete, StartLoc)) return ExprError(); MarkFunctionReferenced(StartLoc, OperatorDelete); + if (getLangOpts().SYCLIsDevice) + CheckSYCLCall(StartLoc, OperatorDelete); } return CXXNewExpr::Create(Context, UseGlobal, OperatorNew, OperatorDelete, diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index eadc01e5efb6b..bc2cea6f5c24c 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -12396,6 +12396,8 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, FnDecl->getType()->castAs())) return ExprError(); + if (getLangOpts().SYCLIsDevice) + CheckSYCLCall(OpLoc, FnDecl); return MaybeBindToTemporary(TheCall); } else { // We matched a built-in operator. Convert the arguments, then @@ -12639,6 +12641,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, isa(FnDecl), OpLoc, TheCall->getSourceRange(), VariadicDoesNotApply); + if (getLangOpts().SYCLIsDevice) + CheckSYCLCall(OpLoc, FnDecl); return MaybeBindToTemporary(TheCall); } else { // We matched a built-in operator. Convert the arguments, then @@ -12852,6 +12856,8 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, Method->getType()->castAs())) return ExprError(); + if (getLangOpts().SYCLIsDevice) + CheckSYCLCall(RLoc, FnDecl); return MaybeBindToTemporary(TheCall); } else { // We matched a built-in operator. Convert the arguments, then diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index 604726131179f..2ed045c244643 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -38,18 +38,6 @@ enum target { image_array }; -enum RestrictKind { - KernelGlobalVariable, - KernelRTTI, - KernelNonConstStaticDataVariable, - KernelCallVirtualFunction, - KernelCallRecursiveFunction, - KernelCallFunctionPointer, - KernelAllocateStorage, - KernelUseExceptions, - KernelUseAssembly -}; - using ParamDesc = std::tuple; /// Various utilities. @@ -95,16 +83,16 @@ class MarkDeviceFunction : public RecursiveASTVisitor { // definitions. if (RecursiveSet.count(Callee)) { SemaRef.Diag(e->getExprLoc(), diag::err_sycl_restrict) - << KernelCallRecursiveFunction; + << Sema::KernelCallRecursiveFunction; SemaRef.Diag(Callee->getSourceRange().getBegin(), diag::note_sycl_recursive_function_declared_here) - << KernelCallRecursiveFunction; + << Sema::KernelCallRecursiveFunction; } if (const CXXMethodDecl *Method = dyn_cast(Callee)) if (Method->isVirtual()) SemaRef.Diag(e->getExprLoc(), diag::err_sycl_restrict) - << KernelCallVirtualFunction; + << Sema::KernelCallVirtualFunction; CheckSYCLType(Callee->getReturnType(), Callee->getSourceRange()); @@ -116,7 +104,7 @@ class MarkDeviceFunction : public RecursiveASTVisitor { } } else if (!SemaRef.getLangOpts().SYCLAllowFuncPtr) SemaRef.Diag(e->getExprLoc(), diag::err_sycl_restrict) - << KernelCallFunctionPointer; + << Sema::KernelCallFunctionPointer; return true; } @@ -144,12 +132,12 @@ class MarkDeviceFunction : public RecursiveASTVisitor { } bool VisitCXXTypeidExpr(CXXTypeidExpr *E) { - SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) << KernelRTTI; + SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) << Sema::KernelRTTI; return true; } bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) { - SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) << KernelRTTI; + SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) << Sema::KernelRTTI; return true; } @@ -178,7 +166,7 @@ class MarkDeviceFunction : public RecursiveASTVisitor { bool IsConst = VD->getType().getNonReferenceType().isConstQualified(); if (!IsConst && VD->isStaticDataMember()) SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) - << KernelNonConstStaticDataVariable; + << Sema::KernelNonConstStaticDataVariable; } return true; } @@ -189,11 +177,11 @@ class MarkDeviceFunction : public RecursiveASTVisitor { bool IsConst = VD->getType().getNonReferenceType().isConstQualified(); if (!IsConst && VD->isStaticDataMember()) SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) - << KernelNonConstStaticDataVariable; + << Sema::KernelNonConstStaticDataVariable; else if (!IsConst && VD->hasGlobalStorage() && !VD->isStaticLocal() && !VD->isStaticDataMember() && !isa(VD)) SemaRef.Diag(E->getLocation(), diag::err_sycl_restrict) - << KernelGlobalVariable; + << Sema::KernelGlobalVariable; if (!VD->isLocalVarDeclOrParm() && VD->hasGlobalStorage()) { VD->addAttr(SYCLDeviceAttr::CreateImplicit(SemaRef.Context)); SemaRef.addSyclDeviceDecl(VD); @@ -213,7 +201,7 @@ class MarkDeviceFunction : public RecursiveASTVisitor { if (FunctionDecl *FD = E->getOperatorNew()) { if (FD->isReplaceableGlobalAllocationFunction()) { SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) - << KernelAllocateStorage; + << Sema::KernelAllocateStorage; } else if (FunctionDecl *Def = FD->getDefinition()) { if (!Def->hasAttr()) { Def->addAttr(SYCLDeviceAttr::CreateImplicit(SemaRef.Context)); @@ -223,40 +211,16 @@ class MarkDeviceFunction : public RecursiveASTVisitor { } return true; } - - bool VisitCXXThrowExpr(CXXThrowExpr *E) { - SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) - << KernelUseExceptions; - return true; - } - - bool VisitCXXCatchStmt(CXXCatchStmt *S) { - SemaRef.Diag(S->getBeginLoc(), diag::err_sycl_restrict) - << KernelUseExceptions; - return true; - } - - bool VisitCXXTryStmt(CXXTryStmt *S) { - SemaRef.Diag(S->getBeginLoc(), diag::err_sycl_restrict) - << KernelUseExceptions; - return true; - } - - bool VisitSEHTryStmt(SEHTryStmt *S) { - SemaRef.Diag(S->getBeginLoc(), diag::err_sycl_restrict) - << KernelUseExceptions; - return true; - } - + bool VisitGCCAsmStmt(GCCAsmStmt *S) { SemaRef.Diag(S->getBeginLoc(), diag::err_sycl_restrict) - << KernelUseAssembly; + << Sema::KernelUseAssembly; return true; } - + bool VisitMSAsmStmt(MSAsmStmt *S) { SemaRef.Diag(S->getBeginLoc(), diag::err_sycl_restrict) - << KernelUseAssembly; + << Sema::KernelUseAssembly; return true; } @@ -361,21 +325,31 @@ class MarkDeviceFunction : public RecursiveASTVisitor { return true; if (CRD->isPolymorphic()) { - SemaRef.Diag(CRD->getLocation(), diag::err_sycl_virtual_types); - SemaRef.Diag(Loc.getBegin(), diag::note_sycl_used_here); + // Exceptions aren't allowed in SYCL device code. + if (SemaRef.getLangOpts().SYCLIsDevice) { + SemaRef.SYCLDiagIfDeviceCode(CRD->getLocation(), + diag::err_sycl_restrict) + << Sema::KernelHavePolymorphicClass; + SemaRef.SYCLDiagIfDeviceCode(Loc.getBegin(), + diag::note_sycl_used_here); + } return false; } for (const auto &Field : CRD->fields()) { if (!CheckSYCLType(Field->getType(), Field->getSourceRange(), Visited)) { - SemaRef.Diag(Loc.getBegin(), diag::note_sycl_used_here); + if (SemaRef.getLangOpts().SYCLIsDevice) + SemaRef.SYCLDiagIfDeviceCode(Loc.getBegin(), + diag::note_sycl_used_here); return false; } } } else if (const auto *RD = Ty->getAsRecordDecl()) { for (const auto &Field : RD->fields()) { if (!CheckSYCLType(Field->getType(), Field->getSourceRange(), Visited)) { - SemaRef.Diag(Loc.getBegin(), diag::note_sycl_used_here); + if (SemaRef.getLangOpts().SYCLIsDevice) + SemaRef.SYCLDiagIfDeviceCode(Loc.getBegin(), + diag::note_sycl_used_here); return false; } } @@ -1036,6 +1010,54 @@ void Sema::MarkDevice(void) { } } } +// +// Do we know that we will eventually codegen the given function? +static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { + if (!FD) + return true; // Seen in LIT testing + + if (FD->hasAttr() || + FD->hasAttr()) + return true; + + // Templates are emitted when they're instantiated. + if (FD->isDependentContext()) + return false; + + // Otherwise, the function is known-emitted if it's in our set of + // known-emitted functions. + return S.DeviceKnownEmittedFns.count(FD) > 0; +} + +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(CurContext))) + return DeviceDiagBuilder::K_ImmediateWithCallStack; + return DeviceDiagBuilder::K_Deferred; + }(); + return DeviceDiagBuilder(DiagKind, Loc, DiagID, + dyn_cast(CurContext), *this); +} + +bool Sema::CheckSYCLCall(SourceLocation Loc, FunctionDecl *Callee) { + + assert(Callee && "Callee may not be null."); + FunctionDecl *Caller = getCurFunctionDecl(); + + // 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. + if (//!isOpenMPDeviceDelayedContext(*this) || + (Caller && Caller->hasAttr()) || + (Caller && Caller->hasAttr()) || + (Caller && isKnownEmitted(*this, Caller))) + markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); + else if (Caller) + DeviceCallGraph[Caller].insert({Callee, Loc}); + return true; +} // ----------------------------------------------------------------------------- // Integration header functionality implementation diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index c7fb5654516a6..16d2a853256a3 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -4017,6 +4017,11 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, CUDADiagIfDeviceCode(TryLoc, diag::err_cuda_device_exceptions) << "try" << CurrentCUDATarget(); + // Exceptions aren't allowed in SYCL device code. + if (getLangOpts().SYCLIsDevice) + SYCLDiagIfDeviceCode(TryLoc, diag::err_sycl_restrict) + << KernelUseExceptions; + if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope()) Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try"; @@ -4114,6 +4119,11 @@ StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, } } + // Exceptions aren't allowed in SYCL device code. + if (getLangOpts().SYCLIsDevice) + SYCLDiagIfDeviceCode(TryLoc, diag::err_sycl_restrict) + << KernelUseExceptions; + FSI->setHasSEHTry(TryLoc); // Reject __try in Obj-C methods, blocks, and captured decls, since we don't diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index f9f210f911bce..a21bfd4eb8905 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -256,6 +256,8 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, // Skip all the checks if we are compiling SYCL device code, but the function // is not marked to be used on device, this code won't be codegen'ed anyway. if (getLangOpts().SYCLIsDevice) { + SYCLDiagIfDeviceCode(AsmLoc, diag::err_sycl_restrict) + << KernelUseAssembly; GCCAsmStmt *NS = new (Context) GCCAsmStmt( Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names, Constraints, Exprs.data(), AsmString, NumClobbers, Clobbers, RParenLoc); @@ -863,6 +865,9 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, SourceLocation EndLoc) { bool IsSimple = (NumOutputs != 0 || NumInputs != 0); setFunctionHasBranchProtectedScope(); + if (getLangOpts().SYCLIsDevice) + SYCLDiagIfDeviceCode(AsmLoc, diag::err_sycl_restrict) + << KernelUseAssembly; MSAsmStmt *NS = new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple, /*IsVolatile*/ true, AsmToks, NumOutputs, NumInputs, diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 1092cc53ad8ad..787da8742ca95 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1494,7 +1494,8 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { Result = Context.DoubleTy; break; case DeclSpec::TST_float128: - if (!S.Context.getTargetInfo().hasFloat128Type() && + if (!S.Context.getTargetInfo().hasFloat128Type() && + !S.getLangOpts().SYCLIsDevice && !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsDevice)) S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) << "__float128"; @@ -7013,6 +7014,11 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr, << (int)Sema::CallingConventionIgnoredReason::VariadicFunction; attr.setInvalid(); + if (S.getLangOpts().SYCLIsDevice) { + S.SYCLDiagIfDeviceCode(attr.getLoc(), diag::err_cconv_varargs) + << FunctionType::getNameForCallConv(CC); + return true; + } else return S.Diag(attr.getLoc(), diag::err_cconv_varargs) << FunctionType::getNameForCallConv(CC); } diff --git a/clang/test/SemaSYCL/forward-decl.cpp b/clang/test/SemaSYCL/forward-decl.cpp index ec9d7ade406d3..1ec1b317493bf 100644 --- a/clang/test/SemaSYCL/forward-decl.cpp +++ b/clang/test/SemaSYCL/forward-decl.cpp @@ -14,7 +14,7 @@ int main() { }); #elif VIRTUAL kernel_single_task([]() { - // expected-error@+2{{No class with a vtable can be used in a SYCL kernel or any code included in the kernel}} + // expected-error@+2{{SYCL kernel cannot have a class with a virtual function table}} // expected-note@+1{{used here}} class Boo { public: diff --git a/clang/test/SemaSYCL/inline-asm.cpp b/clang/test/SemaSYCL/inline-asm.cpp index 40c2bf6ed9a90..cab5ff20b2659 100644 --- a/clang/test/SemaSYCL/inline-asm.cpp +++ b/clang/test/SemaSYCL/inline-asm.cpp @@ -13,9 +13,9 @@ void foo() { void bar() { int a; #ifdef LINUX_ASM - __asm__("int3"); // expected-error {{SYCL kernel cannot use inline assembly}} + __asm__("int3"); // expected-error {{SYCL kernel cannot use inline assembly}} #else - __asm int 3 // expected-error {{SYCL kernel cannot use inline assembly}} + __asm int 3 // expected-error {{SYCL kernel cannot use inline assembly}} #endif // LINUX_ASM } diff --git a/clang/test/SemaSYCL/no-vtables2.cpp b/clang/test/SemaSYCL/no-vtables2.cpp index f3dd57672a257..8e5ad8565d1ba 100644 --- a/clang/test/SemaSYCL/no-vtables2.cpp +++ b/clang/test/SemaSYCL/no-vtables2.cpp @@ -4,7 +4,7 @@ struct Base { virtual void f() const {} }; -// expected-error@+1 9{{No class with a vtable can be used in a SYCL kernel or any code included in the kernel}} +// expected-error@+1 9{{SYCL kernel cannot have a class with a virtual function table}} struct Inherit : Base { virtual void f() const override {} }; diff --git a/clang/test/SemaSYCL/no-vtables3.cpp b/clang/test/SemaSYCL/no-vtables3.cpp index aebdb82a74292..e3748e9537693 100644 --- a/clang/test/SemaSYCL/no-vtables3.cpp +++ b/clang/test/SemaSYCL/no-vtables3.cpp @@ -4,7 +4,7 @@ struct Base { virtual void f() const {} }; -// expected-error@+1 3{{No class with a vtable can be used in a SYCL kernel or any code included in the kernel}} +// expected-error@+1 3{{SYCL kernel cannot have a class with a virtual function table}} struct Inherit : Base { virtual void f() const override {} }; diff --git a/clang/test/SemaSYCL/no-vtables4.cpp b/clang/test/SemaSYCL/no-vtables4.cpp index 70905869565ff..3770c72a3ce46 100644 --- a/clang/test/SemaSYCL/no-vtables4.cpp +++ b/clang/test/SemaSYCL/no-vtables4.cpp @@ -4,7 +4,7 @@ struct Base { virtual void f() const {} }; -// expected-error@+1{{No class with a vtable can be used in a SYCL kernel or any code included in the kernel}} +// expected-error@+1{{SYCL kernel cannot have a class with a virtual function table}} struct Inherit : Base { virtual void f() const override {} }; diff --git a/clang/test/SemaSYCL/sycl-restrict.cpp b/clang/test/SemaSYCL/sycl-restrict.cpp index 8589bf55bd4f2..39776307bbe1a 100644 --- a/clang/test/SemaSYCL/sycl-restrict.cpp +++ b/clang/test/SemaSYCL/sycl-restrict.cpp @@ -19,8 +19,7 @@ class Fraction }; bool operator==(const Fraction& lhs, const Fraction& rhs) { - // expected-error@+1 {{SYCL kernel cannot allocate storage}} - new int; + new int; // expected-error {{SYCL kernel cannot allocate storage}} return lhs.num() == rhs.num() && lhs.den() == rhs.den(); }} @@ -36,7 +35,7 @@ void restriction(int p) { void* operator new (std::size_t size, void* ptr) throw() { return ptr; }; namespace Check_RTTI_Restriction { -// expected-error@+1 5{{No class with a vtable can be used in a SYCL kernel or any code included in the kernel}} +// expected-error@+1 9{{SYCL kernel cannot have a class with a virtual function table}} struct A { virtual ~A(){}; }; @@ -48,8 +47,8 @@ struct B : public A { struct OverloadedNewDelete { // This overload allocates storage, give diagnostic. void *operator new(std::size_t size) throw() { - // expected-error@+1 {{SYCL kernel cannot allocate storage}} - float *pt = new float; + // expected-error@+1 {{SYCL kernel cannot allocate storage}} + float *pt = new float; return 0;} // This overload does not allocate: no diagnostic. void *operator new[](std::size_t size) throw() {return 0;} @@ -70,18 +69,18 @@ bool isa_B(A *a) { // expected-error@+1 {{SYCL kernel cannot use rtti}} (void)typeid(int); // expected-error@+2 {{SYCL kernel cannot use rtti}} - // expected-note@+1{{used here}} + // expected-note@+1 {{used here}} return dynamic_cast(a) != 0; } __attribute__((sycl_kernel)) void kernel1(void) { - // expected-note@+1{{used here}} + // expected-note@+1 {{used here}} A *a; // expected-note@+1 3{{used here}} isa_B(a); } } -// expected-error@+1 {{No class with a vtable can be used in a SYCL kernel or any code included in the kernel}} +// expected-error@+1 {{SYCL kernel cannot have a class with a virtual function table}} typedef struct Base { virtual void f() const {} } b_type; @@ -118,7 +117,6 @@ void eh_not_ok(void) // expected-error@+1 {{SYCL kernel cannot use exceptions}} try { ; - // expected-error@+1 {{SYCL kernel cannot use exceptions}} } catch (...) { ; } @@ -136,10 +134,10 @@ void usage( myFuncDef functionPtr ) { // expected-error@+2 {{SYCL kernel cannot call through a function pointer}} #endif if ((*functionPtr)(1,2)) - // expected-note@+3{{used here}} - // expected-error@+2 {{SYCL kernel cannot use a global variable}} - // expected-error@+1 {{SYCL kernel cannot call a virtual function}} - b.f(); + // expected-error@+3 {{SYCL kernel cannot use a global variable}} + // expected-error@+2 {{SYCL kernel cannot call a virtual function}} + // expected-note@+1 {{used here}} + b.f(); Check_RTTI_Restriction::kernel1(); } @@ -153,6 +151,10 @@ extern "C++" { } } +int addInt(int n, int m) { + return n+m; +} + int use2 ( a_type ab, a_type *abp ) { if (ab.constexpr_stat_member) return 2; @@ -168,10 +170,15 @@ int use2 ( a_type ab, a_type *abp ) { return ns::glob + // expected-error@+1 {{SYCL kernel cannot use a global variable}} AnotherNS::moar_globals; -} - -int addInt(int n, int m) { - return n+m; + // expected-note@+1 {{called by 'use2'}} + eh_not_ok(); + // expected-note@+1 {{used here}} + Check_RTTI_Restriction:: A *a; + // expected-note@+1 3{{used here}} + Check_RTTI_Restriction:: isa_B(a); + usage(&addInt); + Check_User_Operators::Fraction f1(3, 8), f2(1, 2), f3(10, 2); + if (f1 == f2) return false; } template @@ -179,6 +186,7 @@ __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); }