SkSLErrorTest.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. /*
  2. * Copyright 2016 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/sksl/SkSLCompiler.h"
  8. #include "tests/Test.h"
  9. static void test_failure(skiatest::Reporter* r, const char* src, const char* error) {
  10. SkSL::Compiler compiler;
  11. SkSL::Program::Settings settings;
  12. sk_sp<GrShaderCaps> caps = SkSL::ShaderCapsFactory::Default();
  13. settings.fCaps = caps.get();
  14. std::unique_ptr<SkSL::Program> program = compiler.convertProgram(SkSL::Program::kFragment_Kind,
  15. SkSL::String(src), settings);
  16. if (!compiler.errorCount()) {
  17. compiler.optimize(*program);
  18. }
  19. SkSL::String skError(error);
  20. if (compiler.errorText() != skError) {
  21. SkDebugf("SKSL ERROR:\n source: %s\n expected: %s received: %s", src, error,
  22. compiler.errorText().c_str());
  23. }
  24. REPORTER_ASSERT(r, compiler.errorText() == skError);
  25. }
  26. static void test_success(skiatest::Reporter* r, const char* src) {
  27. SkSL::Compiler compiler;
  28. SkSL::Program::Settings settings;
  29. sk_sp<GrShaderCaps> caps = SkSL::ShaderCapsFactory::Default();
  30. settings.fCaps = caps.get();
  31. std::unique_ptr<SkSL::Program> program = compiler.convertProgram(SkSL::Program::kFragment_Kind,
  32. SkSL::String(src), settings);
  33. REPORTER_ASSERT(r, program);
  34. }
  35. DEF_TEST(SkSLOpenArray, r) {
  36. test_failure(r,
  37. "void main(inout float4 color) { color.r[ = ( color.g ); }",
  38. "error: 1: expected expression, but found '='\n1 error\n");
  39. }
  40. DEF_TEST(SkSLUndefinedSymbol, r) {
  41. test_failure(r,
  42. "void main() { x = float2(1); }",
  43. "error: 1: unknown identifier 'x'\n1 error\n");
  44. }
  45. DEF_TEST(SkSLUndefinedFunction, r) {
  46. test_failure(r,
  47. "void main() { int x = foo(1); }",
  48. "error: 1: unknown identifier 'foo'\n1 error\n");
  49. }
  50. DEF_TEST(SkSLGenericArgumentMismatch, r) {
  51. test_failure(r,
  52. "void main() { float x = sin(1, 2); }",
  53. "error: 1: no match for sin(int, int)\n1 error\n");
  54. test_failure(r,
  55. "void main() { float x = sin(true); }",
  56. "error: 1: no match for sin(bool)\n1 error\n");
  57. test_success(r,
  58. "void main() { float x = sin(1); }");
  59. }
  60. DEF_TEST(SkSLArgumentCountMismatch, r) {
  61. test_failure(r,
  62. "float foo(float x) { return x * x; }"
  63. "void main() { float x = foo(1, 2); }",
  64. "error: 1: call to 'foo' expected 1 argument, but found 2\n1 error\n");
  65. }
  66. DEF_TEST(SkSLArgumentMismatch, r) {
  67. test_failure(r,
  68. "float foo(float x) { return x * x; }"
  69. "void main() { float x = foo(true); }",
  70. "error: 1: expected 'float', but found 'bool'\n1 error\n");
  71. }
  72. DEF_TEST(SkSLIfTypeMismatch, r) {
  73. test_failure(r,
  74. "void main() { if (3) { } }",
  75. "error: 1: expected 'bool', but found 'int'\n1 error\n");
  76. }
  77. DEF_TEST(SkSLDoTypeMismatch, r) {
  78. test_failure(r,
  79. "void main() { do { } while (float2(1)); }",
  80. "error: 1: expected 'bool', but found 'float2'\n1 error\n");
  81. }
  82. DEF_TEST(SkSLWhileTypeMismatch, r) {
  83. test_failure(r,
  84. "void main() { while (float3(1)) { } }",
  85. "error: 1: expected 'bool', but found 'float3'\n1 error\n");
  86. }
  87. DEF_TEST(SkSLForTypeMismatch, r) {
  88. test_failure(r,
  89. "void main() { for (int x = 0; x; x++) { } }",
  90. "error: 1: expected 'bool', but found 'int'\n1 error\n");
  91. }
  92. DEF_TEST(SkSLConstructorTypeMismatch, r) {
  93. test_failure(r,
  94. "void main() { float2 x = float2(1.0, false); }",
  95. "error: 1: expected 'float', but found 'bool'\n1 error\n");
  96. test_failure(r,
  97. "void main() { float2 x = float2(bool2(false)); }",
  98. "error: 1: 'bool2' is not a valid parameter to 'float2' constructor\n1 error\n");
  99. test_failure(r,
  100. "void main() { bool2 x = bool2(float2(1)); }",
  101. "error: 1: 'float2' is not a valid parameter to 'bool2' constructor\n1 error\n");
  102. test_failure(r,
  103. "void main() { bool x = bool(1.0); }",
  104. "error: 1: cannot construct 'bool'\n1 error\n");
  105. test_failure(r,
  106. "struct foo { int x; }; void main() { foo x = foo(5); }",
  107. "error: 1: cannot construct 'foo'\n1 error\n");
  108. test_failure(r,
  109. "struct foo { int x; } foo; void main() { float x = float(foo); }",
  110. "error: 1: invalid argument to 'float' constructor (expected a number or bool, but found 'foo')\n1 error\n");
  111. test_failure(r,
  112. "struct foo { int x; } foo; void main() { float2 x = float2(foo); }",
  113. "error: 1: 'foo' is not a valid parameter to 'float2' constructor\n1 error\n");
  114. test_failure(r,
  115. "void main() { float2x2 x = float2x2(true); }",
  116. "error: 1: expected 'float', but found 'bool'\n1 error\n");
  117. }
  118. DEF_TEST(SkSLConstructorArgumentCount, r) {
  119. test_failure(r,
  120. "void main() { float3 x = float3(1.0, 2.0); }",
  121. "error: 1: invalid arguments to 'float3' constructor (expected 3 scalars, but "
  122. "found 2)\n1 error\n");
  123. test_failure(r,
  124. "void main() { float3 x = float3(1.0, 2.0, 3.0, 4.0); }",
  125. "error: 1: invalid arguments to 'float3' constructor (expected 3 scalars, but found "
  126. "4)\n1 error\n");
  127. }
  128. DEF_TEST(SkSLSwizzleScalar, r) {
  129. test_failure(r,
  130. "void main() { float x = 1; float y = x.y; }",
  131. "error: 1: cannot swizzle value of type 'float'\n1 error\n");
  132. }
  133. DEF_TEST(SkSLSwizzleMatrix, r) {
  134. test_failure(r,
  135. "void main() { float2x2 x = float2x2(1); float y = x.y; }",
  136. "error: 1: cannot swizzle value of type 'float2x2'\n1 error\n");
  137. }
  138. DEF_TEST(SkSLSwizzleOutOfBounds, r) {
  139. test_failure(r,
  140. "void main() { float3 test = float2(1).xyz; }",
  141. "error: 1: invalid swizzle component 'z'\n1 error\n");
  142. }
  143. DEF_TEST(SkSLSwizzleTooManyComponents, r) {
  144. test_failure(r,
  145. "void main() { float4 test = float2(1).xxxxx; }",
  146. "error: 1: too many components in swizzle mask 'xxxxx'\n1 error\n");
  147. }
  148. DEF_TEST(SkSLSwizzleDuplicateOutput, r) {
  149. test_failure(r,
  150. "void main() { float4 test = float4(1); test.xyyz = float4(1); }",
  151. "error: 1: cannot write to the same swizzle field more than once\n1 error\n");
  152. }
  153. DEF_TEST(SkSLSwizzleConstantOutput, r) {
  154. test_failure(r,
  155. "void main() { float4 test = float4(1); test.xyz0 = float4(1); }",
  156. "error: 1: cannot write to a swizzle mask containing a constant\n1 error\n");
  157. }
  158. DEF_TEST(SkSLAssignmentTypeMismatch, r) {
  159. test_failure(r,
  160. "void main() { int x = 1.0; }",
  161. "error: 1: expected 'int', but found 'float'\n1 error\n");
  162. test_failure(r,
  163. "void main() { int x; x = 1.0; }",
  164. "error: 1: type mismatch: '=' cannot operate on 'int', 'float'\n1 error\n");
  165. test_success(r,
  166. "void main() { float3 x = float3(0); x *= 1.0; }");
  167. test_failure(r,
  168. "void main() { int3 x = int3(0); x *= 1.0; }",
  169. "error: 1: type mismatch: '*=' cannot operate on 'int3', 'float'\n1 error\n");
  170. }
  171. DEF_TEST(SkSLReturnFromVoid, r) {
  172. test_failure(r,
  173. "void main() { return true; }",
  174. "error: 1: may not return a value from a void function\n1 error\n");
  175. }
  176. DEF_TEST(SkSLReturnMissingValue, r) {
  177. test_failure(r,
  178. "int foo() { return; } void main() { }",
  179. "error: 1: expected function to return 'int'\n1 error\n");
  180. }
  181. DEF_TEST(SkSLReturnTypeMismatch, r) {
  182. test_failure(r,
  183. "int foo() { return 1.0; } void main() { }",
  184. "error: 1: expected 'int', but found 'float'\n1 error\n");
  185. }
  186. DEF_TEST(SkSLDuplicateFunction, r) {
  187. test_failure(r,
  188. "void main() { } void main() { }",
  189. "error: 1: duplicate definition of void main()\n1 error\n");
  190. test_success(r,
  191. "void main(); void main() { }");
  192. }
  193. DEF_TEST(SkSLUsingInvalidValue, r) {
  194. test_failure(r,
  195. "void main() { int x = int; }",
  196. "error: 1: expected '(' to begin constructor invocation\n1 error\n");
  197. test_failure(r,
  198. "int test() { return 1; } void main() { int x = test; }",
  199. "error: 1: expected '(' to begin function call\n1 error\n");
  200. }
  201. DEF_TEST(SkSLDifferentReturnType, r) {
  202. test_failure(r,
  203. "int main() { return 1; } void main() { }",
  204. "error: 1: functions 'void main()' and 'int main()' differ only in return type\n1 "
  205. "error\n");
  206. }
  207. DEF_TEST(SkSLDifferentModifiers, r) {
  208. test_failure(r,
  209. "void test(int x); void test(out int x) { }",
  210. "error: 1: modifiers on parameter 1 differ between declaration and definition\n1 "
  211. "error\n");
  212. }
  213. DEF_TEST(SkSLDuplicateSymbol, r) {
  214. test_failure(r,
  215. "int main; void main() { }",
  216. "error: 1: symbol 'main' was already defined\n1 error\n");
  217. test_failure(r,
  218. "int x; int x; void main() { }",
  219. "error: 1: symbol 'x' was already defined\n1 error\n");
  220. test_success(r, "int x; void main() { int x; }");
  221. }
  222. DEF_TEST(SkSLBinaryTypeMismatch, r) {
  223. test_failure(r,
  224. "void main() { float x = 3 * true; }",
  225. "error: 1: type mismatch: '*' cannot operate on 'int', 'bool'\n1 error\n");
  226. test_failure(r,
  227. "void main() { bool x = 1 || 2.0; }",
  228. "error: 1: type mismatch: '||' cannot operate on 'int', 'float'\n1 error\n");
  229. test_failure(r,
  230. "void main() { bool x = float2(0) == 0; }",
  231. "error: 1: type mismatch: '==' cannot operate on 'float2', 'int'\n1 error\n");
  232. test_failure(r,
  233. "void main() { bool x = float2(0) != 0; }",
  234. "error: 1: type mismatch: '!=' cannot operate on 'float2', 'int'\n1 error\n");
  235. }
  236. DEF_TEST(SkSLCallNonFunction, r) {
  237. test_failure(r,
  238. "void main() { float x = 3; x(); }",
  239. "error: 1: 'x' is not a function\n1 error\n");
  240. }
  241. DEF_TEST(SkSLInvalidUnary, r) {
  242. test_failure(r,
  243. "void main() { float4x4 x = float4x4(1); ++x; }",
  244. "error: 1: '++' cannot operate on 'float4x4'\n1 error\n");
  245. test_failure(r,
  246. "void main() { float3 x = float3(1); --x; }",
  247. "error: 1: '--' cannot operate on 'float3'\n1 error\n");
  248. test_failure(r,
  249. "void main() { float4x4 x = float4x4(1); x++; }",
  250. "error: 1: '++' cannot operate on 'float4x4'\n1 error\n");
  251. test_failure(r,
  252. "void main() { float3 x = float3(1); x--; }",
  253. "error: 1: '--' cannot operate on 'float3'\n1 error\n");
  254. test_failure(r,
  255. "void main() { int x = !12; }",
  256. "error: 1: '!' cannot operate on 'int'\n1 error\n");
  257. test_failure(r,
  258. "struct foo { } bar; void main() { foo x = +bar; }",
  259. "error: 1: '+' cannot operate on 'foo'\n1 error\n");
  260. test_failure(r,
  261. "struct foo { } bar; void main() { foo x = -bar; }",
  262. "error: 1: '-' cannot operate on 'foo'\n1 error\n");
  263. test_success(r,
  264. "void main() { float2 x = float2(1, 1); x = +x; x = -x; }");
  265. }
  266. DEF_TEST(SkSLInvalidAssignment, r) {
  267. test_failure(r,
  268. "void main() { 1 = 2; }",
  269. "error: 1: cannot assign to '1'\n1 error\n");
  270. test_failure(r,
  271. "uniform int x; void main() { x = 0; }",
  272. "error: 1: cannot modify immutable variable 'x'\n1 error\n");
  273. test_failure(r,
  274. "const int x; void main() { x = 0; }",
  275. "error: 1: cannot modify immutable variable 'x'\n1 error\n");
  276. }
  277. DEF_TEST(SkSLBadIndex, r) {
  278. test_failure(r,
  279. "void main() { int x = 2[0]; }",
  280. "error: 1: expected array, but found 'int'\n1 error\n");
  281. test_failure(r,
  282. "void main() { float2 x = float2(0); int y = x[0][0]; }",
  283. "error: 1: expected array, but found 'float'\n1 error\n");
  284. }
  285. DEF_TEST(SkSLTernaryMismatch, r) {
  286. test_failure(r,
  287. "void main() { int x = 5 > 2 ? true : 1.0; }",
  288. "error: 1: ternary operator result mismatch: 'bool', 'float'\n1 error\n");
  289. test_failure(r,
  290. "void main() { int x = 5 > 2 ? float3(1) : 1.0; }",
  291. "error: 1: ternary operator result mismatch: 'float3', 'float'\n1 error\n");
  292. }
  293. DEF_TEST(SkSLInterfaceBlockStorageModifiers, r) {
  294. test_failure(r,
  295. "uniform foo { out int x; };",
  296. "error: 1: interface block fields may not have storage qualifiers\n1 error\n");
  297. }
  298. DEF_TEST(SkSLUseWithoutInitialize, r) {
  299. test_failure(r,
  300. "void main() { int x; if (5 == 2) x = 3; x++; }",
  301. "error: 1: 'x' has not been assigned\n1 error\n");
  302. test_failure(r,
  303. "void main() { int x[2][2]; int i; x[i][1] = 4; }",
  304. "error: 1: 'i' has not been assigned\n1 error\n");
  305. test_failure(r,
  306. "int main() { int r; return r; }",
  307. "error: 1: 'r' has not been assigned\n1 error\n");
  308. test_failure(r,
  309. "void main() { int x; int y = x; }",
  310. "error: 1: 'x' has not been assigned\n1 error\n");
  311. test_failure(r,
  312. "void main() { bool x; if (true && (false || x)) return; }",
  313. "error: 1: 'x' has not been assigned\n1 error\n");
  314. test_failure(r,
  315. "void main() { int x; switch (3) { case 0: x = 0; case 1: x = 1; }"
  316. "sk_FragColor = half4(x); }",
  317. "error: 1: 'x' has not been assigned\n1 error\n");
  318. }
  319. DEF_TEST(SkSLUnreachable, r) {
  320. test_failure(r,
  321. "void main() { return; return; }",
  322. "error: 1: unreachable\n1 error\n");
  323. test_failure(r,
  324. "void main() { for (;;) { continue; int x = 1; } }",
  325. "error: 1: unreachable\n1 error\n");
  326. /* test_failure(r,
  327. "void main() { for (;;) { } return; }",
  328. "error: 1: unreachable\n1 error\n");*/
  329. test_failure(r,
  330. "void main() { if (true) return; else discard; return; }",
  331. "error: 1: unreachable\n1 error\n");
  332. test_failure(r,
  333. "void main() { return; while (true); }",
  334. "error: 1: unreachable\n1 error\n");
  335. }
  336. DEF_TEST(SkSLNoReturn, r) {
  337. test_failure(r,
  338. "int foo() { if (2 > 5) return 3; }",
  339. "error: 1: function can exit without returning a value\n1 error\n");
  340. }
  341. DEF_TEST(SkSLBreakOutsideLoop, r) {
  342. test_failure(r,
  343. "void foo() { while(true) {} if (true) break; }",
  344. "error: 1: break statement must be inside a loop or switch\n1 error\n");
  345. }
  346. DEF_TEST(SkSLContinueOutsideLoop, r) {
  347. test_failure(r,
  348. "void foo() { for(;;); continue; }",
  349. "error: 1: continue statement must be inside a loop\n1 error\n");
  350. test_failure(r,
  351. "void foo() { switch (1) { default: continue; } }",
  352. "error: 1: continue statement must be inside a loop\n1 error\n");
  353. }
  354. DEF_TEST(SkSLStaticIfError, r) {
  355. // ensure eliminated branch of static if / ternary is still checked for errors
  356. test_failure(r,
  357. "void foo() { if (true); else x = 5; }",
  358. "error: 1: unknown identifier 'x'\n1 error\n");
  359. test_failure(r,
  360. "void foo() { if (false) x = 5; }",
  361. "error: 1: unknown identifier 'x'\n1 error\n");
  362. test_failure(r,
  363. "void foo() { true ? 5 : x; }",
  364. "error: 1: unknown identifier 'x'\n1 error\n");
  365. test_failure(r,
  366. "void foo() { false ? x : 5; }",
  367. "error: 1: unknown identifier 'x'\n1 error\n");
  368. }
  369. DEF_TEST(SkSLBadCap, r) {
  370. test_failure(r,
  371. "bool b = sk_Caps.bugFreeDriver;",
  372. "error: 1: unknown capability flag 'bugFreeDriver'\n1 error\n");
  373. }
  374. DEF_TEST(SkSLDivByZero, r) {
  375. test_failure(r,
  376. "int x = 1 / 0;",
  377. "error: 1: division by zero\n1 error\n");
  378. test_failure(r,
  379. "float x = 1 / 0;",
  380. "error: 1: division by zero\n1 error\n");
  381. test_failure(r,
  382. "float x = 1.0 / 0.0;",
  383. "error: 1: division by zero\n1 error\n");
  384. test_failure(r,
  385. "float x = -67.0 / (3.0 - 3);",
  386. "error: 1: division by zero\n1 error\n");
  387. }
  388. DEF_TEST(SkSLUnsupportedGLSLIdentifiers, r) {
  389. test_failure(r,
  390. "void main() { float x = gl_FragCoord.x; };",
  391. "error: 1: unknown identifier 'gl_FragCoord'\n1 error\n");
  392. test_failure(r,
  393. "void main() { float r = gl_FragColor.r; };",
  394. "error: 1: unknown identifier 'gl_FragColor'\n1 error\n");
  395. }
  396. DEF_TEST(SkSLWrongSwitchTypes, r) {
  397. test_failure(r,
  398. "void main() { switch (float2(1)) { case 1: break; } }",
  399. "error: 1: expected 'int', but found 'float2'\n1 error\n");
  400. test_failure(r,
  401. "void main() { switch (1) { case float2(1): break; } }",
  402. "error: 1: expected 'int', but found 'float2'\n1 error\n");
  403. }
  404. DEF_TEST(SkSLNonConstantCase, r) {
  405. test_failure(r,
  406. "void main() { int x = 1; switch (1) { case x: break; } }",
  407. "error: 1: case value must be a constant\n1 error\n");
  408. }
  409. DEF_TEST(SkSLDuplicateCase, r) {
  410. test_failure(r,
  411. "void main() { switch (1) { case 0: case 1: case 0: break; } }",
  412. "error: 1: duplicate case value\n1 error\n");
  413. }
  414. DEF_TEST(SkSLFieldAfterRuntimeArray, r) {
  415. test_failure(r,
  416. "buffer broken { float x[]; float y; };",
  417. "error: 1: only the last entry in an interface block may be a runtime-sized "
  418. "array\n1 error\n");
  419. }
  420. DEF_TEST(SkSLStaticIf, r) {
  421. test_success(r,
  422. "void main() { float x = 5; float y = 10;"
  423. "@if (x < y) { sk_FragColor = half4(1); } }");
  424. test_failure(r,
  425. "void main() { float x = sqrt(25); float y = 10;"
  426. "@if (x < y) { sk_FragColor = half4(1); } }",
  427. "error: 1: static if has non-static test\n1 error\n");
  428. }
  429. DEF_TEST(SkSLStaticSwitch, r) {
  430. test_success(r,
  431. "void main() {"
  432. "int x = 1;"
  433. "@switch (x) {"
  434. "case 1: sk_FragColor = half4(1); break;"
  435. "default: sk_FragColor = half4(0);"
  436. "}"
  437. "}");
  438. test_failure(r,
  439. "void main() {"
  440. "int x = int(sqrt(1));"
  441. "@switch (x) {"
  442. "case 1: sk_FragColor = half4(1); break;"
  443. "default: sk_FragColor = half4(0);"
  444. "}"
  445. "}",
  446. "error: 1: static switch has non-static test\n1 error\n");
  447. test_failure(r,
  448. "void main() {"
  449. "int x = 1;"
  450. "@switch (x) {"
  451. "case 1: sk_FragColor = half4(1); if (sqrt(0) < sqrt(1)) break;"
  452. "default: sk_FragColor = half4(0);"
  453. "}"
  454. "}",
  455. "error: 1: static switch contains non-static conditional break\n1 error\n");
  456. }
  457. DEF_TEST(SkSLInterfaceBlockScope, r) {
  458. test_failure(r,
  459. "uniform testBlock {"
  460. "float x;"
  461. "} test[x];",
  462. "error: 1: unknown identifier 'x'\n1 error\n");
  463. }
  464. DEF_TEST(SkSLDuplicateOutput, r) {
  465. test_failure(r,
  466. "layout (location=0, index=0) out half4 duplicateOutput;",
  467. "error: 1: out location=0, index=0 is reserved for sk_FragColor\n1 error\n");
  468. }
  469. DEF_TEST(SkSLConstantSwizzleNotLast, r) {
  470. test_failure(r,
  471. "void main() { sk_FragColor = half4(1).rg00; }",
  472. "error: 1: only the last swizzle component can be a constant\n1 error\n");
  473. }