diff options
Diffstat (limited to 'tests/initializer-list')
| -rw-r--r-- | tests/initializer-list/c-style-type.slang | 44 | ||||
| -rw-r--r-- | tests/initializer-list/default-member.slang | 35 | ||||
| -rw-r--r-- | tests/initializer-list/explicit-ctor-diagnostic.slang | 19 | ||||
| -rw-r--r-- | tests/initializer-list/explicit-ctor.slang | 41 | ||||
| -rw-r--r-- | tests/initializer-list/extension-overload-1.slang | 49 | ||||
| -rw-r--r-- | tests/initializer-list/extension-overload-2.slang | 28 | ||||
| -rw-r--r-- | tests/initializer-list/modulea.slang | 5 | ||||
| -rw-r--r-- | tests/initializer-list/partial-init-diagnostic.slang | 19 | ||||
| -rw-r--r-- | tests/initializer-list/partial-init.slang | 47 | ||||
| -rw-r--r-- | tests/initializer-list/struct-visibility-1.slang | 105 | ||||
| -rw-r--r-- | tests/initializer-list/struct-visibility-diagnostic-1.slang | 21 | ||||
| -rw-r--r-- | tests/initializer-list/struct-visibility-diagnostic-2.slang | 21 | ||||
| -rw-r--r-- | tests/initializer-list/struct-visibility-diagnostic-3.slang | 21 | ||||
| -rw-r--r-- | tests/initializer-list/struct-visibility-diagnostic-4.slang | 16 | ||||
| -rw-r--r-- | tests/initializer-list/unintialize-warning.slang | 85 |
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); +} |
