(root)/
gcc-13.2.0/
gcc/
testsuite/
jit.dg/
test-local-init-rvalue.c
       1  #include <stdio.h>
       2  #include "libgccjit.h"
       3  #include "harness.h"
       4  
       5  /* This testcase checks that gcc_jit_context_new_constructor() works
       6     with locals. Tests that constructors can be used as return
       7     values or function call values. Test that constructors can have side
       8     effects and be assigned to locals.
       9   */
      10  
      11  void
      12  create_code (gcc_jit_context *ctxt, void *user_data)
      13  {
      14    gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
      15      GCC_JIT_TYPE_INT);
      16    gcc_jit_type *pint_type = gcc_jit_type_get_pointer (int_type);
      17    gcc_jit_type *double_type = gcc_jit_context_get_type (ctxt,
      18      GCC_JIT_TYPE_DOUBLE);
      19    gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt,
      20      GCC_JIT_TYPE_FLOAT);
      21    gcc_jit_type *bool_type = gcc_jit_context_get_type (ctxt,
      22      GCC_JIT_TYPE_BOOL);
      23    gcc_jit_type *char_type = gcc_jit_context_get_type (ctxt,
      24      GCC_JIT_TYPE_CHAR);
      25    gcc_jit_type *size_type = gcc_jit_context_get_type (ctxt,
      26      GCC_JIT_TYPE_SIZE_T);
      27    gcc_jit_type *voidptr_type = gcc_jit_context_get_type (ctxt,
      28      GCC_JIT_TYPE_VOID_PTR);
      29    gcc_jit_type *void_type = gcc_jit_context_get_type (ctxt,
      30      GCC_JIT_TYPE_VOID);
      31  
      32    /* Make a struct: struct fi { float f; int i;} */
      33    gcc_jit_field *fi_f = gcc_jit_context_new_field (ctxt,
      34  						 0,
      35  						 float_type,
      36  						 "f");
      37    gcc_jit_field *fi_i = gcc_jit_context_new_field (ctxt,
      38  						 0,
      39  						 int_type,
      40  						 "i");
      41    gcc_jit_field *fields[] = {fi_f, fi_i};
      42  
      43    gcc_jit_type *struct_fi_type =
      44      gcc_jit_struct_as_type (
      45        gcc_jit_context_new_struct_type (ctxt,
      46  				       0,
      47  				       "fi",
      48  				       2,
      49  				       fields));
      50  
      51    /* Make a struct:
      52  
      53       struct bar {
      54         int ii;
      55         int arr[50];
      56         float ff;
      57         char cc;
      58       }
      59    */
      60    gcc_jit_field *bar_ff = gcc_jit_context_new_field (ctxt,
      61  				  0,
      62  				  float_type,
      63  				  "ff");
      64    gcc_jit_field *bar_ii = gcc_jit_context_new_field (ctxt,
      65  				  0,
      66  				  int_type,
      67  				  "ii");
      68    gcc_jit_field *bar_cc = gcc_jit_context_new_field (ctxt,
      69  				  0,
      70  				  char_type,
      71  				  "cc");
      72    gcc_jit_type *int50arr_type =
      73      gcc_jit_context_new_array_type (ctxt,
      74  				    0,
      75  				    int_type,
      76  				    50);
      77    gcc_jit_field *bar_fi = gcc_jit_context_new_field (ctxt,
      78  						 0,
      79  						 int50arr_type,
      80  						 "arr");
      81    gcc_jit_field *fields2[] = {bar_ff, bar_fi, bar_ii, bar_cc};
      82  
      83    gcc_jit_type *struct_bar_type =
      84      gcc_jit_struct_as_type (
      85        gcc_jit_context_new_struct_type (ctxt,
      86  				       0,
      87  				       "bar",
      88  				       4,
      89  				       fields2));
      90  
      91    /* Make an union:
      92  
      93       union ubar {
      94         float ff;
      95         int ii;
      96       };
      97    */
      98    gcc_jit_field *ubar_ff = gcc_jit_context_new_field (ctxt,
      99  						      0,
     100  						      float_type,
     101  						      "ff");
     102    gcc_jit_field *ubar_ii = gcc_jit_context_new_field (ctxt,
     103  						      0,
     104  						      int_type,
     105  						      "ii");
     106    gcc_jit_field *fields3[] = {ubar_ff, ubar_ii};
     107    gcc_jit_type *ubar = gcc_jit_context_new_union_type (ctxt,
     108  						       0,
     109  						       "ubar",
     110  						       2,
     111  						       fields3);
     112  
     113    (void) ubar;
     114    (void) struct_bar_type;
     115    (void) struct_fi_type;
     116    (void) bool_type;
     117    (void) double_type;
     118    (void) pint_type;
     119    (void) voidptr_type;
     120    (void) size_type;
     121  
     122    gcc_jit_function *fn_int_3;
     123    { /* int foo () { int local = 3; return local;} */
     124      fn_int_3 =
     125        gcc_jit_context_new_function (ctxt,
     126  				    0,
     127  				    GCC_JIT_FUNCTION_EXPORTED,
     128  				    int_type,
     129  				    "fn_int_3",
     130  				    0,
     131  				    0,
     132  				    0);
     133      gcc_jit_block *block = gcc_jit_function_new_block (fn_int_3, "start");
     134      gcc_jit_lvalue *local = gcc_jit_function_new_local (fn_int_3,
     135  							0,
     136  							int_type,
     137  							"local");
     138      gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int (
     139        ctxt, int_type, 3);
     140  
     141      gcc_jit_block_add_assignment (block, 0, local, rval);
     142  
     143      gcc_jit_block_end_with_return (block,
     144  				   0,
     145  				   gcc_jit_lvalue_as_rvalue(local));
     146    }
     147    { /* struct fi foo() { return (struct fi){1,2};} */
     148      gcc_jit_function *fn =
     149        gcc_jit_context_new_function (ctxt,
     150  				    0,
     151  				    GCC_JIT_FUNCTION_EXPORTED,
     152  				    struct_fi_type,
     153  				    "fn_fi_1_2",
     154  				    0,
     155  				    0,
     156  				    0);
     157      gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
     158  
     159      gcc_jit_rvalue *rval_f1 = gcc_jit_context_new_rvalue_from_int (
     160        ctxt, float_type, 1);
     161      gcc_jit_rvalue *rval_i2 = gcc_jit_context_new_rvalue_from_int (
     162        ctxt, int_type, 2);
     163  
     164      gcc_jit_rvalue *vals[] = { rval_f1, rval_i2};
     165      gcc_jit_field *fields[] = {fi_f, fi_i};
     166  
     167      gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
     168        (ctxt, 0,
     169         struct_fi_type,
     170         2,
     171         fields,
     172         vals);
     173  
     174      gcc_jit_block_end_with_return (block,
     175  				   0,
     176  				   ctor);
     177    }
     178    { /*
     179         struct fi foo()
     180         {
     181  	 struct fi local = {1,2};
     182  	 local = (struct fi){5,6};
     183  	 return local;
     184         }
     185       */
     186      gcc_jit_function *fn =
     187        gcc_jit_context_new_function (ctxt,
     188  				    0,
     189  				    GCC_JIT_FUNCTION_EXPORTED,
     190  				    struct_fi_type,
     191  				    "fn_fi_5_6",
     192  				    0,
     193  				    0,
     194  				    0);
     195      gcc_jit_lvalue *local = gcc_jit_function_new_local (fn,
     196  							0,
     197  							struct_fi_type,
     198  							"local");
     199      gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
     200  
     201      {
     202        gcc_jit_rvalue *rval_f1 =
     203  	gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 1);
     204        gcc_jit_rvalue *rval_i2 =
     205  	gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 2);
     206  
     207        gcc_jit_rvalue *vals[] = { rval_f1, rval_i2};
     208        gcc_jit_field *fields[] = {fi_f, fi_i};
     209  
     210        gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
     211  	(ctxt, 0,
     212  	 struct_fi_type,
     213  	 2,
     214  	 fields,
     215  	 vals);
     216        gcc_jit_block_add_assignment (block, 0, local, ctor);
     217      }
     218      {
     219        gcc_jit_rvalue *rval_f1 =
     220  	gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 5);
     221        gcc_jit_rvalue *rval_i2 =
     222  	gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 6);
     223  
     224        gcc_jit_rvalue *vals[] = { rval_f1, rval_i2};
     225        gcc_jit_field *fields[] = {fi_f, fi_i};
     226  
     227        gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
     228  	(ctxt, 0,
     229  	 struct_fi_type,
     230  	 2,
     231  	 fields,
     232  	 vals);
     233        gcc_jit_block_add_assignment (block, 0, local, ctor);
     234      }
     235  
     236      gcc_jit_block_end_with_return (block,
     237  				   0,
     238  				   gcc_jit_lvalue_as_rvalue(local));
     239    }
     240    { /* struct fi foo() { struct fi local = {1, fn_int_3()};
     241  			 return local;}
     242  
     243         The ctor has a side effect (funccall) */
     244      gcc_jit_function *fn =
     245        gcc_jit_context_new_function (ctxt,
     246  				    0,
     247  				    GCC_JIT_FUNCTION_EXPORTED,
     248  				    struct_fi_type,
     249  				    "fn_fi_1_3",
     250  				    0,
     251  				    0,
     252  				    0);
     253      gcc_jit_lvalue *local = gcc_jit_function_new_local (fn,
     254  							0,
     255  							struct_fi_type,
     256  							"local");
     257      gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
     258  
     259      {
     260        gcc_jit_rvalue *rval_f1 =
     261  	gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 1);
     262        gcc_jit_rvalue *rval_i2 =
     263  	gcc_jit_context_new_call (ctxt, 0, fn_int_3, 0, 0);
     264  
     265        gcc_jit_rvalue *vals[] = { rval_f1, rval_i2};
     266        gcc_jit_field *fields[] = {fi_f, fi_i};
     267  
     268        gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
     269  	(ctxt, 0,
     270  	 struct_fi_type,
     271  	 2,
     272  	 fields,
     273  	 vals);
     274        gcc_jit_block_add_assignment (block, 0, local, ctor);
     275      }
     276  
     277      gcc_jit_block_end_with_return (block,
     278  				   0,
     279  				   gcc_jit_lvalue_as_rvalue(local));
     280    }
     281    { /* struct fi foo(fi) { return fi;}
     282         struct fi bar() { return foo((struct fi){3, 4}); }
     283       */
     284  
     285      gcc_jit_param *fi_param =
     286        gcc_jit_context_new_param (ctxt, 0, struct_fi_type, "fi");
     287  
     288      gcc_jit_function *fn0 =
     289        gcc_jit_context_new_function (ctxt,
     290  				    0,
     291  				    GCC_JIT_FUNCTION_EXPORTED,
     292  				    struct_fi_type,
     293  				    "fn_fi_x_x",
     294  				    1,
     295  				    &fi_param,
     296  				    0);
     297      gcc_jit_block *block0 = gcc_jit_function_new_block (fn0, "start");
     298      gcc_jit_block_end_with_return (block0,
     299  				   0,
     300  				   gcc_jit_param_as_rvalue (
     301  				     gcc_jit_function_get_param (fn0, 0)));
     302  
     303      gcc_jit_function *fn =
     304        gcc_jit_context_new_function (ctxt,
     305  				    0,
     306  				    GCC_JIT_FUNCTION_EXPORTED,
     307  				    struct_fi_type,
     308  				    "fn_fi_3_4",
     309  				    0,
     310  				    0,
     311  				    0);
     312      gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
     313  
     314      gcc_jit_rvalue *rval_f1 = gcc_jit_context_new_rvalue_from_int (
     315        ctxt, float_type, 3);
     316      gcc_jit_rvalue *rval_i2 = gcc_jit_context_new_rvalue_from_int (
     317        ctxt, int_type, 4);
     318  
     319      gcc_jit_rvalue *vals[] = { rval_f1, rval_i2};
     320      gcc_jit_field *fields[] = {fi_f, fi_i};
     321  
     322      gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
     323        (ctxt, 0,
     324         struct_fi_type,
     325         2,
     326         fields,
     327         vals);
     328  
     329      gcc_jit_rvalue *call = gcc_jit_context_new_call (ctxt, 0, fn0, 1, &ctor);
     330  
     331      gcc_jit_block_end_with_return (block,
     332  				   0,
     333  				   call);
     334    }
     335    { /*
     336         void foo(struct bar *b) { *b = (struct bar) {.arr = {1,2}; }
     337       */
     338  
     339      gcc_jit_param *param =
     340        gcc_jit_context_new_param (ctxt, 0,
     341  				 gcc_jit_type_get_pointer (struct_bar_type),
     342  				 "b");
     343  
     344  
     345      gcc_jit_function *fn =
     346        gcc_jit_context_new_function (ctxt,
     347  				    0,
     348  				    GCC_JIT_FUNCTION_EXPORTED,
     349  				    void_type,
     350  				    "fn_pbar_12",
     351  				    1,
     352  				    &param,
     353  				    0);
     354      gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
     355  
     356      gcc_jit_rvalue *rval_i1 = gcc_jit_context_new_rvalue_from_int (
     357        ctxt, int_type, 1);
     358      gcc_jit_rvalue *rval_i2 = gcc_jit_context_new_rvalue_from_int (
     359        ctxt, int_type, 2);
     360  
     361      gcc_jit_rvalue *arr_vals[] = { rval_i1, rval_i2};
     362  
     363      gcc_jit_rvalue *arr_ctor = gcc_jit_context_new_array_constructor
     364        (ctxt, 0,
     365         int50arr_type,
     366         2,
     367         arr_vals);
     368  
     369      gcc_jit_rvalue *str_ctor = gcc_jit_context_new_struct_constructor
     370        (ctxt,
     371         0,
     372         struct_bar_type,
     373         1,
     374         &bar_fi,
     375         &arr_ctor);
     376  
     377      gcc_jit_param *p0 = gcc_jit_function_get_param (fn, 0);
     378      gcc_jit_lvalue *lv0 =  gcc_jit_param_as_lvalue (p0);
     379      gcc_jit_lvalue *deref =
     380        gcc_jit_rvalue_dereference (gcc_jit_lvalue_as_rvalue (lv0), 0);
     381  
     382      gcc_jit_block_add_assignment (block, 0,
     383  				  deref,
     384  				  str_ctor);
     385  
     386      gcc_jit_block_end_with_void_return (block, 0);
     387    }
     388    { /* struct bar foo() { struct bar local = {};
     389  			  return local;}
     390       */
     391      gcc_jit_function *fn =
     392        gcc_jit_context_new_function (ctxt,
     393  				    0,
     394  				    GCC_JIT_FUNCTION_EXPORTED,
     395  				    struct_bar_type,
     396  				    "fn_bar_0s",
     397  				    0,
     398  				    0,
     399  				    0);
     400      gcc_jit_lvalue *local =
     401        gcc_jit_function_new_local (fn,
     402  				  0,
     403  				  struct_bar_type,
     404  				  "local");
     405      gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
     406  
     407      gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
     408  	(ctxt, 0,
     409  	 struct_bar_type,
     410  	 0,
     411  	 0,
     412  	 0);
     413      gcc_jit_block_add_assignment (block, 0, local, ctor);
     414  
     415      gcc_jit_block_end_with_return (block,
     416  				   0,
     417  				   gcc_jit_lvalue_as_rvalue(local));
     418    }
     419    { /* struct bar foo() { struct bar local;
     420  			  local.arr = (int [50]){1,2,3,4,5,6};
     421  			  return local;}
     422       */
     423      gcc_jit_function *fn =
     424        gcc_jit_context_new_function (ctxt,
     425  				    0,
     426  				    GCC_JIT_FUNCTION_EXPORTED,
     427  				    struct_bar_type,
     428  				    "fn_bar_123s",
     429  				    0,
     430  				    0,
     431  				    0);
     432      gcc_jit_lvalue *local =
     433        gcc_jit_function_new_local (fn,
     434  				  0,
     435  				  struct_bar_type,
     436  				  "local");
     437      gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
     438  
     439      gcc_jit_rvalue *values[6];
     440  
     441      for (int i = 0; i < 6; i++)
     442        values[i] = gcc_jit_context_new_rvalue_from_int (ctxt, int_type, i + 1);
     443  
     444      gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor
     445  	(ctxt, 0,
     446  	 int50arr_type,
     447  	 6,
     448  	 values);
     449  
     450      gcc_jit_lvalue *arr_lv = gcc_jit_lvalue_access_field (local,
     451  							  0,
     452  							  bar_fi);
     453      gcc_jit_block_add_assignment (block, 0, arr_lv, ctor);
     454  
     455      gcc_jit_block_end_with_return (block,
     456  				   0,
     457  				   gcc_jit_lvalue_as_rvalue(local));
     458    }
     459    { /* int[50] foo() { int arr[50];
     460  		       arr = (int [50]){1,2,3,4,5,6};
     461  		       return arr;}
     462  
     463         N.B: Not a typo, returning an array.
     464       */
     465      gcc_jit_function *fn =
     466        gcc_jit_context_new_function (ctxt,
     467  				    0,
     468  				    GCC_JIT_FUNCTION_EXPORTED,
     469  				    int50arr_type,
     470  				    "fn_int50arr_123s",
     471  				    0,
     472  				    0,
     473  				    0);
     474      gcc_jit_lvalue *local =
     475        gcc_jit_function_new_local (fn,
     476  				  0,
     477  				  int50arr_type,
     478  				  "local");
     479      gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
     480  
     481      gcc_jit_rvalue *values[6];
     482  
     483      for (int i = 0; i < 6; i++)
     484        values[i] = gcc_jit_context_new_rvalue_from_int (ctxt, int_type, i + 1);
     485  
     486      gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (
     487  	 ctxt,
     488  	 0,
     489  	 int50arr_type,
     490  	 6,
     491  	 values);
     492  
     493      gcc_jit_block_add_assignment (block, 0, local, ctor);
     494  
     495      gcc_jit_block_end_with_return (block,
     496  				   0,
     497  				   gcc_jit_lvalue_as_rvalue(local));
     498    }
     499    { /*
     500        Verify that circular linked lists compiles, .e.g.
     501        that visit_children does not run in circles or something.
     502  
     503        struct llist { struct llist *next; };
     504  
     505        bool foo (void)
     506        {
     507  	volatile struct llist a;
     508  	volatile struct llist b;
     509  
     510  	a = (struct llist) {.next = &b};
     511  	b = (struct llist) {.next = &a};
     512  
     513  	return a.next == &b;
     514        }
     515      */
     516      gcc_jit_struct *llist =
     517        gcc_jit_context_new_opaque_struct(ctxt,
     518  					0, "llist_lcl");
     519      gcc_jit_field *fields[] =
     520        {
     521  	gcc_jit_context_new_field (ctxt, 0,
     522  				   gcc_jit_type_get_pointer (
     523  				     gcc_jit_struct_as_type (llist)),
     524  				   "next")
     525        };
     526      gcc_jit_struct_set_fields (llist, 0, 1, fields);
     527      gcc_jit_type *t_llist = gcc_jit_struct_as_type (llist);
     528  
     529      gcc_jit_function *fn =
     530        gcc_jit_context_new_function (ctxt,
     531  				    0,
     532  				    GCC_JIT_FUNCTION_EXPORTED,
     533  				    bool_type,
     534  				    "fn_llist",
     535  				    0,
     536  				    0,
     537  				    0);
     538      gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
     539  
     540      gcc_jit_lvalue *a =
     541        gcc_jit_function_new_local (fn,
     542  				  0,
     543  				  gcc_jit_type_get_volatile (t_llist),
     544  				  "a");
     545      gcc_jit_lvalue *b =
     546        gcc_jit_function_new_local (fn,
     547  				  0,
     548  				  gcc_jit_type_get_volatile (t_llist),
     549  				  "b");
     550  
     551      gcc_jit_rvalue *a_addr = gcc_jit_lvalue_get_address( a, 0);
     552      gcc_jit_rvalue *b_addr = gcc_jit_lvalue_get_address( b, 0);
     553  
     554      gcc_jit_rvalue *a_ctor = gcc_jit_context_new_struct_constructor (
     555  	 ctxt,
     556  	 0,
     557  	 t_llist,
     558  	 1,
     559  	 0,
     560  	 &b_addr);
     561  
     562      gcc_jit_rvalue *b_ctor = gcc_jit_context_new_struct_constructor (
     563  	 ctxt,
     564  	 0,
     565  	 t_llist,
     566  	 1,
     567  	 0,
     568  	 &a_addr);
     569  
     570      gcc_jit_block_add_assignment (block, 0,
     571  				  a, a_ctor);
     572      gcc_jit_block_add_assignment (block, 0,
     573  				  b, b_ctor);
     574  
     575      gcc_jit_rvalue *cmp =
     576        gcc_jit_context_new_comparison (
     577  	ctxt, 0,
     578  	GCC_JIT_COMPARISON_EQ,
     579  	gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (a),
     580  				     0, fields[0]),
     581  	gcc_jit_context_new_cast (ctxt, 0,
     582  				  gcc_jit_lvalue_get_address (b, 0),
     583  				  gcc_jit_type_get_pointer (t_llist)));
     584  
     585      gcc_jit_block_end_with_return (block,
     586  				   0, cmp);
     587    }
     588  }
     589  
     590  struct fi2 {
     591    float f;
     592    int i;
     593  };
     594  
     595  struct bar2 {
     596    float ff;
     597    int arr[50];
     598    int ii;
     599    char c;
     600  };
     601  
     602  union ubar2 {
     603    float ff;
     604    int ii;
     605  };
     606  
     607  struct int50arr {
     608    int arr[50];
     609  };
     610  
     611  void __attribute__((optimize(0)))
     612  scramble_stack(void)
     613    {
     614      char *p = alloca(100);
     615      for (int i = 0; i < 100; i++)
     616        *p++ = 0xF0;
     617      asm(""); /* Mark for side-effect */
     618    }
     619  
     620  void __attribute__((optimize(0)))
     621  scramble_arr (char *arr, int len)
     622  {
     623    for (int i = 0; i < len; i++)
     624      *arr++ = i;
     625    asm(""); /* Mark for side-effect */
     626  }
     627  
     628  void
     629  verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
     630  {
     631    CHECK_NON_NULL (result);
     632  
     633    {
     634      struct fi2 (*fn) (void) = gcc_jit_result_get_code (result, "fn_fi_1_2");
     635      scramble_stack ();
     636      struct fi2 fi = fn ();
     637      CHECK_VALUE (fi.f, 1);
     638      CHECK_VALUE (fi.i, 2);
     639    }
     640    {
     641      struct fi2 (*fn) (void) = gcc_jit_result_get_code (result, "fn_fi_5_6");
     642      struct fi2 fi = fn ();
     643      CHECK_VALUE (fi.f, 5);
     644      CHECK_VALUE (fi.i, 6);
     645    }
     646    {
     647      struct fi2 (*fn) (void) = gcc_jit_result_get_code (result, "fn_fi_1_3");
     648      struct fi2 fi = fn ();
     649      CHECK_VALUE (fi.f, 1);
     650      CHECK_VALUE (fi.i, 3);
     651    }
     652    {
     653      struct fi2 (*fn) (void) = gcc_jit_result_get_code (result, "fn_fi_3_4");
     654      struct fi2 fi = fn ();
     655      CHECK_VALUE (fi.f, 3);
     656      CHECK_VALUE (fi.i, 4);
     657    }
     658    {
     659      scramble_stack();
     660      struct bar2 (*fn) (void) = gcc_jit_result_get_code (result, "fn_bar_0s");
     661      struct bar2 bar = fn ();
     662      struct bar2 key = {};
     663  
     664      CHECK_VALUE (bar.ff, 0);
     665      CHECK_VALUE (bar.ii, 0);
     666      CHECK_VALUE (memcmp (&bar.arr, &key.arr, sizeof (key.arr)), 0);
     667    }
     668    {
     669  
     670      void (*fn) (struct bar2 *) = gcc_jit_result_get_code (result, "fn_pbar_12");
     671  
     672      struct bar2 bar = (struct bar2) {};
     673  
     674      scramble_arr ((char*)&bar, sizeof bar);
     675      scramble_stack();
     676  
     677      fn (&bar);
     678  
     679      struct bar2 key = {.arr = {1,2}};
     680      __builtin_clear_padding (&key);
     681  
     682      CHECK_VALUE (memcmp (&bar, &key, sizeof (key)), 0);
     683    }
     684    {
     685      scramble_stack();
     686      struct bar2 (*fn) (void) = gcc_jit_result_get_code (result, "fn_bar_123s");
     687      struct bar2 bar = fn ();
     688      struct bar2 key = {.arr = {1,2,3,4,5,6} };
     689  
     690      CHECK_VALUE (memcmp (&bar.arr, &key.arr, sizeof (key.arr)), 0);
     691    }
     692    {
     693      scramble_stack ();
     694      /* This is abit shady. Lets just pretend that array returns à la Fortran
     695         is the same thing as returning a struct with an array in it in C. */
     696      struct int50arr (*fn) (void) =
     697        gcc_jit_result_get_code (result, "fn_int50arr_123s");
     698      struct int50arr ans = fn ();
     699      int key[50] = {1,2,3,4,5,6};
     700  
     701      CHECK_VALUE (memcmp (ans.arr, key, sizeof (key)), 0);
     702    }
     703    {
     704      _Bool (*fn) (void) = gcc_jit_result_get_code (result, "fn_llist");
     705      CHECK_VALUE (fn (), 1);
     706    }
     707  }