Opened 4 years ago

Closed 4 years ago

#19 closed defect (fixed)

Functions taking array types and taking pointer types are conflicting overloads

Reported by: Rob Schluntz Owned by: Rob Schluntz <rschlunt@…>
Priority: major Component: cfa-cc
Version: 1.0 Keywords: include conflicting overload extern C linkage
Cc:

Description

extern "C" {
    void fred(int __env[1]);
    void fred(int *__env);
}

cfa test3.c
CFA Version 1.0.0 (debug)
test3.c:3 error: conflicting overload of C function fred: C function
  with parameters
    __env: C pointer to signed int
  returning 
    _retval_fred:       Attribute with name: unused
void 

Change History (2)

comment:1 Changed 4 years ago by pabuhr

This is only true of the outermost layer though. If you add just one level, they cease to be equivalent, i.e., int ** is equivalent to int *[10], but not the same as int (*)[10] or int [10][10]). So you should be careful to only make the outermost array level mangle the same way as a pointer, if you go down this route.

And actually, we already do this transformation (but improperly mangle every such array type as a pointer):

$ cat test.c
void foo(int __env[1]);
void foo(int *__env);

void bar(int (*)[10]);
void bar(int *[10]);
void bar(int **);
void bar(int [10][10]);
$ cfa -CFA test.c
void __foo__F_Pi__1(int ____env__Pi_1[((long unsigned int )1)]);
void __foo__F_Pi__1(int *____env__Pi_1);

void __bar__F_PA0i__1(int (*__anonymous_object1657)[((long unsigned int )10)]); 
void __bar__F_PPi__1(int *__anonymous_object1658[((long unsigned int )10)]);
void __bar__F_PPi__1(int **__anonymous_object1659);
void __bar__F_PPi__1(int __anonymous_object1660[((long unsigned int )10)][((long unsigned int )10)]); // this one is wrong, should also be __bar__F_PA0i__1

It might be that it’s happening too late though. This transformation happens in FixFunction, which is called from EnumAndPointerDecay and ForallPointerDecay in Validate.cc, but LinkReferenceToTypes is an Indexer that is run before either of those.

As a side note, a while back I added recursion to the ArrayType cases in AdjustExprType and FixFunction to make this transformation happen deeply, because multiple subscript operators did not work on multi-dimensional arrays. I could be convinced that this was the wrong thing to do, and that instead, adjustExprType was not happening in all of the right places. An alternative would be to just make Mangler smarter about how it handles pointer types that are really array types (and likewise, make AdjustExprType and FixFunction recursive on PointerType).

The first bar is correctly mangled because FixFunction isn’t recursive on PointerType, but as such multiple subscripts do not work:

$ cat test.c
void fred(int (*x)[10]) { x[0][0]; }
$ cfa test.c
test.c:1 error: No reasonable alternatives for expression Applying untyped: 
  Name: ?[?]
...to: 
  Applying untyped: 
      Name: ?[?]
    ...to: 
      Name: x

      constant expression (0 0: zero_t)

  constant expression (0 0: zero_t)

comment:2 Changed 4 years ago by Rob Schluntz <rschlunt@…>

Owner: set to Rob Schluntz <rschlunt@…>
Resolution: fixed
Status: newclosed

In 8e0147a:

Reorder Validate passes so that array parameters are converted into pointers before the first Indexer pass [fixes #19]

Note: See TracTickets for help on using tickets.