summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/bugs/gh-4434.slang24
-rw-r--r--tests/bugs/gh-4441.slang24
-rw-r--r--tests/diagnostics/ctor-ordinary-retval-legal.slang3
-rw-r--r--tests/diagnostics/uninitialized-out.slang57
-rw-r--r--tests/diagnostics/uninitialized.slang263
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