Closed aleino-nv closed 2 days ago
This came up as part of https://github.com/shader-slang/slang/issues/4807 because WGSL doesn't allow these kinds of type mismatches, and doesn't try to do any implicit conversions.
https://www.w3.org/TR/WGSL/#switch-statement says:
Type rule precondition: For a single switch statement, the selector expression and all case selector expressions must be of the same concrete integer scalar type.
This issue was actually a TODO in the code:
void SemanticsStmtVisitor::visitCaseStmt(CaseStmt* stmt)
{
auto expr = CheckExpr(stmt->expr);
// coerce to type being switch on, and ensure that value is a compile-time constant
// The Vals in the AST are pointer-unique, making them easy to check for duplicates
// by addeing them to a HashSet.
auto exprVal = tryConstantFoldExpr(expr, ConstantFoldingKind::CompileTime, nullptr);
auto switchStmt = FindOuterStmt<SwitchStmt>();
if (!switchStmt)
{
getSink()->diagnose(stmt, Diagnostics::caseOutsideSwitch);
}
else
{
// TODO: need to do some basic matching to ensure the type
// for the `case` is consistent with the type for the `switch`...
}
stmt->expr = expr;
stmt->exprVal = exprVal;
stmt->parentStmt = switchStmt;
}
As we found out when merging the initial WGSL commit the front-end fix worked, but will first require a fix in Falcor.
Blocking Falcor issue to do the fix https://github.com/NVIDIAGameWorks/Falcor/issues/449
Let's fork Falcor to shader-slang/
and use it for CI testing.
Then we can fix the error in our fork of Falcor to unblock this change.
This is done.
What is Slang's semantics when the type of the case expression doesn't match the type in the switch init expression? Example:
The GLSL specification says:
In GLSL this means
-1
will be treated likecase bitcast<uint>(int(-1))
which meanswrap<uint>(int(-1))
in two's complement representation.Based on GLSL and HLSL output, it seems Slang's de facto semantics is
case bitcast<uint>(int(-1))
:case -1
and as mentioned the GLSL spec reads this ascase bitcast<uint>(int(-1))
case int(-1)
, and I believe the DXC compiler ends up turning this intocase bitcast<uint>(int(-1))
.Can someone confirm?