github.com/gotranspile/cxgo@v0.3.7/pointers_test.go (about)

     1  package cxgo
     2  
     3  import "testing"
     4  
     5  var casesTranslatePtrs = []parseCase{
     6  	{
     7  		name: "if ptr",
     8  		src: `
     9  void foo() {
    10  	int* a;
    11  	if (a) return;
    12  }
    13  `,
    14  		exp: `
    15  func foo() {
    16  	var a *int32
    17  	if a != nil {
    18  		return
    19  	}
    20  }
    21  `,
    22  	},
    23  	{
    24  		name: "if not ptr",
    25  		src: `
    26  void foo() {
    27  	int* a;
    28  	if (!a) return;
    29  }
    30  `,
    31  		exp: `
    32  func foo() {
    33  	var a *int32
    34  	if a == nil {
    35  		return
    36  	}
    37  }
    38  `,
    39  	},
    40  	{
    41  		name: "if unsafe ptr",
    42  		src: `
    43  void foo() {
    44  	void* a;
    45  	if (a) return;
    46  }
    47  `,
    48  		exp: `
    49  func foo() {
    50  	var a unsafe.Pointer
    51  	if a != nil {
    52  		return
    53  	}
    54  }
    55  `,
    56  	},
    57  	{
    58  		name: "if not unsafe ptr",
    59  		src: `
    60  void foo() {
    61  	void* a;
    62  	if (!a) return;
    63  }
    64  `,
    65  		exp: `
    66  func foo() {
    67  	var a unsafe.Pointer
    68  	if a == nil {
    69  		return
    70  	}
    71  }
    72  `,
    73  	},
    74  	{
    75  		name: "if func",
    76  		src: `
    77  void foo() {
    78  	void(*a)(void);
    79  	if (a) return;
    80  }
    81  `,
    82  		exp: `
    83  func foo() {
    84  	var a func()
    85  	if a != nil {
    86  		return
    87  	}
    88  }
    89  `,
    90  	},
    91  	{
    92  		name: "if not func",
    93  		src: `
    94  void foo() {
    95  	void(*a)(void);
    96  	if (!a) return;
    97  }
    98  `,
    99  		exp: `
   100  func foo() {
   101  	var a func()
   102  	if a == nil {
   103  		return
   104  	}
   105  }
   106  `,
   107  	},
   108  	{
   109  		name: "bool -> ptr",
   110  		src: `
   111  #include <stdbool.h>
   112  
   113  void foo() {
   114  	bool a;
   115  	int* b;
   116  	b = a;
   117  }
   118  `,
   119  		exp: `
   120  func foo() {
   121  	var (
   122  		a bool
   123  		b *int32
   124  	)
   125  	_ = b
   126  	b = (*int32)(unsafe.Pointer(uintptr(libc.BoolToInt(a))))
   127  }
   128  `,
   129  	},
   130  	{
   131  		name:     "uintptr",
   132  		builtins: true,
   133  		src: `
   134  void bar(_cxgo_go_uintptr a) {
   135  	bar(a);
   136  }
   137  void foo(unsigned int a, int b) {
   138  	_cxgo_go_uintptr c;
   139  	c = a;
   140  	c = b;
   141  	bar(a);
   142  	bar(b);
   143  	bar(c);
   144  }
   145  `,
   146  		exp: `
   147  func bar(a uintptr) {
   148  	bar(a)
   149  }
   150  func foo(a uint32, b int32) {
   151  	var c uintptr
   152  	c = uintptr(a)
   153  	c = uintptr(b)
   154  	bar(uintptr(a))
   155  	bar(uintptr(b))
   156  	bar(c)
   157  }
   158  `,
   159  	},
   160  	{
   161  		name: "inc ptr",
   162  		src: `
   163  void foo() {
   164  	char* a;
   165  	a++;
   166  	a--;
   167  }
   168  `,
   169  		exp: `
   170  func foo() {
   171  	var a *byte
   172  	a = (*byte)(unsafe.Add(unsafe.Pointer(a), 1))
   173  	a = (*byte)(unsafe.Add(unsafe.Pointer(a), -1))
   174  }
   175  `,
   176  	},
   177  	{
   178  		name: "unsafe ptr add",
   179  		src: `
   180  void foo() {
   181  	int a = 2;
   182  	void* pa;
   183  	pa = pa + a;
   184  	pa = pa + 3;
   185  	pa += a;
   186  	pa += 5;
   187  }
   188  `,
   189  		exp: `
   190  func foo() {
   191  	var (
   192  		a  int32 = 2
   193  		pa unsafe.Pointer
   194  	)
   195  	pa = unsafe.Add(pa, a)
   196  	pa = unsafe.Add(pa, 3)
   197  	pa = unsafe.Add(pa, a)
   198  	pa = unsafe.Add(pa, 5)
   199  }
   200  `,
   201  	},
   202  	{
   203  		name: "named ptr -> named ptr",
   204  		src: `
   205  typedef struct{} A;
   206  typedef struct{} B;
   207  void foo(A* a) {
   208  	B *b = a;
   209  }
   210  `,
   211  		exp: `
   212  type A struct {
   213  }
   214  type B struct {
   215  }
   216  
   217  func foo(a *A) {
   218  	var b *B = (*B)(unsafe.Pointer(a))
   219  	_ = b
   220  }
   221  `,
   222  	},
   223  	{
   224  		name: "cast ptr to func ptr",
   225  		src: `
   226  void foo(void* a) {
   227  	(*(void (**)(void))a)();
   228  }
   229  `,
   230  		exp: `
   231  func foo(a unsafe.Pointer) {
   232  	(*(*func())(a))()
   233  }
   234  `,
   235  	},
   236  	{
   237  		name: "cast ptr to func",
   238  		src: `
   239  void foo(int* a) {
   240  	((void (*)(void))a)();
   241  }
   242  `,
   243  		exp: `
   244  func foo(a *int32) {
   245  	(libc.AsFunc(a, (*func())(nil)).(func()))()
   246  }
   247  `,
   248  	},
   249  	{
   250  		name: "cast ptr to int",
   251  		src: `
   252  void foo(int* a) {
   253  	int b = a;
   254  }
   255  `,
   256  		exp: `
   257  func foo(a *int32) {
   258  	var b int32 = int32(uintptr(unsafe.Pointer(a)))
   259  	_ = b
   260  }
   261  `,
   262  	},
   263  	{
   264  		name: "cast struct ptr to int",
   265  		src: `
   266  typedef struct A {} A;
   267  
   268  void foo(A* a) {
   269  	int b = a;
   270  }
   271  `,
   272  		exp: `
   273  type A struct {
   274  }
   275  
   276  func foo(a *A) {
   277  	var b int32 = int32(uintptr(unsafe.Pointer(a)))
   278  	_ = b
   279  }
   280  `,
   281  	},
   282  	{
   283  		name: "cast func to int",
   284  		src: `
   285  void foo(int a) {
   286  	a = foo;
   287  }
   288  `,
   289  		exp: `
   290  func foo(a int32) {
   291  	a = int32(libc.FuncAddr(foo))
   292  }
   293  `,
   294  	},
   295  	{
   296  		name: "ptr multi cast",
   297  		src: `
   298  typedef int* PT;
   299  
   300  void foo(PT a) {
   301  	char b;
   302  	foo((PT)&b);
   303  }
   304  `,
   305  		exp: `
   306  type PT *int32
   307  
   308  func foo(a PT) {
   309  	var b int8
   310  	foo(PT(unsafe.Pointer(&b)))
   311  }
   312  `,
   313  	},
   314  	{
   315  		name: "ptr add",
   316  		src: `
   317  void foo() {
   318  	int a = 2;
   319  	int* pa;
   320  	pa = pa + a;
   321  	pa = pa + 3;
   322  	pa += a;
   323  	pa += 5;
   324  }
   325  `,
   326  		exp: `
   327  func foo() {
   328  	var (
   329  		a  int32 = 2
   330  		pa *int32
   331  	)
   332  	pa = (*int32)(unsafe.Add(unsafe.Pointer(pa), unsafe.Sizeof(int32(0))*uintptr(a)))
   333  	pa = (*int32)(unsafe.Add(unsafe.Pointer(pa), unsafe.Sizeof(int32(0))*3))
   334  	pa = (*int32)(unsafe.Add(unsafe.Pointer(pa), unsafe.Sizeof(int32(0))*uintptr(a)))
   335  	pa = (*int32)(unsafe.Add(unsafe.Pointer(pa), unsafe.Sizeof(int32(0))*5))
   336  }
   337  `,
   338  	},
   339  	{
   340  		name: "int add ptr",
   341  		src: `
   342  void foo() {
   343  	int a = 2;
   344  	int* pa;
   345  	pa = a + 4;
   346  }
   347  `,
   348  		exp: `
   349  func foo() {
   350  	var (
   351  		a  int32 = 2
   352  		pa *int32
   353  	)
   354  	_ = pa
   355  	pa = (*int32)(unsafe.Pointer(uintptr(a + 4)))
   356  }
   357  `,
   358  	},
   359  	{
   360  		name: "int add short ptr",
   361  		src: `
   362  void foo() {
   363  	int a = 2;
   364  	short* pa;
   365  	pa = a + 748;
   366  }
   367  `,
   368  		exp: `
   369  func foo() {
   370  	var (
   371  		a  int32 = 2
   372  		pa *int16
   373  	)
   374  	_ = pa
   375  	pa = (*int16)(unsafe.Pointer(uintptr(a + 748)))
   376  }
   377  `,
   378  	},
   379  	{
   380  		name: "int add short ptr unaligned",
   381  		src: `
   382  void foo() {
   383  	int a = 2;
   384  	short* pa;
   385  	pa = a + 3;
   386  }
   387  `,
   388  		exp: `
   389  func foo() {
   390  	var (
   391  		a  int32 = 2
   392  		pa *int16
   393  	)
   394  	_ = pa
   395  	pa = (*int16)(unsafe.Pointer(uintptr(a + 3)))
   396  }
   397  `,
   398  	},
   399  	{
   400  		name: "int add byte ptr",
   401  		src: `
   402  void foo() {
   403  	int a = 2;
   404  	char* pa;
   405  	pa = a + 4;
   406  }
   407  `,
   408  		exp: `
   409  func foo() {
   410  	var (
   411  		a  int32 = 2
   412  		pa *byte
   413  	)
   414  	_ = pa
   415  	pa = (*byte)(unsafe.Pointer(uintptr(a + 4)))
   416  }
   417  `,
   418  	},
   419  	{
   420  		name: "int add byte ptr unaligned",
   421  		src: `
   422  void foo() {
   423  	int a = 2;
   424  	char* pa;
   425  	pa = a + 3;
   426  }
   427  `,
   428  		exp: `
   429  func foo() {
   430  	var (
   431  		a  int32 = 2
   432  		pa *byte
   433  	)
   434  	_ = pa
   435  	pa = (*byte)(unsafe.Pointer(uintptr(a + 3)))
   436  }
   437  `,
   438  	},
   439  	{
   440  		name: "int -> unsafe ptr",
   441  		src: `
   442  void foo() {
   443  	int a;
   444  	void* b;
   445  	b = a;
   446  }
   447  `,
   448  		exp: `
   449  func foo() {
   450  	var (
   451  		a int32
   452  		b unsafe.Pointer
   453  	)
   454  	_ = b
   455  	b = unsafe.Pointer(uintptr(a))
   456  }
   457  `,
   458  	},
   459  	{
   460  		name: "unsafe ptr -> int",
   461  		src: `
   462  void foo() {
   463  	void* a;
   464  	int b;
   465  	b = a;
   466  }
   467  `,
   468  		exp: `
   469  func foo() {
   470  	var (
   471  		a unsafe.Pointer
   472  		b int32
   473  	)
   474  	_ = b
   475  	b = int32(uintptr(a))
   476  }
   477  `,
   478  	},
   479  	{
   480  		name: "int -> ptr",
   481  		src: `
   482  void foo() {
   483  	int a;
   484  	int* b;
   485  	b = a;
   486  }
   487  `,
   488  		exp: `
   489  func foo() {
   490  	var (
   491  		a int32
   492  		b *int32
   493  	)
   494  	_ = b
   495  	b = (*int32)(unsafe.Pointer(uintptr(a)))
   496  }
   497  `,
   498  	},
   499  	{
   500  		name: "ptr -> int",
   501  		src: `
   502  void foo() {
   503  	int* a;
   504  	int b;
   505  	b = a;
   506  }
   507  `,
   508  		exp: `
   509  func foo() {
   510  	var (
   511  		a *int32
   512  		b int32
   513  	)
   514  	_ = b
   515  	b = int32(uintptr(unsafe.Pointer(a)))
   516  }
   517  `,
   518  	},
   519  	{
   520  		name: "array -> ptr",
   521  		src: `
   522  void foo() {
   523  	char a[5];
   524  	int* b;
   525  	b = a;
   526  }
   527  `,
   528  		exp: `
   529  func foo() {
   530  	var (
   531  		a [5]byte
   532  		b *int32
   533  	)
   534  	_ = b
   535  	b = (*int32)(unsafe.Pointer(&a[0]))
   536  }
   537  `,
   538  	},
   539  	{
   540  		name: "array -> unsafe ptr",
   541  		src: `
   542  void foo() {
   543  	char a[5];
   544  	void* b;
   545  	b = a;
   546  }
   547  `,
   548  		exp: `
   549  func foo() {
   550  	var (
   551  		a [5]byte
   552  		b unsafe.Pointer
   553  	)
   554  	_ = b
   555  	b = unsafe.Pointer(&a[0])
   556  }
   557  `,
   558  	},
   559  	{
   560  		name: "store func ptr",
   561  		src: `
   562  void foo() {
   563  	char a[8];
   564  	*(void**)& a[4] = &foo;
   565  }
   566  `,
   567  		exp: `
   568  func foo() {
   569  	var a [8]byte
   570  	*(*unsafe.Pointer)(unsafe.Pointer(&a[4])) = unsafe.Pointer(libc.FuncAddr(foo))
   571  }
   572  `,
   573  	},
   574  	{
   575  		name: "get func pointer",
   576  		src: `
   577  void foo() {
   578  	char a[8];
   579  	(*(void(**)(int)) &a)(1);
   580  }
   581  `,
   582  		exp: `
   583  func foo() {
   584  	var a [8]byte
   585  	(*(*func(int32))(unsafe.Pointer(&a[0])))(1)
   586  }
   587  `,
   588  	},
   589  	{
   590  		name: "call func ptr",
   591  		src: `
   592  void foo(void(***a)(void)) {
   593  	void(**b)(void);
   594  	b = *a;
   595  	(*b)();
   596  }
   597  `,
   598  		exp: `
   599  func foo(a **func()) {
   600  	var b *func()
   601  	b = *a
   602  	(*b)()
   603  }
   604  `,
   605  	},
   606  	{
   607  		name: "post inc and set ptr",
   608  		src: `
   609  void foo() {
   610  	int* a;
   611  	int b;
   612  	*a++ = b;
   613  }
   614  `,
   615  		exp: `
   616  func foo() {
   617  	var (
   618  		a *int32
   619  		b int32
   620  	)
   621  	*func() *int32 {
   622  		p := &a
   623  		x := *p
   624  		*p = (*int32)(unsafe.Add(unsafe.Pointer(*p), unsafe.Sizeof(int32(0))*1))
   625  		return x
   626  	}() = b
   627  }
   628  `,
   629  	},
   630  	{
   631  		name: "ptr decr size",
   632  		src: `
   633  void foo() {
   634    int *ptr = 0;
   635    ptr -= 3;
   636  }
   637  `,
   638  		exp: `
   639  func foo() {
   640  	var ptr *int32 = nil
   641  	ptr = (*int32)(unsafe.Add(unsafe.Pointer(ptr), -int(unsafe.Sizeof(int32(0))*3)))
   642  }
   643  `,
   644  	},
   645  	{
   646  		name: "negative ptr",
   647  		src: `
   648  void foo() {
   649  	const char* a;
   650  	a = -1;
   651  	a = -2;
   652  	if (a == (const char*)-1) {
   653  		return;
   654  	}
   655  }
   656  `,
   657  		exp: `
   658  func foo() {
   659  	var a *byte
   660  	a = (*byte)(unsafe.Pointer(uintptr(math.MaxUint32)))
   661  	a = (*byte)(unsafe.Pointer(uintptr(0xFFFFFFFE)))
   662  	if uintptr(unsafe.Pointer(a)) == uintptr(math.MaxUint32) {
   663  		return
   664  	}
   665  }
   666  `,
   667  	},
   668  	{
   669  		name: "negative void ptr",
   670  		src: `
   671  void foo() {
   672  	void* a;
   673  	a = -1;
   674  	a = (void*)-1;
   675  	a = -2;
   676  	if (a == -1) {
   677  		return;
   678  	}
   679  }
   680  `,
   681  		exp: `
   682  func foo() {
   683  	var a unsafe.Pointer
   684  	a = unsafe.Pointer(uintptr(math.MaxUint32))
   685  	a = unsafe.Pointer(uintptr(math.MaxUint32))
   686  	a = unsafe.Pointer(uintptr(0xFFFFFFFE))
   687  	if uintptr(a) == uintptr(math.MaxUint32) {
   688  		return
   689  	}
   690  }
   691  `,
   692  	},
   693  	{
   694  		name: "return zero ptr",
   695  		src: `
   696  int* foo() {
   697  	return 0;
   698  }
   699  `,
   700  		exp: `
   701  func foo() *int32 {
   702  	return nil
   703  }
   704  `,
   705  	},
   706  	{
   707  		name: "return zero ptr named",
   708  		inc:  `typedef int my_size_t;`,
   709  		src: `
   710  my_size_t* foo() {
   711  	return 0;
   712  }
   713  `,
   714  		exp: `
   715  func foo() *my_size_t {
   716  	return nil
   717  }
   718  `,
   719  	},
   720  	{
   721  		name: "compare unsafe pointers",
   722  		src: `
   723  void foo(void* a, void* b) {
   724  	if (a < b) return;
   725  }
   726  `,
   727  		exp: `
   728  func foo(a unsafe.Pointer, b unsafe.Pointer) {
   729  	if uintptr(a) < uintptr(b) {
   730  		return
   731  	}
   732  }
   733  `,
   734  	},
   735  	{
   736  		name: "compare pointers",
   737  		src: `
   738  void foo(int* a, int* b) {
   739  	if (a < b) return;
   740  }
   741  `,
   742  		exp: `
   743  func foo(a *int32, b *int32) {
   744  	if uintptr(unsafe.Pointer(a)) < uintptr(unsafe.Pointer(b)) {
   745  		return
   746  	}
   747  }
   748  `,
   749  	},
   750  	{
   751  		name: "compare diff pointers",
   752  		src: `
   753  void foo(int* a, void* b) {
   754  	if (a < b) return;
   755  }
   756  `,
   757  		exp: `
   758  func foo(a *int32, b unsafe.Pointer) {
   759  	if uintptr(unsafe.Pointer(a)) < uintptr(b) {
   760  		return
   761  	}
   762  }
   763  `,
   764  	},
   765  	{
   766  		name: "equal unsafe pointers",
   767  		src: `
   768  void foo(void* a, void* b) {
   769  	if (a == b) return;
   770  }
   771  `,
   772  		exp: `
   773  func foo(a unsafe.Pointer, b unsafe.Pointer) {
   774  	if a == b {
   775  		return
   776  	}
   777  }
   778  `,
   779  	},
   780  	{
   781  		name: "equal pointers",
   782  		src: `
   783  void foo(int* a, int* b) {
   784  	if (a == b) return;
   785  }
   786  `,
   787  		exp: `
   788  func foo(a *int32, b *int32) {
   789  	if a == b {
   790  		return
   791  	}
   792  }
   793  `,
   794  	},
   795  	{
   796  		name: "equal diff pointers",
   797  		src: `
   798  void foo(int* a, void* b) {
   799  	if (a == b) return;
   800  }
   801  `,
   802  		exp: `
   803  func foo(a *int32, b unsafe.Pointer) {
   804  	if unsafe.Pointer(a) == b {
   805  		return
   806  	}
   807  }
   808  `,
   809  	},
   810  	{
   811  		name: "equal pointer and const",
   812  		src: `
   813  void foo(int* a, void* b) {
   814  	if (a == 1 && b == 1) return;
   815  }
   816  `,
   817  		exp: `
   818  func foo(a *int32, b unsafe.Pointer) {
   819  	if uintptr(unsafe.Pointer(a)) == uintptr(1) && uintptr(b) == uintptr(1) {
   820  		return
   821  	}
   822  }
   823  `,
   824  	},
   825  	{
   826  		name: "diff pointers",
   827  		src: `
   828  #include <stddef.h>
   829  void foo(int* a, int* b) {
   830  	int c = a - b;
   831  }
   832  `,
   833  		exp: `
   834  func foo(a *int32, b *int32) {
   835  	var c int32 = int32(uintptr(unsafe.Pointer(a)) - uintptr(unsafe.Pointer(b)))
   836  	_ = c
   837  }
   838  `,
   839  	},
   840  	{
   841  		name: "array ptr equal",
   842  		src: `
   843  void foo() {
   844  	int a[10];
   845  	if (a == 0x1000) {
   846  		return;
   847  	}
   848  }
   849  `,
   850  		exp: `
   851  func foo() {
   852  	var a [10]int32
   853  	if uintptr(unsafe.Pointer(&a[0])) == uintptr(4096) {
   854  		return
   855  	}
   856  }
   857  `,
   858  	},
   859  	{
   860  		name: "equal func",
   861  		src: `
   862  void foo() {
   863  	void(*a)(void);
   864  	if (a == foo) {
   865  		return;
   866  	}
   867  }
   868  `,
   869  		exp: `
   870  func foo() {
   871  	var a func()
   872  	if libc.FuncAddr(a) == libc.FuncAddr(foo) {
   873  		return
   874  	}
   875  }
   876  `,
   877  	},
   878  	{
   879  		name: "array reinterpret",
   880  		inc:  `unsigned char bytes[124];`,
   881  		src: `
   882  void foo() {
   883  	unsigned char* a;
   884  	a = *(unsigned char**)& bytes[4];
   885  }
   886  `,
   887  		exp: `
   888  func foo() {
   889  	var a *uint8
   890  	_ = a
   891  	a = *(**uint8)(unsafe.Pointer(&bytes[4]))
   892  }
   893  `,
   894  	},
   895  	{
   896  		name: "malloc and free",
   897  		src: `
   898  #include <stdlib.h>
   899  void foo() {
   900  	void* a;
   901  	a = malloc(124);
   902  	free(a);
   903  }
   904  `,
   905  		exp: `
   906  func foo() {
   907  	var a unsafe.Pointer
   908  	_ = a
   909  	a = libc.Malloc(124)
   910  	a = nil
   911  }
   912  `,
   913  	},
   914  	{
   915  		name: "malloc sizeof",
   916  		src: `
   917  #include <stdlib.h>
   918  void foo() {
   919  	int* a = malloc(sizeof(int));
   920  }
   921  `,
   922  		exp: `
   923  func foo() {
   924  	var a *int32 = new(int32)
   925  	_ = a
   926  }
   927  `,
   928  	},
   929  	{
   930  		name: "memset sizeof",
   931  		src: `
   932  #include <stdlib.h>
   933  void foo(int* a) {
   934  	memset(a, 0, sizeof(int));
   935  }
   936  `,
   937  		exp: `
   938  func foo(a *int32) {
   939  	*a = 0
   940  }
   941  `,
   942  	},
   943  	{
   944  		skip: true, // TODO
   945  		name: "memset slice",
   946  		src: `
   947  #include <stdlib.h>
   948  void foo(int* a) {
   949  	memset(a, 0, 10*sizeof(int));
   950  }
   951  `,
   952  		exp: `
   953  func foo(a []int32) {
   954  	copy(a[:10], make([]int32, 10))
   955  }
   956  `,
   957  		configFuncs: []configFunc{
   958  			withIdentField("foo", IdentConfig{Name: "a", Type: HintSlice}),
   959  		},
   960  	},
   961  	{
   962  		name: "memset sizeof struct",
   963  		src: `
   964  #include <stdlib.h>
   965  
   966  typedef struct {
   967  	int x;
   968  } A;
   969  
   970  void foo(A* a) {
   971  	memset(a, 0, sizeof(A));
   972  }
   973  `,
   974  		exp: `
   975  type A struct {
   976  	X int32
   977  }
   978  
   979  func foo(a *A) {
   980  	*a = A{}
   981  }
   982  `,
   983  	},
   984  	{
   985  		name: "array ptr assign",
   986  		src: `
   987  void foo() {
   988  	char bytes[10];
   989  	*(void**)& bytes[1] = &bytes[2];
   990  }
   991  `,
   992  		exp: `
   993  func foo() {
   994  	var bytes [10]byte
   995  	*(*unsafe.Pointer)(unsafe.Pointer(&bytes[1])) = unsafe.Pointer(&bytes[2])
   996  }
   997  `,
   998  	},
   999  	{
  1000  		name: "addr of field",
  1001  		src: `
  1002  typedef struct {
  1003  	int field;
  1004  } A;
  1005  
  1006  void foo() {
  1007  	A a;
  1008  	int* b;
  1009  	b = &a.field;
  1010  }
  1011  `,
  1012  		exp: `
  1013  type A struct {
  1014  	Field int32
  1015  }
  1016  
  1017  func foo() {
  1018  	var (
  1019  		a A
  1020  		b *int32
  1021  	)
  1022  	_ = b
  1023  	b = &a.Field
  1024  }
  1025  `,
  1026  	},
  1027  	{
  1028  		name: "implicit 0 field ptr",
  1029  		src: `
  1030  typedef struct {
  1031  	int x;
  1032  } A;
  1033  typedef struct {
  1034  	A a;
  1035  	A b;
  1036  } B;
  1037  
  1038  void bar(A* arg) {
  1039  	int x = arg->x;
  1040  }
  1041  
  1042  void foo(B* arg) {
  1043  	bar(arg);
  1044  }
  1045  `,
  1046  		exp: `
  1047  type A struct {
  1048  	X int32
  1049  }
  1050  type B struct {
  1051  	A A
  1052  	B A
  1053  }
  1054  
  1055  func bar(arg *A) {
  1056  	var x int32 = arg.X
  1057  	_ = x
  1058  }
  1059  func foo(arg *B) {
  1060  	bar(&arg.A)
  1061  }
  1062  `,
  1063  	},
  1064  	{
  1065  		name: "implicit array access",
  1066  		src: `
  1067  struct s {
  1068      int i;
  1069  };
  1070  
  1071  struct s ss[] = {
  1072      {0},
  1073  };
  1074  
  1075  
  1076  void foo() {
  1077      int i = ss->i;
  1078  }
  1079  `,
  1080  		exp: `
  1081  type s struct {
  1082  	I int32
  1083  }
  1084  
  1085  var ss [1]s = [1]s{}
  1086  
  1087  func foo() {
  1088  	var i int32 = ss[0].I
  1089  	_ = i
  1090  }
  1091  `,
  1092  	},
  1093  	{
  1094  		name: "named ptr call",
  1095  		src: `
  1096  typedef int H;
  1097  typedef struct F {} F;
  1098  void foo(F* a);
  1099  void bar(void) {
  1100  	H a;
  1101  	foo(((F*)a));
  1102  }
  1103  `,
  1104  		exp: `
  1105  type H int32
  1106  type F struct {
  1107  }
  1108  
  1109  func foo(a *F)
  1110  func bar() {
  1111  	var a H
  1112  	foo((*F)(unsafe.Pointer(uintptr(a))))
  1113  }
  1114  `,
  1115  	},
  1116  	{
  1117  		name: "sizeof int conv",
  1118  		src: `
  1119  #include <stddef.h>
  1120  
  1121  typedef struct {
  1122  	int x;
  1123  } A;
  1124  
  1125  void foo () {
  1126  	int x = sizeof(A);
  1127  }
  1128  `,
  1129  		exp: `
  1130  type A struct {
  1131  	X int32
  1132  }
  1133  
  1134  func foo() {
  1135  	var x int32 = int32(unsafe.Sizeof(A{}))
  1136  	_ = x
  1137  }
  1138  `,
  1139  	},
  1140  	{
  1141  		name: "ptr add size mult",
  1142  		src: `
  1143  #include <stddef.h>
  1144  
  1145  typedef struct {
  1146  	int x;
  1147  	int y;
  1148  } A;
  1149  
  1150  void foo() {
  1151  	int* ptr;
  1152  	ptr += 20 * (sizeof(A)/2);
  1153  }
  1154  `,
  1155  		exp: `
  1156  
  1157  type A struct {
  1158  	X int32
  1159  	Y int32
  1160  }
  1161  
  1162  func foo() {
  1163  	var ptr *int32
  1164  	ptr = (*int32)(unsafe.Add(unsafe.Pointer(ptr), unsafe.Sizeof(int32(0))*(20*(unsafe.Sizeof(A{})/2))))
  1165  }
  1166  `,
  1167  	},
  1168  	{
  1169  		skip: true, // TODO
  1170  		name: "ptr compare out of bounds",
  1171  		src: `
  1172  void foo() {
  1173  	void* p;
  1174  	int arr[9];
  1175  	if (p > &arr[9]) {
  1176  		foo();
  1177  	}
  1178  }
  1179  `,
  1180  		exp: `
  1181  func foo() {
  1182  	var (
  1183  		p   unsafe.Pointer
  1184  		arr [9]int32
  1185  	)
  1186  	if uintptr(unsafe.Pointer(p)) - uintptr(unsafe.Pointer(&arr)) > unsafe.Sizeof(int32(0))*9 {
  1187  		foo()
  1188  	}
  1189  }
  1190  `,
  1191  	},
  1192  	{
  1193  		name: "pointer to first elem",
  1194  		src: `
  1195  void foo() {
  1196  	char b[10];
  1197  	char* p;
  1198  	p = b;
  1199  	p = &b;
  1200  	p = &b[0];
  1201  }
  1202  `,
  1203  		exp: `
  1204  func foo() {
  1205  	var (
  1206  		b [10]byte
  1207  		p *byte
  1208  	)
  1209  	_ = p
  1210  	p = &b[0]
  1211  	p = &b[0]
  1212  	p = &b[0]
  1213  }
  1214  `,
  1215  	},
  1216  	{
  1217  		name: "slice override global",
  1218  		src: `
  1219  int* foo;
  1220  `,
  1221  		exp: `
  1222  var foo []int32
  1223  `,
  1224  		configFuncs: []configFunc{
  1225  			withIdent(IdentConfig{
  1226  				Name: "foo",
  1227  				Type: HintSlice,
  1228  			}),
  1229  		},
  1230  	},
  1231  	{
  1232  		name: "slice override func arg",
  1233  		src: `
  1234  void foo(int* a);
  1235  void bar(int* b){
  1236  }
  1237  `,
  1238  		exp: `
  1239  func foo(a []int32)
  1240  func bar(b []int32) {
  1241  }
  1242  `,
  1243  		configFuncs: []configFunc{
  1244  			withIdentField("foo", IdentConfig{Name: "a", Type: HintSlice}),
  1245  			withIdentField("bar", IdentConfig{Name: "b", Type: HintSlice}),
  1246  		},
  1247  	},
  1248  	{
  1249  		name: "slice override struct field",
  1250  		src: `
  1251  typedef struct{
  1252  	int* a
  1253  } foo;
  1254  
  1255  typedef struct bar {
  1256  	int* b
  1257  } bar;
  1258  
  1259  struct baz {
  1260  	int* c
  1261  };
  1262  `,
  1263  		exp: `
  1264  type foo struct {
  1265  	A []int32
  1266  }
  1267  type bar struct {
  1268  	B []int32
  1269  }
  1270  type baz struct {
  1271  	C []int32
  1272  }
  1273  `,
  1274  		configFuncs: []configFunc{
  1275  			withIdentField("foo", IdentConfig{Name: "a", Type: HintSlice}),
  1276  			withIdentField("bar", IdentConfig{Name: "b", Type: HintSlice}),
  1277  			withIdentField("baz", IdentConfig{Name: "c", Type: HintSlice}),
  1278  		},
  1279  	},
  1280  	{
  1281  		name: "slice and ptr",
  1282  		src: `
  1283  void foo(int* a, int* b, int c) {
  1284  	a = b;
  1285  	b = a;
  1286  	c = *a;
  1287  	c = a[1];
  1288  	if (a != 0) {
  1289  		a = 0;
  1290  	}
  1291  }
  1292  `,
  1293  		exp: `
  1294  func foo(a []int32, b *int32, c int32) {
  1295  	a = []int32(b)
  1296  	b = &a[0]
  1297  	c = a[0]
  1298  	c = a[1]
  1299  	if a != nil {
  1300  		a = nil
  1301  	}
  1302  }
  1303  `,
  1304  		configFuncs: []configFunc{
  1305  			withIdentField("foo", IdentConfig{Name: "a", Type: HintSlice}),
  1306  		},
  1307  	},
  1308  	{
  1309  		name: "slice calloc",
  1310  		src: `
  1311  #include <stdlib.h>
  1312  
  1313  int n;
  1314  int* a = calloc(n, sizeof(int));
  1315  int* b = (int*)calloc(n, sizeof(int));
  1316  int* c = (int*)calloc(n, sizeof(int));
  1317  `,
  1318  		exp: `
  1319  var n int32
  1320  var a []int32 = make([]int32, int(n))
  1321  var b []int32 = make([]int32, int(n))
  1322  var c *int32 = &make([]int32, int(n))[0]
  1323  `,
  1324  		configFuncs: []configFunc{
  1325  			withIdent(IdentConfig{Name: "a", Type: HintSlice}),
  1326  			withIdent(IdentConfig{Name: "b", Type: HintSlice}),
  1327  		},
  1328  	},
  1329  	{
  1330  		name: "slice safe calloc",
  1331  		src: `
  1332  #include <stdlib.h>
  1333  
  1334  void foo(int* a, int n) {
  1335  	if ((a = (int*)calloc(n, sizeof(int))) != 0) {
  1336  		a = 0;
  1337  	}
  1338  }
  1339  `,
  1340  		exp: `
  1341  func foo(a []int32, n int32) {
  1342  	if (func() []int32 {
  1343  		a = make([]int32, int(n))
  1344  		return a
  1345  	}()) != nil {
  1346  		a = nil
  1347  	}
  1348  }
  1349  `,
  1350  		configFuncs: []configFunc{
  1351  			withIdentField("foo", IdentConfig{Name: "a", Type: HintSlice}),
  1352  		},
  1353  	},
  1354  	{
  1355  		name: "slice index",
  1356  		src: `
  1357  typedef struct {
  1358  	int* ptr
  1359  } A;
  1360  
  1361  void foo(A x, int y) {
  1362  	y = *x.ptr;
  1363  	y = x.ptr[1];
  1364  	y = *(x.ptr + 1);
  1365  	y = *(x.ptr + 2*y + 1);
  1366  	y = *(&(x.ptr + 2*y + 1)[y]);
  1367  }
  1368  `,
  1369  		exp: `
  1370  type A struct {
  1371  	Ptr []int32
  1372  }
  1373  
  1374  func foo(x A, y int32) {
  1375  	y = x.Ptr[0]
  1376  	y = x.Ptr[1]
  1377  	y = x.Ptr[1]
  1378  	y = x.Ptr[y*2+1]
  1379  	y = x.Ptr[y*2+1+y]
  1380  }
  1381  `,
  1382  		configFuncs: []configFunc{
  1383  			withIdentField("A", IdentConfig{Name: "ptr", Type: HintSlice}),
  1384  		},
  1385  	},
  1386  	{
  1387  		name: "slice to bytes",
  1388  		src: `
  1389  void foo(unsigned char* x) {
  1390  }
  1391  void foo2(char* x) {
  1392  	foo(x);
  1393  }
  1394  `,
  1395  		exp: `
  1396  func foo(x []byte) {
  1397  }
  1398  func foo2(x string) {
  1399  	foo([]byte(x))
  1400  }
  1401  `,
  1402  		configFuncs: []configFunc{
  1403  			withIdentField("foo", IdentConfig{Name: "x", Type: HintSlice}),
  1404  			withIdentField("foo2", IdentConfig{Name: "x", Type: HintString}),
  1405  		},
  1406  	},
  1407  	{
  1408  		name:     "slice def index",
  1409  		builtins: true,
  1410  		src: `
  1411  typedef struct {
  1412  	_cxgo_go_slice_t(int) ptr
  1413  } A;
  1414  
  1415  void foo(A x, int y) {
  1416  	y = *x.ptr;
  1417  	y = x.ptr[1];
  1418  	y = *(x.ptr + 1);
  1419  	y = *(x.ptr + 2*y + 1);
  1420  	y = *(&(x.ptr + 2*y + 1)[y]);
  1421  }
  1422  `,
  1423  		exp: `
  1424  type A struct {
  1425  	Ptr []int32
  1426  }
  1427  
  1428  func foo(x A, y int32) {
  1429  	y = x.Ptr[0]
  1430  	y = x.Ptr[1]
  1431  	y = x.Ptr[1]
  1432  	y = x.Ptr[y*2+1]
  1433  	y = x.Ptr[y*2+1+y]
  1434  }
  1435  `,
  1436  	},
  1437  	{
  1438  		name:     "slice def ops",
  1439  		builtins: true,
  1440  		src: `
  1441  void foo(int y) {
  1442  	_cxgo_go_slice_t(int) arr;
  1443  	arr = 0;
  1444  	arr = _cxgo_go_make(_cxgo_go_slice_t(int), 1);
  1445  	arr = _cxgo_go_make(_cxgo_go_slice_t(int), 1, 2);
  1446  	arr = _cxgo_go_make_same(arr, 3, 4);
  1447  	y = _cxgo_go_len(arr);
  1448  	y = _cxgo_go_cap(arr);
  1449  	arr = _cxgo_go_slice(arr, -1, -1);
  1450  	arr = _cxgo_go_slice(arr, -1, 2);
  1451  	arr = _cxgo_go_slice(arr, 1, -1);
  1452  	arr = _cxgo_go_slice(arr, 1, 2);
  1453  	arr = _cxgo_go_slice(arr, -1, -1, -1);
  1454  	arr = _cxgo_go_slice(arr, -1, 2, 3);
  1455  	arr = _cxgo_go_slice(arr, 1, 2, 3);
  1456  	arr = _cxgo_go_append(arr, 1);
  1457  	arr = _cxgo_go_append(arr, 1, 2);
  1458  	arr = _cxgo_go_append(arr, arr);
  1459  }
  1460  `,
  1461  		exp: `
  1462  func foo(y int32) {
  1463  	var arr []int32
  1464  	arr = nil
  1465  	arr = make([]int32, 1)
  1466  	arr = make([]int32, 1, 2)
  1467  	arr = make([]int32, 3, 4)
  1468  	y = int32(len(arr))
  1469  	y = int32(cap(arr))
  1470  	arr = arr[:]
  1471  	arr = arr[:2]
  1472  	arr = arr[1:]
  1473  	arr = arr[1:2]
  1474  	arr = arr[:]
  1475  	arr = arr[:2:3]
  1476  	arr = arr[1:2:3]
  1477  	arr = append(arr, 1)
  1478  	arr = append(arr, 1, 2)
  1479  	arr = append(arr, arr...)
  1480  }
  1481  `,
  1482  	},
  1483  }
  1484  
  1485  func TestPointers(t *testing.T) {
  1486  	runTestTranslate(t, casesTranslatePtrs)
  1487  }