Skip to content

FFI Incompatible types when assigning to type 'void(*)()' from type 'void(*)()' #9090

Closed
@adsr

Description

@adsr

Description

It appears we're unable to assign a function pointer via FFI:

$ cat ffibug.c 
#include <stdio.h>

void func() {
    printf("hello\n");
}

void (*func_ptr)() = NULL;

void call_func() {
    if (func_ptr != NULL) func_ptr();
}
$ gcc -shared -fPIC -o libffibug.so ffibug.c
$ php -v
PHP 8.2.0-dev (cli) (built: Jul 19 2022 20:25:19) (NTS DEBUG)
Copyright (c) The PHP Group
Zend Engine v4.2.0-dev, Copyright (c) Zend Technologies
$ php -a
Interactive shell

php > $ffi = FFI::cdef('void func(); void (*func_ptr)(); void call_func();', __DIR__ . '/libffibug.so');
php > $ffi->call_func();
php > $ffi->func_ptr = $ffi->func;

Warning: Uncaught FFI\Exception: Incompatible types when assigning to type 'void(*)()' from type 'void(*)()' in php shell code:1
Stack trace:
#0 {main}
  thrown in php shell code on line 1
php > 

The following patch seems to fix:

diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c
index cb82c3a3c3..3cd568826f 100644
--- a/ext/ffi/ffi.c
+++ b/ext/ffi/ffi.c
@@ -267,7 +267,8 @@ static bool zend_ffi_is_compatible_type(zend_ffi_type *dst_type, zend_ffi_type *
 				dst_type = ZEND_FFI_TYPE(dst_type->pointer.type);
 				src_type = ZEND_FFI_TYPE(src_type->pointer.type);
 				if (dst_type->kind == ZEND_FFI_TYPE_VOID ||
-				    src_type->kind == ZEND_FFI_TYPE_VOID) {
+				    src_type->kind == ZEND_FFI_TYPE_VOID ||
+				    src_type->kind == dst_type->kind) {
 				    return 1;
 				}
 			} else if (dst_type->kind == ZEND_FFI_TYPE_ARRAY &&
$ php -a
Interactive shell

php > $ffi = FFI::cdef('void func(); void (*func_ptr)(); void call_func();', __DIR__ . '/libffibug.so');
php > $ffi->call_func();
php > $ffi->func_ptr = $ffi->func;
php > $ffi->call_func();
hello
php > 
$ 

I'm not familiar with FFI internals so could use a review. FFI tests continue to pass at least. If it looks ok I can follow up with a PR + phpt.

PHP Version

HEAD

Operating System

Debian testing

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions