Skip to content

Commit a156fed

Browse files
authored
Fix crash in CanConvert from incomplete type (#8110)
A crash could be triggered in IsHLSLCopyableAnnotatableRecord when checking whether an explicit cast would be allowed for diagnostics, when adding function overload candidates with an incomplete target param type, and the source type is a basic type that supports splat to record type. Fixed by attempting to complete the type in CanConvert before calling IsHLSLNumericOrAggregateOfNumericType (which calls IsHLSLCopyableAnnotatableRecord). If it fails to complete, it will harmlessly skip this case.
1 parent 317e2f1 commit a156fed

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

tools/clang/lib/Sema/SemaHLSL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10133,6 +10133,7 @@ bool HLSLExternalSource::CanConvert(SourceLocation loc, Expr *sourceExpr,
1013310133
// We can only splat to target types that do not contain object/resource
1013410134
// types
1013510135
if (sourceSingleElementBuiltinType != nullptr &&
10136+
!m_sema->RequireCompleteType(loc, target, 0) &&
1013610137
hlsl::IsHLSLNumericOrAggregateOfNumericType(target)) {
1013710138
BuiltinType::Kind kind = sourceSingleElementBuiltinType->getKind();
1013810139
switch (kind) {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// RUN: %dxc -T vs_6_0 -E main %s | FileCheck %s
2+
3+
// CHECK: %[[IN:[^ ]+]] = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
4+
// CHECK: call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %[[IN]])
5+
6+
template<typename T> struct Wrapper;
7+
float get(float x) { return x;}
8+
float get(Wrapper<float> o);
9+
10+
template<typename T> struct Wrapper2;
11+
float get(Wrapper2<float> o);
12+
13+
template<typename T>
14+
struct Wrapper {
15+
T value;
16+
void set(float x) {
17+
// Incomplete target in CanConvert triggered during check whether explicit
18+
// cast would be allowed for converting to overload candidate 'float
19+
// get(Wrapper<float>)'. CanConvert would check spat potential when
20+
// explicit and source is a basic numeric type. This would cause crash in
21+
// IsHLSLCopyableAnnotatableRecord from the incomplete type.
22+
// Here, we can complete the type: Wrapper<float>, but not Wrapper2<float>
23+
value = get(x);
24+
}
25+
};
26+
27+
float get(Wrapper<float> o) { return o.value; }
28+
29+
template<typename T>
30+
struct Wrapper2 : Wrapper<T> {
31+
};
32+
33+
float get(Wrapper2<float> o) { return o.value; }
34+
35+
float main(float x : IN) : OUT {
36+
Wrapper2<float> w;
37+
w.set(x);
38+
return get(w);
39+
}

0 commit comments

Comments
 (0)