Skip to content

Commit cadd309

Browse files
committed
disallow splatting things with bitvectors, add tests to show casting bitvectors not allowed. At test showing splatting union is not allowed. At test showing splatting union in elementwise cast is not allowed.
1 parent 848315d commit cadd309

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2771,7 +2771,7 @@ bool SemaHLSL::CanPerformScalarCast(QualType SrcTy, QualType DestTy) {
27712771
}
27722772

27732773
// Detect if a type contains a bitfield. Will be removed when
2774-
// bitfield support is added to HLSLElementwiseCast
2774+
// bitfield support is added to HLSLElementwiseCast and HLSLSplatCast
27752775
bool SemaHLSL::ContainsBitField(QualType BaseTy) {
27762776
llvm::SmallVector<QualType, 16> WorkList;
27772777
WorkList.push_back(BaseTy);
@@ -2822,11 +2822,16 @@ bool SemaHLSL::CanPerformSplatCast(Expr *Src, QualType DestTy) {
28222822
if (SrcVecTy)
28232823
SrcTy = SrcVecTy->getElementType();
28242824

2825+
if (ContainsBitField(DestTy))
2826+
return false;
2827+
28252828
llvm::SmallVector<QualType> DestTypes;
28262829
BuildFlattenedTypeList(DestTy, DestTypes);
28272830

2828-
for (unsigned i = 0; i < DestTypes.size(); i++) {
2829-
if (!CanPerformScalarCast(SrcTy, DestTypes[i]))
2831+
for (unsigned I = 0, Size = DestTypes.size(); I < Size; I++) {
2832+
if (DestTypes[I]->isUnionType())
2833+
return false;
2834+
if (!CanPerformScalarCast(SrcTy, DestTypes[I]))
28302835
return false;
28312836
}
28322837
return true;

clang/test/SemaHLSL/Language/ElementwiseCast-errors.hlsl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,23 @@ export void cantCast3() {
2727
S s = (S)C;
2828
// expected-error@-1 {{no matching conversion for C-style cast from 'int2' (aka 'vector<int, 2>') to 'S'}}
2929
}
30+
31+
struct R {
32+
// expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int2' (aka 'vector<int, 2>') to 'const R' for 1st argument}}
33+
// expected-note@-2 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int2' (aka 'vector<int, 2>') to 'R' for 1st argument}}
34+
// expected-note@-3 {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
35+
int A;
36+
union {
37+
float F;
38+
int4 G;
39+
};
40+
};
41+
42+
export void cantCast4() {
43+
int2 A = {1,2};
44+
R r = R(A);
45+
// expected-error@-1 {{no matching conversion for functional-style cast from 'int2' (aka 'vector<int, 2>') to 'R'}}
46+
R r2 = {1, 2};
47+
int2 B = (int2)r2;
48+
// expected-error@-1 {{cannot convert 'R' to 'int2' (aka 'vector<int, 2>') without a conversion operator}}
49+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -verify
2+
3+
struct S {
4+
// expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const S' for 1st argument}}
5+
// expected-note@-2 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'S' for 1st argument}}
6+
// expected-note@-3 {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
7+
int A : 8;
8+
int B;
9+
};
10+
11+
struct R {
12+
// expected-note@-1 {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const R' for 1st argument}}
13+
// expected-note@-2 {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'R' for 1st argument}}
14+
// expected-note@-3 {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
15+
int A;
16+
union {
17+
float F;
18+
int4 G;
19+
};
20+
};
21+
22+
// casting types which contain bitfields is not yet supported.
23+
export void cantCast() {
24+
S s = (S)1;
25+
// expected-error@-1 {{no matching conversion for C-style cast from 'int' to 'S'}}
26+
}
27+
28+
// Can't cast a union
29+
export void cantCast2() {
30+
R r = (R)1;
31+
// expected-error@-1 {{no matching conversion for C-style cast from 'int' to 'R'}}
32+
}

0 commit comments

Comments
 (0)