Skip to content

Commit 5a735a2

Browse files
authored
[HLSL][Sema] Fixed Diagnostics that assumed only two arguments (#122772)
In the below code B varies over the arg list via a loop. However, the diagnostics do not vary with the loop. Fix so that diagnostics can vary with B.
1 parent ce6e66d commit 5a735a2

File tree

2 files changed

+57
-15
lines changed

2 files changed

+57
-15
lines changed

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,13 +1688,21 @@ static bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) {
16881688
auto *VecTyA = ArgTyA->getAs<VectorType>();
16891689
SourceLocation BuiltinLoc = TheCall->getBeginLoc();
16901690

1691+
bool AllBArgAreVectors = true;
16911692
for (unsigned i = 1; i < TheCall->getNumArgs(); ++i) {
16921693
ExprResult B = TheCall->getArg(i);
16931694
QualType ArgTyB = B.get()->getType();
16941695
auto *VecTyB = ArgTyB->getAs<VectorType>();
1695-
if (VecTyA == nullptr && VecTyB == nullptr)
1696-
return false;
1697-
1696+
if (VecTyB == nullptr)
1697+
AllBArgAreVectors &= false;
1698+
if (VecTyA && VecTyB == nullptr) {
1699+
// Note: if we get here 'B' is scalar which
1700+
// requires a VectorSplat on ArgN
1701+
S->Diag(BuiltinLoc, diag::err_vec_builtin_non_vector)
1702+
<< TheCall->getDirectCallee() << /*useAllTerminology*/ true
1703+
<< SourceRange(A.get()->getBeginLoc(), B.get()->getEndLoc());
1704+
return true;
1705+
}
16981706
if (VecTyA && VecTyB) {
16991707
bool retValue = false;
17001708
if (VecTyA->getElementType() != VecTyB->getElementType()) {
@@ -1712,21 +1720,23 @@ static bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) {
17121720
// HLSLVectorTruncation.
17131721
S->Diag(BuiltinLoc, diag::err_vec_builtin_incompatible_vector)
17141722
<< TheCall->getDirectCallee() << /*useAllTerminology*/ true
1715-
<< SourceRange(TheCall->getArg(0)->getBeginLoc(),
1716-
TheCall->getArg(1)->getEndLoc());
1723+
<< SourceRange(A.get()->getBeginLoc(), B.get()->getEndLoc());
17171724
retValue = true;
17181725
}
1719-
return retValue;
1726+
if (retValue)
1727+
return retValue;
17201728
}
17211729
}
17221730

1723-
// Note: if we get here one of the args is a scalar which
1724-
// requires a VectorSplat on Arg0 or Arg1
1725-
S->Diag(BuiltinLoc, diag::err_vec_builtin_non_vector)
1726-
<< TheCall->getDirectCallee() << /*useAllTerminology*/ true
1727-
<< SourceRange(TheCall->getArg(0)->getBeginLoc(),
1728-
TheCall->getArg(1)->getEndLoc());
1729-
return true;
1731+
if (VecTyA == nullptr && AllBArgAreVectors) {
1732+
// Note: if we get here 'A' is a scalar which
1733+
// requires a VectorSplat on Arg0
1734+
S->Diag(BuiltinLoc, diag::err_vec_builtin_non_vector)
1735+
<< TheCall->getDirectCallee() << /*useAllTerminology*/ true
1736+
<< SourceRange(A.get()->getBeginLoc(), A.get()->getEndLoc());
1737+
return true;
1738+
}
1739+
return false;
17301740
}
17311741

17321742
static bool CheckArgTypeMatches(Sema *S, Expr *Arg, QualType ExpectedType) {

clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,38 @@ float2 test_lerp_no_second_arg(float2 p0) {
2020
// expected-error@-1 {{no matching function for call to 'lerp'}}
2121
}
2222

23-
float2 test_lerp_vector_size_mismatch(float3 p0, float2 p1) {
23+
float2 test_lerp_vector_trunc_warn1(float3 p0) {
24+
return lerp(p0, p0, p0);
25+
// expected-warning@-1 {{implicit conversion truncates vector: 'float3' (aka 'vector<float, 3>') to 'vector<float, 2>' (vector of 2 'float' values)}}
26+
}
27+
28+
float2 test_lerp_vector_trunc_warn2(float3 p0, float2 p1) {
2429
return lerp(p0, p0, p1);
2530
// expected-warning@-1 {{implicit conversion truncates vector: 'float3' (aka 'vector<float, 3>') to 'vector<float, 2>' (vector of 2 'float' values)}}
31+
// expected-warning@-2 {{implicit conversion truncates vector: 'float3' (aka 'vector<float, 3>') to 'vector<float, 2>' (vector of 2 'float' values)}}
32+
}
33+
34+
float2 test_lerp_vector_trunc_warn3(float3 p0, float2 p1) {
35+
return lerp(p0, p1, p0);
36+
// expected-warning@-1 {{implicit conversion truncates vector: 'float3' (aka 'vector<float, 3>') to 'vector<float, 2>' (vector of 2 'float' values)}}
37+
// expected-warning@-2 {{implicit conversion truncates vector: 'float3' (aka 'vector<float, 3>') to 'vector<float, 2>' (vector of 2 'float' values)}}
2638
}
2739

28-
float2 test_lerp_builtin_vector_size_mismatch(float3 p0, float2 p1) {
40+
float2 test_lerp_builtin_vector_size_mismatch_Arg1(float3 p0, float2 p1) {
2941
return __builtin_hlsl_lerp(p0, p1, p1);
3042
// expected-error@-1 {{all arguments to '__builtin_hlsl_lerp' must have the same type}}
3143
}
3244

45+
float2 test_lerp_builtin_vector_size_mismatch_Arg2(float3 p0, float2 p1) {
46+
return __builtin_hlsl_lerp(p1, p0, p1);
47+
// expected-error@-1 {{all arguments to '__builtin_hlsl_lerp' must have the same type}}
48+
}
49+
50+
float2 test_lerp_builtin_vector_size_mismatch_Arg3(float3 p0, float2 p1) {
51+
return __builtin_hlsl_lerp(p1, p1, p0);
52+
// expected-error@-1 {{all arguments to '__builtin_hlsl_lerp' must have the same type}}
53+
}
54+
3355
float test_lerp_scalar_mismatch(float p0, half p1) {
3456
return lerp(p1, p0, p1);
3557
// expected-error@-1 {{call to 'lerp' is ambiguous}}
@@ -45,6 +67,16 @@ float2 test_builtin_lerp_float2_splat(float p0, float2 p1) {
4567
// expected-error@-1 {{all arguments to '__builtin_hlsl_lerp' must be vectors}}
4668
}
4769

70+
float2 test_builtin_lerp_float2_splat2(double p0, double2 p1) {
71+
return __builtin_hlsl_lerp(p1, p0, p1);
72+
// expected-error@-1 {{all arguments to '__builtin_hlsl_lerp' must be vectors}}
73+
}
74+
75+
float2 test_builtin_lerp_float2_splat3(double p0, double2 p1) {
76+
return __builtin_hlsl_lerp(p1, p1, p0);
77+
// expected-error@-1 {{all arguments to '__builtin_hlsl_lerp' must be vectors}}
78+
}
79+
4880
float3 test_builtin_lerp_float3_splat(float p0, float3 p1) {
4981
return __builtin_hlsl_lerp(p0, p1, p1);
5082
// expected-error@-1 {{all arguments to '__builtin_hlsl_lerp' must be vectors}}

0 commit comments

Comments
 (0)