[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaHLSL / parameter_modifiers.hlsl
blob5c4a1e4ec2926a8b1c16672dd11cf7fe20f9d797
1 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library %s -verify -Wconversion
2 void fn(in out float f); // #fn
4 // expected-error@#fn2{{duplicate parameter modifier 'in'}}
5 // expected-note@#fn2{{conflicting attribute is here}}
6 void fn2(in in float f); // #fn2
8 // expected-error@#fn3{{duplicate parameter modifier 'out'}}
9 // expected-note@#fn3{{conflicting attribute is here}}
10 void fn3(out out float f); // #fn3
12 // expected-error@#fn4{{duplicate parameter modifier 'in'}}
13 // expected-error@#fn4{{duplicate parameter modifier 'out'}}
14 // expected-note@#fn4{{conflicting attribute is here}}
15 // expected-note@#fn4{{conflicting attribute is here}}
16 void fn4(inout in out float f); // #fn4
18 // expected-error@#fn5{{duplicate parameter modifier 'in'}}
19 // expected-note@#fn5{{conflicting attribute is here}}
20 void fn5(inout in float f); // #fn5
22 // expected-error@#fn6{{duplicate parameter modifier 'out'}}
23 // expected-note@#fn6{{conflicting attribute is here}}
24 void fn6(inout out float f); // #fn6
26 // expected-error@#fn-def{{conflicting parameter qualifier 'out' on parameter 'f'}}
27 // expected-note@#fn{{previously declared as 'inout' here}}
28 void fn(out float f) { // #fn-def
29   f = 2;
32 // Overload resolution failure.
33 void fn(in float f); // #fn-in
35 void failOverloadResolution() {
36   float f = 1.0;
37   fn(f); // expected-error{{call to 'fn' is ambiguous}}
38   // expected-note@#fn{{candidate function}}
39   // expected-note@#fn-in{{candidate function}}
42 void implicitFn(float f);
43 void inFn(in float f);
44 void inoutFn(inout float f); // #inoutFn
45 void outFn(out float f); // #outFn
47 void callFns() {
48   // Call with literal arguments.
49   implicitFn(1); // Ok.
50   inFn(1); // Ok.
51   inoutFn(1); // expected-error{{cannot bind non-lvalue argument 1 to inout paramemter}}
52   outFn(1); // expected-error{{cannot bind non-lvalue argument 1 to out paramemter}}
54   // Call with variables.
55   float f;
56   implicitFn(f); // Ok.
57   inFn(f); // Ok.
58   inoutFn(f); // Ok.
59   outFn(f); // Ok.
62 // No errors on these scenarios.
64 // Alternating `inout` and `in out` spellings between declaration and
65 // definitions is fine since they have the same semantic meaning.
66 void fn7(inout float f);
67 void fn7(in out float f) {}
69 void fn8(in out float f);
70 void fn8(inout float f) {}
72 // These two declare two different functions (although calling them will be
73 // ambiguous). This is equivalent to declaring a function that takes a
74 // reference and a function that takes a value of the same type.
75 void fn9(in float f);
76 void fn9(out float f);
78 // The `in` attribute is effectively optional. If no attribute is present it is
79 // the same as `in`, so these declarations match the functions.
80 void fn10(in float f);
81 void fn10(float f) {}
83 void fn11(float f);
84 void fn11(in float f) {}
86 template <typename T>
87 void fn12(inout T f);
89 void fn13() {
90   float f;
91   fn12<float>(f);
94 void fn14(out float f);
96 void fn15() {
97   float f;
98   int x = 5;
99   fn14(f += x); // expected-warning{{implicit conversion from 'int' to 'float' may lose precision}}