test-accessing-union.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include "libgccjit.h"
  4. #include "harness.h"
  5. /* Quote from here in docs/topics/types.rst. */
  6. union int_or_float
  7. {
  8. int as_int;
  9. float as_float;
  10. };
  11. void
  12. create_code (gcc_jit_context *ctxt, void *user_data)
  13. {
  14. /* Let's try to inject the equivalent of:
  15. float
  16. test_union (int i)
  17. {
  18. union int_or_float u;
  19. u.as_int = i;
  20. return u.as_float;
  21. }
  22. */
  23. gcc_jit_type *int_type =
  24. gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
  25. gcc_jit_type *float_type =
  26. gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
  27. gcc_jit_field *as_int =
  28. gcc_jit_context_new_field (ctxt,
  29. NULL,
  30. int_type,
  31. "as_int");
  32. gcc_jit_field *as_float =
  33. gcc_jit_context_new_field (ctxt,
  34. NULL,
  35. float_type,
  36. "as_float");
  37. gcc_jit_field *fields[] = {as_int, as_float};
  38. gcc_jit_type *union_type =
  39. gcc_jit_context_new_union_type (ctxt, NULL,
  40. "int_or_float", 2, fields);
  41. /* Build the test function. */
  42. gcc_jit_param *param_i =
  43. gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
  44. gcc_jit_function *test_fn =
  45. gcc_jit_context_new_function (ctxt, NULL,
  46. GCC_JIT_FUNCTION_EXPORTED,
  47. float_type,
  48. "test_union",
  49. 1, &param_i,
  50. 0);
  51. gcc_jit_lvalue *u =
  52. gcc_jit_function_new_local (test_fn, NULL,
  53. union_type, "u");
  54. gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
  55. /* u.as_int = i; */
  56. gcc_jit_block_add_assignment (
  57. block,
  58. NULL,
  59. /* "u.as_int = ..." */
  60. gcc_jit_lvalue_access_field (u,
  61. NULL,
  62. as_int),
  63. gcc_jit_param_as_rvalue (param_i));
  64. /* return u.as_float; */
  65. gcc_jit_block_end_with_return (
  66. block, NULL,
  67. gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (u),
  68. NULL,
  69. as_float));
  70. }
  71. /* Quote up to here in docs/topics/types.rst. */
  72. void
  73. verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
  74. {
  75. typedef float (*fn_type) (int i);
  76. CHECK_NON_NULL (result);
  77. fn_type test_union =
  78. (fn_type)gcc_jit_result_get_code (result, "test_union");
  79. CHECK_NON_NULL (test_union);
  80. /* Call the JIT-generated function. */
  81. float f_result = test_union (42);
  82. union int_or_float u;
  83. u.as_float = f_result;
  84. CHECK_VALUE (u.as_int, 42);
  85. }