diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index e795947add373..1c07c91e7dbb7 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -236,6 +236,10 @@ static void checkSYCLVarType(Sema &S, QualType Ty, SourceRange Loc, emitDeferredDiagnosticAndNote(S, Loc, diag::err_typecheck_zero_array_size, UsedAtLoc); + // variable length arrays + if (Ty->isVariableArrayType()) + emitDeferredDiagnosticAndNote(S, Loc, diag::err_vla_unsupported, UsedAtLoc); + // Sub-reference array or pointer, then proceed with that type. while (Ty->isAnyPointerType() || Ty->isArrayType()) Ty = QualType{Ty->getPointeeOrArrayElementType(), 0}; @@ -284,9 +288,6 @@ class MarkDeviceFunction : public RecursiveASTVisitor { : RecursiveASTVisitor(), SemaRef(S) {} bool VisitCallExpr(CallExpr *e) { - for (const auto &Arg : e->arguments()) - CheckSYCLType(Arg->getType(), Arg->getSourceRange()); - if (FunctionDecl *Callee = e->getDirectCallee()) { Callee = Callee->getCanonicalDecl(); assert(Callee && "Device function canonical decl must be available"); @@ -308,8 +309,6 @@ class MarkDeviceFunction : public RecursiveASTVisitor { SemaRef.Diag(e->getExprLoc(), diag::err_sycl_restrict) << Sema::KernelCallVirtualFunction; - CheckSYCLType(Callee->getReturnType(), Callee->getSourceRange()); - if (auto const *FD = dyn_cast(Callee)) { // FIXME: We need check all target specified attributes for error if // that function with attribute can not be called from sycl kernel. The @@ -338,12 +337,6 @@ class MarkDeviceFunction : public RecursiveASTVisitor { return true; } - bool VisitCXXConstructExpr(CXXConstructExpr *E) { - for (const auto &Arg : E->arguments()) - CheckSYCLType(Arg->getType(), Arg->getSourceRange()); - return true; - } - bool VisitCXXTypeidExpr(CXXTypeidExpr *E) { SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) << Sema::KernelRTTI; return true; @@ -354,35 +347,6 @@ class MarkDeviceFunction : public RecursiveASTVisitor { return true; } - bool VisitTypedefNameDecl(TypedefNameDecl *TD) { - CheckSYCLType(TD->getUnderlyingType(), TD->getLocation()); - return true; - } - - bool VisitRecordDecl(RecordDecl *RD) { - CheckSYCLType(QualType{RD->getTypeForDecl(), 0}, RD->getLocation()); - return true; - } - - bool VisitParmVarDecl(VarDecl *VD) { - CheckSYCLType(VD->getType(), VD->getLocation()); - return true; - } - - bool VisitVarDecl(VarDecl *VD) { - CheckSYCLType(VD->getType(), VD->getLocation()); - return true; - } - - bool VisitDeclRefExpr(DeclRefExpr *E) { - Decl *D = E->getDecl(); - if (SemaRef.isKnownGoodSYCLDecl(D)) - return true; - - CheckSYCLType(E->getType(), E->getSourceRange()); - return true; - } - // The call graph for this translation unit. CallGraph SYCLCG; // The set of functions called by a kernel function. @@ -506,64 +470,6 @@ class MarkDeviceFunction : public RecursiveASTVisitor { } private: - bool CheckSYCLType(QualType Ty, SourceRange Loc) { - llvm::DenseSet visited; - return CheckSYCLType(Ty, Loc, visited); - } - - bool CheckSYCLType(QualType Ty, SourceRange Loc, - llvm::DenseSet &Visited) { - if (Ty->isVariableArrayType()) { - SemaRef.Diag(Loc.getBegin(), diag::err_vla_unsupported); - return false; - } - - while (Ty->isAnyPointerType() || Ty->isArrayType()) - Ty = QualType{Ty->getPointeeOrArrayElementType(), 0}; - - // Pointers complicate recursion. Add this type to Visited. - // If already there, bail out. - if (!Visited.insert(Ty).second) - return true; - - if (const auto *ATy = dyn_cast(Ty)) - return CheckSYCLType(ATy->getModifiedType(), Loc, Visited); - - if (const auto *CRD = Ty->getAsCXXRecordDecl()) { - // If the class is a forward declaration - skip it, because otherwise we - // would query property of class with no definition, which results in - // clang crash. - if (!CRD->hasDefinition()) - return true; - - for (const auto &Field : CRD->fields()) { - if (!CheckSYCLType(Field->getType(), Field->getSourceRange(), - Visited)) { - if (SemaRef.getLangOpts().SYCLIsDevice) - SemaRef.Diag(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)) { - if (SemaRef.getLangOpts().SYCLIsDevice) - SemaRef.Diag(Loc.getBegin(), diag::note_sycl_used_here); - return false; - } - } - } else if (const auto *FPTy = dyn_cast(Ty)) { - for (const auto &ParamTy : FPTy->param_types()) - if (!CheckSYCLType(ParamTy, Loc, Visited)) - return false; - return CheckSYCLType(FPTy->getReturnType(), Loc, Visited); - } else if (const auto *FTy = dyn_cast(Ty)) { - return CheckSYCLType(FTy->getReturnType(), Loc, Visited); - } - return true; - } - Sema &SemaRef; }; diff --git a/clang/test/SemaSYCL/sycl-restrict.cpp b/clang/test/SemaSYCL/sycl-restrict.cpp index 097baf742403f..ba946097be9da 100644 --- a/clang/test/SemaSYCL/sycl-restrict.cpp +++ b/clang/test/SemaSYCL/sycl-restrict.cpp @@ -36,7 +36,16 @@ void no_restriction(int p) { int index[p + 2]; } void restriction(int p) { - int index[p + 2]; // expected-error {{variable length arrays are not supported for the current target}} + // This particular violation is nested under two kernels with intermediate function calls. + // e.g. main -> 1stkernel -> usage -> 2ndkernel -> isa_B -> restriction -> !! + // Because the error is in two different kernels, we are given helpful notes for the origination of the error, twice. + // expected-note@#call_usage {{called by 'operator()'}} + // expected-note@#call_kernelFunc {{called by 'kernel_single_task __attribute__((sycl_kernel)) void kernel1(L l) { - l(); // expected-note 6{{called by 'kernel1([]() { // expected-note 3{{called by 'usage'}} + Check_RTTI_Restriction::kernel1([]() { //#call_rtti_kernel // expected-note 3{{called by 'usage'}} Check_RTTI_Restriction::A *a; - Check_RTTI_Restriction::isa_B(a); // expected-note 6{{called by 'operator()'}} + Check_RTTI_Restriction::isa_B(a); //#call_isa_B // expected-note 6{{called by 'operator()'}} }); // ======= Float128 Not Allowed in Kernel ========== @@ -323,7 +332,7 @@ int use2(a_type ab, a_type *abp) { template __attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) { - kernelFunc(); // expected-note 7{{called by 'kernel_single_task([=]() { - usage(&addInt); // expected-note 5{{called by 'operator()'}} + usage(&addInt); //#call_usage // expected-note 5{{called by 'operator()'}} a_type *p; use2(ab, p); // expected-note 2{{called by 'operator()'}} });