diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/bugs/gh-4434.slang | 24 | ||||
| -rw-r--r-- | tests/bugs/gh-4441.slang | 24 | ||||
| -rw-r--r-- | tests/diagnostics/ctor-ordinary-retval-legal.slang | 3 | ||||
| -rw-r--r-- | tests/diagnostics/uninitialized-out.slang | 57 | ||||
| -rw-r--r-- | tests/diagnostics/uninitialized.slang | 263 |
5 files changed, 291 insertions, 80 deletions
diff --git a/tests/bugs/gh-4434.slang b/tests/bugs/gh-4434.slang index 975226008..c9a48d439 100644 --- a/tests/bugs/gh-4434.slang +++ b/tests/bugs/gh-4434.slang @@ -15,17 +15,19 @@ RWStructuredBuffer<uint> outputBuffer; [numthreads(4, 1, 1)] void computeMain(uint tid : SV_GroupIndex) { - bool a, b, c; - c = and(a, b); - - bool1 i, j, k; - bool2 l, m, n; - bool3 o, p, q; - bool4 r, s, t; - k = and(i, j); - n = and(m, l); - q = and(o, p); - t = and(r, s); + bool K = (bool)outputBuffer[tid]; + + bool c = and(K, K); + + bool1 K1 = K; + bool2 K2 = K; + bool3 K3 = K; + bool4 K4 = K; + + bool1 k = and(K, K); + bool2 n = and(K, K); + bool3 q = and(K, K); + bool4 t = and(K, K); k = !and(k, false); n = !and(n, false); diff --git a/tests/bugs/gh-4441.slang b/tests/bugs/gh-4441.slang index 59d577c8d..a2de7e00d 100644 --- a/tests/bugs/gh-4441.slang +++ b/tests/bugs/gh-4441.slang @@ -15,17 +15,19 @@ RWStructuredBuffer<uint> outputBuffer; [numthreads(4, 1, 1)] void computeMain(uint tid : SV_GroupIndex) { - bool a, b, c; - c = or(a, b); - - bool1 i, j, k; - bool2 l, m, n; - bool3 o, p, q; - bool4 r, s, t; - k = or(i, j); - n = or(m, l); - q = or(o, p); - t = or(r, s); + bool K = (bool)outputBuffer[tid]; + + bool c = or(K, K); + + bool1 K1 = K; + bool2 K2 = K; + bool3 K3 = K; + bool4 K4 = K; + + bool1 k = or(K, K); + bool2 n = or(K, K); + bool3 q = or(K, K); + bool4 t = or(K, K); k = or(k, true); n = or(n, true); diff --git a/tests/diagnostics/ctor-ordinary-retval-legal.slang b/tests/diagnostics/ctor-ordinary-retval-legal.slang index f2d1765ff..8117b4c80 100644 --- a/tests/diagnostics/ctor-ordinary-retval-legal.slang +++ b/tests/diagnostics/ctor-ordinary-retval-legal.slang @@ -11,7 +11,8 @@ struct S { - float v; + float v; + __init() { v = 0; } } struct S1a : S diff --git a/tests/diagnostics/uninitialized-out.slang b/tests/diagnostics/uninitialized-out.slang deleted file mode 100644 index d0d87449f..000000000 --- a/tests/diagnostics/uninitialized-out.slang +++ /dev/null @@ -1,57 +0,0 @@ -//DIAGNOSTIC_TEST:SIMPLE: - -float foo(out float3 v) -{ - // This should error as we haven't set v before we read from it - float r = v.x + 1.0; - // This should warn as we haven't set v before we return - return r; -} - -// This should warn as we return without x being initialized -float bar(out float x) -{ - return 0; -} - -// This should also warn pointing at the implicit return -void baz(out float x) {} - -void twoReturns(bool b, out float y) -{ - if(b) - { - // Should warn - return; - } - y = 0; - // Shouldn't warn - return; -} - -void twoOkReturns(bool b, out float y) -{ - if(b) - { - // Shouldn't warn - unused(y); - return; - } - y = 0; - // Shouldn't warn - return; -} - -// TODO: This should warn that n is potentially uninitialized -int ok(bool b, out int n) -{ - if(b) - n = 0; - return n; -} - -// TODO: This should warn that arr isn't fully initialized -void partial(out float arr[2]) -{ - arr[0] = 1; -} diff --git a/tests/diagnostics/uninitialized.slang b/tests/diagnostics/uninitialized.slang new file mode 100644 index 000000000..4779f45c9 --- /dev/null +++ b/tests/diagnostics/uninitialized.slang @@ -0,0 +1,263 @@ +//TEST:SIMPLE(filecheck=CHK): -target spirv + +// TODO: +// * warn potentially uninitialized variables (control flow) +// * warn partially uninitialized variables (structs, arrays, etc.) +// * warn uninitialized fields in constructors + +/////////////////////////////////// +// Uninitialized local variables // +/////////////////////////////////// + +// Should not warn here (unconditionalBranch) +float3 unconditional(int mode) +{ + float f(float) { return 1; } + + float k0; + float k1; + + if (mode == 1) + { + k1 = 1; + k0 = 1; + + const float w = k1 * f(1); + k0 = 4.0f * k0 * w; + k1 = 2.0f * k1 * w; + } + + return k0 + k1; +} + +// Warn here for branches using the variables +int conditional() +{ + int k; + //CHK-DAG: warning 41016: use of uninitialized variable 'k' + return (k > 0); +} + +// Using unitialized values +int use_undefined_value(int k) +{ + int x; + x += k; + //CHK-DAG: warning 41016: use of uninitialized variable 'x' + return x; +} + +// Returning uninitialized values +__generic<T> +T generic_undefined_return() +{ + T x; + //CHK-DAG: warning 41016: use of uninitialized variable 'x' + return x; +} + +// Array variables +float undefined_array() +{ + float array[2]; + //CHK-DAG: warning 41016: use of uninitialized variable 'array' + return array[0]; +} + +float filled_array(int mode) +{ + float array[2]; + array[0] = 1.0f; + return array[0]; +} + +// Structs and nested structs +struct Data +{ + float value; +}; + +struct NestedData +{ + Data data; +}; + +// No warnings here, even thought autodiff generates +// IR which frequently returns undefined values +struct DiffStruct : IDifferentiable +{ + Data data; + float x; +} + +// Same story here +[ForwardDifferentiable] +DiffStruct differentiable(float x) +{ + DiffStruct ds; + ds.x = x; + return ds; +} + +// Empty structures should not generate diagnostics +// for empty default constructors +struct EmptyStruct +{ + __init() {} +}; + +// No warnings for empty structs even without __init() +struct NonEmptyStruct +{ + int field; + + __init() + { + field = 1; + } +}; + +// No warnings even when __init() is not specified +struct NoDefault +{ + int f(int i) + { + return i; + } +}; + +// Constructing the above structs +int constructors() +{ + EmptyStruct empty; + NoDefault no_default; + return no_default.f(1); +} + +// Using struct fields and nested structs +float structs() +{ + Data inputData = Data(1.0); + + float undefVar; + Data undefData; + NestedData nestedData; + + float result = inputData.value; + + //CHK-DAG: warning 41016: use of uninitialized variable 'undefVar' + result += undefVar; + + //CHK-DAG: warning 41016: use of uninitialized variable 'undefData' + result += undefData.value; + + //CHK-DAG: warning 41016: use of uninitialized variable 'nestedData' + result += nestedData.data.value; + + return result; +} + +//////////////////////////////////// +// Uninitialized global variables // +//////////////////////////////////// + +// Using groupshared variables +groupshared float4 gsConstexpr = float4(1.0f); +groupshared float4 gsUndefined; + +// OK +float use_constexpr_initialized_gs() +{ + return gsConstexpr.x; +} + +float use_undefined_gs() +{ + //CHK-DAG: warning 41017: use of uninitialized global variable 'gsUndefined' + return gsUndefined.x; +} + +// Using static variables +static const float cexprInitialized = 1.0f; +static float writtenNever; +static float writtenLater; + +// OK +float use_initialized_static() +{ + return cexprInitialized; +} + +// Should detect this and treat it as a store +void write_to_later() +{ + writtenLater = 1.0f; +} + +float use_never_written() +{ + //CHK-DAG: warning 41017: use of uninitialized global variable 'writtenNever' + return writtenNever; +} + +// OK because of prior store +float use_later_writte() +{ + return writtenLater; +} + +////////////////////////////////// +// Uninitialized out parameters // +////////////////////////////////// + +// Using before assigning +float regular_undefined_use(out float3 v) +{ + //CHK-DAG: warning 41015: use of uninitialized out parameter 'v' + float r = v.x + 1.0; + + //CHK-DAG: warning 41018: returning without initializing out parameter 'v' + return r; +} + +// Returning before assigning +float returning_undefined_use(out float x) +{ + //CHK-DAG: warning 41018: returning without initializing out parameter 'x' + return 0; +} + +// Implicit, still returning before assigning +void implicit_undefined_use(out float x) +{ + //CHK-DAG: warning 41018: returning without initializing out parameter 'x' +} + +// Warn on potential return paths +void control_flow_undefined(bool b, out float y) +{ + if(b) + { + //CHK-DAG: warning 41018: returning without initializing out parameter 'y' + return; + } + y = 0; + return; +} + +// No warnings if all paths are fine +void control_flow_defined(bool b, out float y) +{ + if(b) + { + unused(y); + return; + } + y = 0; + return; +} + +//CHK-NOT: warning 41015 +//CHK-NOT: warning 41016 +//CHK-NOT: warning 41017 +//CHK-NOT: warning 41018 |
