Skip to content

Commit 0c220ca

Browse files
authored
[SYCL] Do not crash on attempt to visit invalid decl (#2411)
1 parent 58eea55 commit 0c220ca

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2481,6 +2481,10 @@ void Sema::CheckSYCLKernelCall(FunctionDecl *KernelFunc, SourceRange CallLoc,
24812481
Diag(KernelFunc->getLocation(), diag::warn_sycl_pass_by_value_deprecated);
24822482
}
24832483

2484+
// Do not visit invalid kernel object.
2485+
if (KernelObj->isInvalidDecl())
2486+
return;
2487+
24842488
KernelObjVisitor Visitor{*this};
24852489
DiagnosingSYCLKernel = true;
24862490
Visitor.VisitRecordBases(KernelObj, FieldChecker, UnionChecker,
@@ -2520,6 +2524,10 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
25202524
const CXXRecordDecl *KernelObj = getKernelObjectType(KernelCallerFunc);
25212525
assert(KernelObj && "invalid kernel caller");
25222526

2527+
// Do not visit invalid kernel object.
2528+
if (KernelObj->isInvalidDecl())
2529+
return;
2530+
25232531
// Calculate both names, since Integration headers need both.
25242532
std::string CalculatedName, StableName;
25252533
std::tie(CalculatedName, StableName) =
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// RUN: %clang_cc1 -I %S/Inputs -fsycl -fsycl-is-device -fsyntax-only -Wno-sycl-2017-compat -verify %s
2+
3+
// This test checks that compiler doesn't crash if type of kernel argument is
4+
// invalid.
5+
6+
#include <sycl.hpp>
7+
8+
// Invalid field -> invalid decl
9+
class A {
10+
public:
11+
// expected-error@+1 {{unknown type name 'it'}}
12+
it KN;
13+
};
14+
15+
// Invalid type of field -> invalid decl
16+
class B {
17+
A Arr[100];
18+
};
19+
20+
// Invalid base -> invalid decl
21+
class E : public B {
22+
};
23+
24+
// expected-note@+1 {{forward declaration of 'C'}}
25+
class C;
26+
27+
// Invalid base -> invalid decl
28+
// expected-error@+1 {{base class has incomplete type}}
29+
class D : public B, C {
30+
};
31+
32+
// Such thing is also invalid and caused crash
33+
// expected-note@+1 {{definition of 'F' is not complete until the closing '}'}}
34+
class F {
35+
// expected-error@+1 {{field has incomplete type 'F'}}
36+
F Self;
37+
};
38+
39+
template <typename T>
40+
class G {
41+
T Field;
42+
};
43+
44+
class H {
45+
// expected-note@+1 {{previous declaration is here}}
46+
int A;
47+
// expected-error@+1 {{duplicate member 'A'}}
48+
int A;
49+
};
50+
51+
int main() {
52+
A Obj{};
53+
D Obj1{};
54+
B Obj2{};
55+
E Obj3{};
56+
F Obj4{};
57+
G<A> Obj5{};
58+
H Obj6{};
59+
cl::sycl::kernel_single_task<class kernel>(
60+
[=]() {
61+
(void)Obj;
62+
(void)Obj1;
63+
(void)Obj2;
64+
(void)Obj3;
65+
(void)Obj4;
66+
(void)Obj5;
67+
(void)Obj6;
68+
});
69+
return 0;
70+
}

0 commit comments

Comments
 (0)