summaryrefslogtreecommitdiff
path: root/tests/initializer-list
diff options
context:
space:
mode:
Diffstat (limited to 'tests/initializer-list')
-rw-r--r--tests/initializer-list/c-style-type.slang44
-rw-r--r--tests/initializer-list/default-member.slang35
-rw-r--r--tests/initializer-list/explicit-ctor-diagnostic.slang19
-rw-r--r--tests/initializer-list/explicit-ctor.slang41
-rw-r--r--tests/initializer-list/extension-overload-1.slang49
-rw-r--r--tests/initializer-list/extension-overload-2.slang28
-rw-r--r--tests/initializer-list/modulea.slang5
-rw-r--r--tests/initializer-list/partial-init-diagnostic.slang19
-rw-r--r--tests/initializer-list/partial-init.slang47
-rw-r--r--tests/initializer-list/struct-visibility-1.slang105
-rw-r--r--tests/initializer-list/struct-visibility-diagnostic-1.slang21
-rw-r--r--tests/initializer-list/struct-visibility-diagnostic-2.slang21
-rw-r--r--tests/initializer-list/struct-visibility-diagnostic-3.slang21
-rw-r--r--tests/initializer-list/struct-visibility-diagnostic-4.slang16
-rw-r--r--tests/initializer-list/unintialize-warning.slang85
15 files changed, 556 insertions, 0 deletions
diff --git a/tests/initializer-list/c-style-type.slang b/tests/initializer-list/c-style-type.slang
new file mode 100644
index 000000000..500bf37bb
--- /dev/null
+++ b/tests/initializer-list/c-style-type.slang
@@ -0,0 +1,44 @@
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj -vk
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj
+
+struct CLike
+{
+ int x;
+ int y;
+ // compiler synthesizes:
+ // __init(int x, int y);
+}
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+void test()
+{
+ // case 1: initialized with synthesized ctor call using legacy logic to form arguments,
+ // and `c1` is now `{0,0}`.
+ CLike c1 = {};
+
+ // case 2: initialized with legacy initializaer list logic, `c1` is now `{1,0}`:
+ CLike c2 = {1};
+
+ // case 3: initilaized with ctor call `CLike(1,2)`, `c3` is now `{1,2}`:
+ CLike c3 = {1, 2};
+
+ // BUFFER: 0
+ outputBuffer[0] = c1.x;
+ // BUFFER-NEXT: 0
+ outputBuffer[1] = c1.y;
+ // BUFFER-NEXT: 1
+ outputBuffer[2] = c2.x;
+ // BUFFER-NEXT: 0
+ outputBuffer[3] = c2.y;
+ // BUFFER-NEXT: 1
+ outputBuffer[4] = c3.x;
+ // BUFFER-NEXT: 2
+ outputBuffer[5] = c3.y;
+}
+
+[shader("compute")]
+void computeMain()
+{
+ test();
+}
diff --git a/tests/initializer-list/default-member.slang b/tests/initializer-list/default-member.slang
new file mode 100644
index 000000000..8a6a0dc7f
--- /dev/null
+++ b/tests/initializer-list/default-member.slang
@@ -0,0 +1,35 @@
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj -vk
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj
+
+struct DefaultMember {
+ int x = 0;
+ int y = 1;
+ // compiler synthesizes:
+ // __init(int x = 0, int y = 1);
+}
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+void test()
+{
+ DefaultMember m1 = {1}; // calls `__init(1)`, initialized to `{1,1}`.
+
+ // BUFFER: 1
+ outputBuffer[0] = m1.x;
+
+ // BUFFER-NEXT: 1
+ outputBuffer[1] = m1.y;
+
+ DefaultMember m2 = {1,2}; // calls `__init(1,2)`, initialized to `{1,2}`.
+
+ // BUFFER-NEXT: 1
+ outputBuffer[2] = m2.x;
+ // BUFFER-NEXT: 2
+ outputBuffer[3] = m2.y;
+}
+
+[shader("compute")]
+void computeMain()
+{
+ test();
+}
diff --git a/tests/initializer-list/explicit-ctor-diagnostic.slang b/tests/initializer-list/explicit-ctor-diagnostic.slang
new file mode 100644
index 000000000..a9d0e9858
--- /dev/null
+++ b/tests/initializer-list/explicit-ctor-diagnostic.slang
@@ -0,0 +1,19 @@
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK):
+
+struct ExplicitCtor
+{
+ int x;
+ int y;
+ __init(int x)
+ {
+ this.x = x;
+ this.y = 0;
+ }
+ // compiler does not synthesize any ctors.
+}
+
+void test()
+{
+ // CHECK: error 39999: too many arguments to call (got 2, expected 1)
+ ExplicitCtor e = {1, 2}; // error, no ctor matches initializer list.
+}
diff --git a/tests/initializer-list/explicit-ctor.slang b/tests/initializer-list/explicit-ctor.slang
new file mode 100644
index 000000000..c587bcce4
--- /dev/null
+++ b/tests/initializer-list/explicit-ctor.slang
@@ -0,0 +1,41 @@
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj -vk
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj
+
+struct ExplicitCtor
+{
+ int x;
+ int y;
+ __init(int x)
+ {
+ this.x = x;
+ this.y = x + 5;
+ }
+}
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+void test()
+{
+ // case 1: initialized with synthesized ctor call using legacy logic to form arguments,
+ // and `c1` is now `{0,0}`.
+ ExplicitCtor c1 = {4};
+
+ // BUFFER: 4
+ outputBuffer[0] = c1.x;
+ // BUFFER-NEXT: 9
+ outputBuffer[1] = c1.y;
+
+
+ ExplicitCtor c2 = ExplicitCtor(10);
+
+ // BUFFER: A
+ outputBuffer[2] = c2.x;
+ // BUFFER-NEXT: F
+ outputBuffer[3] = c2.y;
+}
+
+[shader("compute")]
+void computeMain()
+{
+ test();
+}
diff --git a/tests/initializer-list/extension-overload-1.slang b/tests/initializer-list/extension-overload-1.slang
new file mode 100644
index 000000000..1c3189f84
--- /dev/null
+++ b/tests/initializer-list/extension-overload-1.slang
@@ -0,0 +1,49 @@
+
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj -vk
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj
+
+import modulea;
+
+// Definition of the Foo struct
+// struct Foo
+// {
+// int a;
+// int b;
+// }
+
+// This test demonstrates that whether struct is a C-Style type only depends on the definition of the struct, not the extension.
+// Even we have an explicit constructor defined in extension of Foo, it is still a C-Style type.
+
+extension Foo
+{
+ __init(int a)
+ {
+ this.a = a + 5;
+ this.b = 3;
+ }
+}
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+
+[shader("compute")]
+[numthreads(1, 1, 1)]
+void computeMain()
+{
+
+ // This will miss both synthesized constructor and explicit constructor in extension, but it will still fall back
+ // to legacy initializer list because Foo is a C-Style type.
+ Foo foo = {};
+ //CHECK: BUFFER: 0
+ //CHECK: BUFFER-NEXT: 0
+ outputBuffer[0] = foo.a;
+ outputBuffer[1] = foo.b;
+
+
+ // When providing 1 parameter, it will lookup for the explicit constructor in extension.
+ Foo foo1 = {1};
+ //CHECK: BUFFER: 6
+ //CHECK: BUFFER-NEXT: 3
+ outputBuffer[2] = foo1.a;
+ outputBuffer[3] = foo1.b;
+}
diff --git a/tests/initializer-list/extension-overload-2.slang b/tests/initializer-list/extension-overload-2.slang
new file mode 100644
index 000000000..3937127f4
--- /dev/null
+++ b/tests/initializer-list/extension-overload-2.slang
@@ -0,0 +1,28 @@
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj -vk
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj
+
+struct Foo
+{
+ int a;
+}
+
+extension Foo
+{
+ __init(int a)
+ {
+ this.a = a + 5;
+ }
+}
+
+//TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+
+[shader("compute")]
+[numthreads(1, 1, 1)]
+void computeMain()
+{
+ // it will prefer the explicit constructor defined in the extension instead of the synthesized one in the struct
+ Foo foo = {1.0f};
+ //CHECK: BUFFER: 6
+ outputBuffer[0] = foo.a;
+}
diff --git a/tests/initializer-list/modulea.slang b/tests/initializer-list/modulea.slang
new file mode 100644
index 000000000..48a4a5d6a
--- /dev/null
+++ b/tests/initializer-list/modulea.slang
@@ -0,0 +1,5 @@
+export struct Foo
+{
+ int a;
+ int b;
+}
diff --git a/tests/initializer-list/partial-init-diagnostic.slang b/tests/initializer-list/partial-init-diagnostic.slang
new file mode 100644
index 000000000..ea3acb2c7
--- /dev/null
+++ b/tests/initializer-list/partial-init-diagnostic.slang
@@ -0,0 +1,19 @@
+//DISABLE_DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK):
+
+struct PartialInit
+{
+ int x = 1;
+ int y;
+ // compiler synthesizes:
+ // __init(int x, int y);
+}
+
+void test()
+{
+ // TODO: Because we have a legacy logic that will always convert the one arugment ctor call to
+ // initializer list, and that initializer list will fall back to the legacy C-Style initialization.
+ // We need to remove that logic.
+
+ // CHECK: error 33070: expected a function, got 'typeof(PartialInit)'
+ PartialInit p = PartialInit(2); // error, no ctor match.
+}
diff --git a/tests/initializer-list/partial-init.slang b/tests/initializer-list/partial-init.slang
new file mode 100644
index 000000000..55f3816fb
--- /dev/null
+++ b/tests/initializer-list/partial-init.slang
@@ -0,0 +1,47 @@
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj -vk
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj
+
+struct PartialInit {
+ // warning: not all members are initialized.
+ // members should either be all-uninitialized or all-initialized with
+ // default expr.
+ int x;
+ int y = 1;
+ // compiler synthesizes:
+ // __init(int x, int y = 1);
+}
+
+struct PartialInit2 {
+ int x = 1;
+ int y;
+ // __init(int x, int y);
+}
+//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+void test()
+{
+ PartialInit p1 = {2}; // calls `__init`, result is `{2,1}`.
+ // BUFFER: 2
+ outputBuffer[0] = p1.x;
+ // BUFFER-NEXT: 1
+ outputBuffer[1] = p1.y;
+
+
+ PartialInit p2 = {2, 3}; // calls `__init`, result is {2, 3}
+ // BUFFER-NEXT: 2
+ outputBuffer[2] = p2.x;
+ // BUFFER-NEXT: 3
+ outputBuffer[3] = p2.y;
+
+ PartialInit2 p3 = {4, 5}; // calls `__init`, result is {4, 5}
+ // BUFFER-NEXT: 4
+ outputBuffer[4] = p3.x;
+ // BUFFER-NEXT: 5
+ outputBuffer[5] = p3.y;
+}
+
+[shader("compute")]
+void computeMain()
+{
+ test();
+}
diff --git a/tests/initializer-list/struct-visibility-1.slang b/tests/initializer-list/struct-visibility-1.slang
new file mode 100644
index 000000000..691e8c991
--- /dev/null
+++ b/tests/initializer-list/struct-visibility-1.slang
@@ -0,0 +1,105 @@
+
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj -vk
+//TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj
+
+public struct Visibility
+{
+ internal int x = 1;
+ public int y = 5;
+
+ int getX() { return x; }
+}
+
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], stride=4):out,name=outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+void test(inout uint index)
+{
+ Visibility t1 = {}; // OK, initialized to {1,5} via ctor call.
+ // BUFFER: 1
+ outputBuffer[index++] = t1.getX();
+ // BUFFER-NEXT: 5
+ outputBuffer[index++] = t1.y;
+
+ Visibility t2 = {1}; // OK, initialized to {1,1} via ctor call.
+ // BUFFER-NEXT: 1
+ outputBuffer[index++] = t2.getX();
+ // BUFFER-NEXT: 1
+ outputBuffer[index++] = t2.y;
+}
+
+internal struct Visibility2
+{
+ // Visibility3 type is considered as C-style struct.
+ // Because all members have the same visibility as the type.
+ // Therefore we will attempt the legacy fallback logic for
+ // initializer-list syntax.
+ // Note that c-style structs can still have init exprs on members.
+ internal int x;
+ internal int y = 2;
+ // compiler synthesizes:
+ // internal __init(int x, int y = 2);
+}
+
+internal void test2(inout uint index)
+{
+ Visibility2 t = {3, 4}; // OK, initialized to {3,4} via ctor call.
+ // BUFFER-NEXT: 3
+ outputBuffer[index++] = t.x;
+ // BUFFER-NEXT: 4
+ outputBuffer[index++] = t.y;
+
+ Visibility2 t1 = {1}; // OK, initialized to {1,2} via ctor call.
+ // BUFFER-NEXT: 1
+ outputBuffer[index++] = t1.x;
+ // BUFFER-NEXT: 2
+ outputBuffer[index++] = t1.y;
+
+ Visibility2 t2 = {}; // OK, initialized to {0, 2} via legacy logic.
+ // BUFFER-NEXT: 0
+ outputBuffer[index++] = t2.x;
+ // BUFFER-NEXT: 2
+ outputBuffer[index++] = t2.y;
+}
+
+internal struct Visibility3
+{
+ // Visibility4 type is considered as C-style struct.
+ // And we still synthesize a ctor for member initialization.
+ // Because Visibility4 has no public members, the synthesized
+ // ctor will take 0 arguments.
+ internal int x = 1;
+ internal int y = 2;
+ // compiler synthesizes:
+ // internal __init(int x = 1, int y = 2);
+}
+
+internal void test3(inout uint index)
+{
+ Visibility3 t = {0, 0}; // OK, initialized to {0,0} via ctor call.
+ // BUFFER-NEXT: 0
+ outputBuffer[index++] = t.x;
+ // BUFFER-NEXT: 0
+ outputBuffer[index++] = t.y;
+
+ Visibility3 t1 = {3}; // OK, initialized to {3,2} via ctor call.
+ // BUFFER-NEXT: 3
+ outputBuffer[index++] = t1.x;
+ // BUFFER-NEXT: 2
+ outputBuffer[index++] = t1.y;
+
+ Visibility3 t2 = {}; // OK, initialized to {1,2} via ctor call.
+ // BUFFER-NEXT: 1
+ outputBuffer[index++] = t2.x;
+ // BUFFER-NEXT: 2
+ outputBuffer[index++] = t2.y;
+}
+
+[shader("compute")]
+void computeMain()
+{
+ uint index = 0;
+ test(index);
+ test2(index);
+ test3(index);
+}
diff --git a/tests/initializer-list/struct-visibility-diagnostic-1.slang b/tests/initializer-list/struct-visibility-diagnostic-1.slang
new file mode 100644
index 000000000..ab11933ae
--- /dev/null
+++ b/tests/initializer-list/struct-visibility-diagnostic-1.slang
@@ -0,0 +1,21 @@
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK):
+
+public struct Visibility
+{
+ internal int x;
+ public int y = 0;
+ // the compiler does not synthesize any ctor.
+ // the compiler will try to synthesize:
+ // public __init(int y);
+ // but then it will find that `x` cannot be initialized.
+ // so this synthesis will fail and no ctor will be added
+ // to the type.
+}
+
+void test()
+{
+ // CHECK: error 39999: too many arguments to call (got 2, expected 1)
+ Visibility t1 = {1, 2}; // error, no matching ctor
+}
+
+
diff --git a/tests/initializer-list/struct-visibility-diagnostic-2.slang b/tests/initializer-list/struct-visibility-diagnostic-2.slang
new file mode 100644
index 000000000..a3255de5e
--- /dev/null
+++ b/tests/initializer-list/struct-visibility-diagnostic-2.slang
@@ -0,0 +1,21 @@
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK):
+
+public struct Visibility
+{
+ internal int x;
+ public int y = 5;
+ // the compiler does not synthesize any ctor.
+ // the compiler will try to synthesize:
+ // public __init(int y);
+ // but then it will find that `x` cannot be initialized.
+ // so this synthesis will fail and no ctor will be added
+ // to the type.
+}
+
+void test()
+{
+ // CHECK: warning 41021: default initializer for 'Visibility' will not initialize field 'x'
+ Visibility t1 = {};
+}
+
+
diff --git a/tests/initializer-list/struct-visibility-diagnostic-3.slang b/tests/initializer-list/struct-visibility-diagnostic-3.slang
new file mode 100644
index 000000000..75ac5919d
--- /dev/null
+++ b/tests/initializer-list/struct-visibility-diagnostic-3.slang
@@ -0,0 +1,21 @@
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK):
+
+public struct Visibility
+{
+ internal int x;
+ public int y;
+ // the compiler does not synthesize any ctor.
+ // the compiler will try to synthesize:
+ // public __init(int y);
+ // but then it will find that `x` cannot be initialized.
+ // so this synthesis will fail and no ctor will be added
+ // to the type.
+}
+
+void test()
+{
+ //CHECK: error 39999: not enough arguments to call (got 0, expected 1)
+ Visibility t1 = {};
+}
+
+
diff --git a/tests/initializer-list/struct-visibility-diagnostic-4.slang b/tests/initializer-list/struct-visibility-diagnostic-4.slang
new file mode 100644
index 000000000..9bc3a76f0
--- /dev/null
+++ b/tests/initializer-list/struct-visibility-diagnostic-4.slang
@@ -0,0 +1,16 @@
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK):
+
+public struct Visibility
+{
+ internal int x = 1;
+ public int y = 5;
+ // compiler synthesizes:
+ // public __init(int y = 0);
+}
+
+void test()
+{
+ //CHECK: error 39999: too many arguments to call (got 2, expected 1)
+ Visibility t1 = {1, 2};
+}
+
diff --git a/tests/initializer-list/unintialize-warning.slang b/tests/initializer-list/unintialize-warning.slang
new file mode 100644
index 000000000..b8f2867ee
--- /dev/null
+++ b/tests/initializer-list/unintialize-warning.slang
@@ -0,0 +1,85 @@
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK):
+
+struct CLike
+{
+ int x;
+ int y;
+ // compiler synthesizes:
+ // __init(int x, int y);
+}
+
+struct ExplicitCtor
+{
+ int x;
+ int y;
+ __init(int x)
+ {
+ this.x = x;
+ this.y = 0;
+ }
+ // compiler does not synthesize any ctors.
+}
+
+struct DefaultMember {
+ int x = 0;
+ int y = 1;
+ // compiler synthesizes:
+ // __init(int x = 0, int y = 1);
+}
+
+struct PartialInit1 {
+ int x;
+ int y = 1;
+ // compiler synthesizes:
+ // __init(int x, int y = 1);
+}
+
+struct PartialInit2 {
+ int x = 1;
+ int y; // warning: not all members are initialized.
+ // compiler synthesizes:
+ // __init(int x, int y);
+}
+
+void func1(CLike c)
+{
+}
+
+void func2(ExplicitCtor e)
+{
+}
+
+void func3(DefaultMember d)
+{
+}
+
+void func4(PartialInit1 p)
+{
+}
+
+void func5(PartialInit2 p)
+{
+}
+
+void test()
+{
+ CLike c; // `c` is uninitialized.
+ // CHECK: warning 41016: use of uninitialized variable 'c'
+ func1(c);
+
+ ExplicitCtor e; // `e` is uninitialized.
+ // CHECK: warning 41016: use of uninitialized variable 'e'
+ func2(e);
+
+ DefaultMember d; // `d` is uninitialized.
+ // CHECK: warning 41016: use of uninitialized variable 'd'
+ func3(d);
+
+ PartialInit1 p1; // `p` is uninitialized.
+ // CHECK: warning 41016: use of uninitialized variable 'p1'
+ func4(p1);
+
+ PartialInit2 p2; // `p` is uninitialized.
+ // CHECK: warning 41016: use of uninitialized variable 'p2'
+ func5(p2);
+}