Skip to content

Commit 2232fcb

Browse files
LegNeatoFirestar99
authored andcommitted
Do not ICE on indirect fn pointers
Fixes #452.
1 parent 808974a commit 2232fcb

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

crates/rustc_codegen_spirv/src/linker/simple_passes.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,18 @@ pub fn check_fragment_insts(sess: &Session, module: &Module) -> super::Result<()
237237
let mut any_err = None;
238238
for inst in module.functions[index].all_inst_iter() {
239239
if inst.class.opcode == Op::FunctionCall {
240-
let callee = func_id_to_idx[&inst.operands[0].unwrap_id_ref()];
241-
let callee_had_err =
242-
visit(sess, module, visited, stack, names, callee, func_id_to_idx).err();
243-
any_err = any_err.or(callee_had_err);
240+
let callee_id = inst.operands[0].unwrap_id_ref();
241+
if let Some(&callee) = func_id_to_idx.get(&callee_id) {
242+
if let Err(e) =
243+
visit(sess, module, visited, stack, names, callee, func_id_to_idx)
244+
{
245+
any_err = any_err.or(Some(e));
246+
}
247+
} else {
248+
// Indirect or external callee: nothing to traverse.
249+
// Keep scanning this function for forbidden fragment ops.
250+
continue;
251+
}
244252
}
245253
if matches!(
246254
inst.class.opcode,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// build-fail
2+
3+
use spirv_std::spirv;
4+
5+
#[derive(Clone, Copy)]
6+
struct Position(u32);
7+
8+
fn use_cmp(cmp: fn(&Position) -> u32) {
9+
let a = Position(0);
10+
let b = Position(1);
11+
12+
let _ = if cmp(&a) <= cmp(&b) { a } else { b };
13+
}
14+
15+
#[spirv(compute(threads(1)))]
16+
pub fn main() {
17+
use_cmp(|p| p.0);
18+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
error: function pointer types are not allowed
2+
--> $DIR/issue-452.rs:8:1
3+
|
4+
LL | fn use_cmp(cmp: fn(&Position) -> u32) {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: used by unnamed global (%10)
8+
note: used from within `issue_452::use_cmp`
9+
--> $DIR/issue-452.rs:8:4
10+
|
11+
LL | fn use_cmp(cmp: fn(&Position) -> u32) {
12+
| ^^^^^^^
13+
note: called by `issue_452::main`
14+
--> $DIR/issue-452.rs:17:5
15+
|
16+
LL | use_cmp(|p| p.0);
17+
| ^^^^^^^^^^^^^^^^
18+
note: called by `main`
19+
--> $DIR/issue-452.rs:16:8
20+
|
21+
LL | pub fn main() {
22+
| ^^^^
23+
24+
error: indirect calls are not supported in SPIR-V
25+
--> $DIR/issue-452.rs:12:27
26+
|
27+
LL | let _ = if cmp(&a) <= cmp(&b) { a } else { b };
28+
| ^^^^^^^
29+
|
30+
note: used from within `issue_452::use_cmp`
31+
--> $DIR/issue-452.rs:8:4
32+
|
33+
LL | fn use_cmp(cmp: fn(&Position) -> u32) {
34+
| ^^^^^^^
35+
note: called by `issue_452::main`
36+
--> $DIR/issue-452.rs:17:5
37+
|
38+
LL | use_cmp(|p| p.0);
39+
| ^^^^^^^^^^^^^^^^
40+
note: called by `main`
41+
--> $DIR/issue-452.rs:16:8
42+
|
43+
LL | pub fn main() {
44+
| ^^^^
45+
46+
error: aborting due to 2 previous errors
47+

0 commit comments

Comments
 (0)