Allow comparison of expressions of function type with function pointers.

This affects equality comparisons where one side has function type (e.g. *function_pointer) and the other side has function pointer type (pointing to a compatible function type) or is a null pointer constant. These should be permitted, because the function type is converted to a function pointer type in this context. ORCA/C could report a spurious error for such comparisons, because it was not always performing those conversions.

(ORCA/C would treat function names as having function pointer type for these purposes, since for those the type conversion is performed elsewhere.)

Here is an example showing several expressions that gave spurious errors:

void f(void) {}
void (*fp)(void);
int main(void) {
        *fp == f;
        *fp == 0;
        *fp == (void *)0;
}
This commit is contained in:
Stephen Heumann committed 2026-02-06 23:10:21 -06:00
1 parent bdb8f3cf2b
commit b0e10d2e80
2 files changed
+7 -7

No files matched your search

+5 -7
View File
@@ -3788,13 +3788,11 @@ var
{ equality - is this for an (in)equality comparison? }
begin {CompareCompatible}
if (t1^.kind = functionType) or (t2^.kind = functionType) then begin
if not CompTypes(t1, t2) then
Error(47)
else if not looseTypeChecks and not equality then
Error(47);
end {if}
else if t1^.kind in [pointerType,arrayType] then begin
if t1^.kind = functionType then
t1 := MakePointerTo(t1);
if t2^.kind = functionType then
t2 := MakePointerTo(t2);
if t1^.kind in [pointerType,arrayType] then begin
if t2^.kind in [pointerType,arrayType] then begin
if CompTypes(t1^.ptype, t2^.ptype) then begin
if not looseTypeChecks and not equality then
+2
View File
@@ -250,3 +250,5 @@ will have the type const void *, rather than void *. This avoids the previous s
6. In certain circumstances where the value of a 16-bit signed integer variable was converted to a wider type following an earlier access to the 16-bit variable, negative values might not be converted correctly if native code peephole optimizations and register optimizations were both enabled.
7. Division or remainder operations with constant operands might be evaluated incorrectly if one operand was a negative integer and the other had an unsigned type, because the usual arithmetic conversions were not applied properly.
8. A spurious error would be reported for certain comparisons involving expressions of function type, e.g. *function_pointer == function_name.