Description
This issue was copied from checkedc/checkedc-clang#668
In checked-c ideally, we would want an assignment to function pointers to follow function subtyping rules.
i.e.,
T1 f;
T2 fptr = f;
Where fptr
is a function pointer of type T2
and f
is a function of type T1
.
The above assignment is valid iff T1 <: T2
according to function subtyping rules.
However, this is not the case.
More detailed example:
int * aptr(_Ptr<int> a, int *b);
int * bptr(int *a, _Ptr<int> b);
int* retptr(int *a, int *b): itype(_Ptr<int>);
int * abptr(_Ptr<int> a, _Ptr<int> b);
int main() {
// This is a function pointer to a function that
// accepts two checked pointers and return a
// wild pointer.
// i.e., all callers using this function pointer
// will pass checked pointers as the two arguments
// and treat the return value as WILD.
_Ptr<int* (_Ptr<int> , _Ptr<int> )> b = 0;
// This should be fine, because it only needs
// first argument as checked pointer.
// int* (_Ptr<int> , int* ) <: int* (_Ptr<int> , _Ptr<int> )
b = aptr;
// Similar to the above reasoning, this should be fine.
b = bptr;
// this is also fine because it expected no checked arguments
// but could return checked type as its return.
// int* (int*, int*) : itype(_Ptr<int>) <: int* (_Ptr<int> , _Ptr<int> )
b = retptr;
// this is the true match.
b = abptr;
return 0;
}
However, the current version of clang throws an error.
When we try to compile the above source file using checkedc-clang, we get the following error:
error: assigning to '_Ptr<int *(_Ptr<int>, _Ptr<int>)>' from incompatible type 'int *(_Ptr<int>, int *)': type mismatch at 2nd parameter ('_Ptr<int>' vs 'int *')
b = aptr;
^ ~~~~
funcptrbug.c:19:6: error: assigning to '_Ptr<int *(_Ptr<int>, _Ptr<int>)>' from incompatible type 'int *(int *, _Ptr<int>)': type mismatch at 1st parameter ('_Ptr<int>' vs 'int *')
b = bptr;
^ ~~~~
funcptrbug.c:23:6: error: assigning to '_Ptr<int *(_Ptr<int>, _Ptr<int>)>' from incompatible type 'int *(int *, int *) : itype(_Ptr<int>)': type mismatch at 1st parameter
('_Ptr<int>' vs 'int *')
b = retptr;
^ ~~~~~~
3 errors generated.
This seems to be consistent with the specification (Page 51, Section 3.8), i.e., function pointers types have to be an exact match, i.e., all the parameters and return types should have the same checked types.
I have the following concerns here:
- This is non-intuitive, should this be changed?
- Is there any rationale on not changing this?