Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6a61f36
[SYCL] add clang diagnostic for illegal data types of kernel free fun…
dklochkov-emb Jun 30, 2025
54d198e
[SYCL] fix syntax
dklochkov-emb Jul 1, 2025
778314d
Merge branch 'sycl' into sycl-free-function-illegal-types
dklochkov-emb Jul 1, 2025
e57c90c
[SYCL] do not emit diagnostics if class with virtual method is used a…
dklochkov-emb Jul 10, 2025
e4036ad
[SYCL] fix formatting
dklochkov-emb Jul 10, 2025
dedadc1
[SYCL] remove unnecessary change
dklochkov-emb Jul 10, 2025
d9c209d
[SYCL][E2E] do not save integration header
dklochkov-emb Jul 10, 2025
208e1a8
[SYCL] do not serialize string number into integer if mangled name is…
dklochkov-emb Jul 11, 2025
a96965e
Merge remote-tracking branch 'upstream/sycl' into sycl-free-function-…
dklochkov-emb Jul 14, 2025
18a7adb
[SYCL] use visitor infrastructure to emit clang diagnostics
dklochkov-emb Jul 15, 2025
bc1ae10
Merge remote-tracking branch 'upstream/sycl' into sycl-free-function-…
dklochkov-emb Jul 15, 2025
61e3b45
[SYCL][E2E] remove redudant const
dklochkov-emb Jul 16, 2025
bf79a78
Merge remote-tracking branch 'upstream/sycl' into sycl-free-function-…
dklochkov-emb Jul 16, 2025
a33a06a
[SYCL] use SyclKernelFieldChecker to check for virtual inheritance
dklochkov-emb Aug 19, 2025
7cdd945
Merge remote-tracking branch 'upstream/sycl' into sycl-free-function-…
dklochkov-emb Aug 19, 2025
375485e
[SYCL] do not recurse withh on whole method
dklochkov-emb Aug 19, 2025
6f9ef69
[SYCL] use leaveStruct method to check on virtual inheritance
dklochkov-emb Aug 19, 2025
5722de2
[SYCL] fix formatting
dklochkov-emb Aug 19, 2025
c9f944c
[SYCL] fix coding style
dklochkov-emb Aug 19, 2025
9adf700
[SYCL] use checker constructor to pass free function location
dklochkov-emb Aug 19, 2025
1779409
[SYCL] update diagostic error name
dklochkov-emb Aug 19, 2025
df2523d
[SYCL] add new tests to check virtual inhertance
dklochkov-emb Aug 19, 2025
e2e229b
[SYCL] more tests
dklochkov-emb Aug 19, 2025
56e8997
[SYCL] fix empty line
dklochkov-emb Aug 20, 2025
b221357
Merge remote-tracking branch 'upstream/sycl' into sycl-free-function-…
dklochkov-emb Aug 20, 2025
361c0fa
[SYCL] remove unused variables and arguments
dklochkov-emb Aug 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -12969,6 +12969,8 @@ def err_free_function_first_occurrence_missing_attr: Error<
"the first occurrence of SYCL kernel free function should be declared with 'sycl-nd-range-kernel' or 'sycl-single-task-kernel' compile time properties">;
def err_free_function_class_method : Error<
"%select{static |}0class method cannot be used to define a SYCL kernel free function kernel">;
def err_free_function_virtual_arg : Error<
"argument type %0 of kernel free function can not %select{be virtually derived |have virtual methods}1">;


// SYCL kernel entry point diagnostics
Expand Down
39 changes: 39 additions & 0 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5849,6 +5849,43 @@ void SemaSYCL::MarkDevices() {
}
}

static bool hasVirtuals(Sema &S, ParmVarDecl *Param) {
const clang::CXXRecordDecl *ParamType =
Param->getType()->getAsCXXRecordDecl();
if (!ParamType || !ParamType->isThisDeclarationADefinition())
return false;

llvm::SmallVector<const clang::CXXRecordDecl *, 8> WorkList;
llvm::SmallPtrSet<const clang::CXXRecordDecl *, 8> Visited;
WorkList.push_back(ParamType);

while (!WorkList.empty()) {
const clang::CXXRecordDecl *Cur = WorkList.pop_back_val();
if (!Visited.insert(Cur).second)
continue;

// Check for virtual bases
for (const clang::CXXBaseSpecifier &Base : Cur->bases()) {
if (Base.isVirtual())
return S.Diag(Param->getLocation(), diag::err_free_function_virtual_arg)
<< ParamType->getNameAsString() << 0 << Param->getSourceRange();
const clang::CXXRecordDecl *BaseDecl =
Base.getType()->getAsCXXRecordDecl();
if (BaseDecl && BaseDecl->isThisDeclarationADefinition())
WorkList.push_back(BaseDecl);
}

// Check for virtual member functions
for (const auto *Method : Cur->methods()) {
if (Method->isVirtual()) {
return S.Diag(Param->getLocation(), diag::err_free_function_virtual_arg)
<< ParamType->getNameAsString() << 1 << Param->getSourceRange();
}
}
}
return false;
}

static bool CheckFreeFunctionDiagnostics(Sema &S, const FunctionDecl *FD) {
if (FD->isVariadic()) {
return S.Diag(FD->getLocation(), diag::err_free_function_variadic_args);
Expand All @@ -5871,6 +5908,8 @@ static bool CheckFreeFunctionDiagnostics(Sema &S, const FunctionDecl *FD) {
diag::err_free_function_with_default_arg)
<< Param->getSourceRange();
}
if (hasVirtuals(S, Param))
return true;
}
return false;
}
Expand Down
78 changes: 78 additions & 0 deletions clang/test/SemaSYCL/free_function_negative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,81 @@ static void StaticsingleTaskKernelMethod(int Value) {
}

};

class Base {};
class Derived : virtual public Base {};

// expected-error@+2 {{argument type Derived of kernel free function can not be virtually derived}}
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]]
void VirtualInheritArg(Derived Value) {
}

// expected-error@+2 {{argument type Derived of kernel free function can not be virtually derived}}
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]]
void VirtualInheritArg1(int a, Derived Value, float b, Derived Value1) {
}

class Derived1 : public Derived {
};

// expected-error@+2 {{argument type Derived1 of kernel free function can not be virtually derived}}
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]]
void VirtualInheritArg2(Derived1 Value) {
}

class Base1 {};
class Derived2 : public Base1, public virtual Base {
};

// expected-error@+2 {{argument type Derived2 of kernel free function can not be virtually derived}}
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]]
void VirtualInheritArg3(Derived2 Value) {
}

struct Derived3 : virtual public Base {
};

// expected-error@+2 {{argument type Derived3 of kernel free function can not be virtually derived}}
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]]
void VirtualInheritArg4(Derived3 Value) {
}

class Class {
public:
virtual void virtualMethod() {}
};

// expected-error@+2 {{argument type Class of kernel free function can not have virtual methods}}
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]]
void VirtualMethodArg1(Class Value) {
}

class Class1: public Class {
public:
void NewMethod() {}
};

// expected-error@+2 {{argument type Class1 of kernel free function can not have virtual methods}}
[[__sycl_detail__::add_ir_attributes_function("sycl-single-task-kernel", 2)]]
void VirtualMethodArg2(Class1 Value) {
}

class Class2: Base1 {
public:
virtual void virtualMethod() {}
};

// expected-error@+2 {{argument type Class2 of kernel free function can not have virtual methods}}
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
void VirtualMethodArg2(Class2 Value) {
}

class Class3 {
public:
virtual ~Class3() {}
};

// expected-error@+2 {{argument type Class3 of kernel free function can not have virtual methods}}
[[__sycl_detail__::add_ir_attributes_function("sycl-nd-range-kernel", 2)]]
void VirtualMethodArg3(Class3 Value) {
}