Skip to content

Commit 2fe9714

Browse files
[SPIR-V] Correctly handle subscript overload in access chain (microsoft#5896)
In order to handle types such as `RWStructuredBuffer`, which has the method `operator[]()`, `operator[]` is treated as a special case by our access chain creation code - it's treated similarly to `ArraySubscriptExpr`. This has the unfortunate side effect that user-defined `operator[]` overloads are not called in all cases. To fix this, this PR adds a check for whether a type is user-defined before handling `operator[]` in `collectArrayStructIndices`. Part of the fix for microsoft#5638.
1 parent a217ac7 commit 2fe9714

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7987,6 +7987,12 @@ const Expr *SpirvEmitter::collectArrayStructIndices(
79877987
indexing->getArg(0)->IgnoreParenNoopCasts(astContext);
79887988

79897989
const auto thisBaseType = thisBase->getType();
7990+
7991+
// If the base type is user defined, return the call expr so that any
7992+
// user-defined overloads of operator[] are called.
7993+
if (hlsl::IsUserDefinedRecordType(thisBaseType))
7994+
return expr;
7995+
79907996
const Expr *base = collectArrayStructIndices(
79917997
thisBase, rawIndex, rawIndices, indices, isMSOutAttribute);
79927998

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s
2+
3+
struct s
4+
{
5+
float field;
6+
};
7+
8+
struct subscriptable
9+
{
10+
s operator[](const uint64_t index)
11+
{
12+
return s(123.0);
13+
}
14+
};
15+
16+
float4 main() : SV_TARGET
17+
{
18+
subscriptable o;
19+
20+
float f;
21+
// CHECK: %param_var_index = OpVariable %_ptr_Function_ulong Function
22+
// CHECK: OpStore %param_var_index %ulong_123
23+
// CHECK: [[op_result:%[0-9]+]] = OpFunctionCall %s %subscriptable_operator_Subscript %o %param_var_index
24+
// CHECK: OpStore %temp_var_s [[op_result]]
25+
// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_float %temp_var_s %int_0
26+
f = o[123].field;
27+
return f;
28+
}

0 commit comments

Comments
 (0)