(root)/
gcc-13.2.0/
gcc/
testsuite/
jit.dg/
test-error-impossible-must-tail-call.c
       1  #include <stdlib.h>
       2  #include <stdio.h>
       3  
       4  #include "libgccjit.h"
       5  
       6  #include "harness.h"
       7  
       8  #ifdef __cplusplus
       9  extern "C" {
      10  #endif
      11  
      12    struct box { char dummy[64]; int i; };
      13  
      14    extern struct box
      15    returns_struct (int i);
      16  
      17  #ifdef __cplusplus
      18  }
      19  #endif
      20  
      21  void
      22  create_code (gcc_jit_context *ctxt, void *user_data)
      23  {
      24    /* Let's try to inject the equivalent of:
      25  
      26         int test (int i)
      27         {
      28           return [MUST TAIL CALL] returns_struct (i).i;
      29         }
      30  
      31       and verify that we get a sane error when the tail call
      32       optimization can't be done.  */
      33  
      34    gcc_jit_type *char_type =
      35      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR);
      36    gcc_jit_type *int_type =
      37      gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
      38  
      39    /* Declare "struct box.  */
      40    gcc_jit_type *array_type =
      41      gcc_jit_context_new_array_type (ctxt, NULL, char_type, 64);
      42    gcc_jit_field *field_dummy =
      43      gcc_jit_context_new_field (ctxt, NULL, array_type, "dummy");
      44    gcc_jit_field *field_i =
      45      gcc_jit_context_new_field (ctxt, NULL, int_type, "i");
      46    gcc_jit_field *fields[2] = {field_dummy, field_i};
      47    gcc_jit_struct *struct_box =
      48      gcc_jit_context_new_struct_type (ctxt, NULL, "box", 2, fields);
      49  
      50    /* Declare the imported function.  */
      51    gcc_jit_param *called_fn_param_i =
      52      gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
      53    gcc_jit_function *called_fn =
      54      gcc_jit_context_new_function (ctxt, NULL,
      55                                    GCC_JIT_FUNCTION_IMPORTED,
      56                                    gcc_jit_struct_as_type (struct_box),
      57                                    "called_function",
      58                                    1, &called_fn_param_i,
      59                                    0);
      60  
      61    /* Build the test_fn.  */
      62    gcc_jit_param *caller_param_i =
      63      gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
      64    gcc_jit_function *test_fn =
      65      gcc_jit_context_new_function (ctxt, NULL,
      66                                    GCC_JIT_FUNCTION_EXPORTED,
      67                                    int_type,
      68                                    "test_caller",
      69                                    1, &caller_param_i,
      70                                    0);
      71    gcc_jit_rvalue *arg = gcc_jit_param_as_rvalue (caller_param_i);
      72  
      73    gcc_jit_rvalue *call =
      74      gcc_jit_context_new_call (ctxt, NULL,
      75                                called_fn,
      76                                1, &arg);
      77  
      78    /* Mark the call as requiring tail-call optimization.  */
      79    gcc_jit_rvalue_set_bool_require_tail_call (call, 1);
      80  
      81    gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
      82    gcc_jit_block_end_with_return (block, NULL,
      83      gcc_jit_rvalue_access_field (call, NULL, field_i));
      84  }
      85  
      86  void
      87  verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
      88  {
      89    CHECK_VALUE (result, NULL);
      90  
      91    CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
      92  		      "cannot tail-call: callee returns a structure");
      93  }