Commit 9bea2f9
committed
XS: fix INTERFACE on strict C compilers
GH #23192
The INTERFACE keyword in XS allows the same XSUB to wrap multiple C
library functions, by storing a function pointer to the C function in
each CV.
This has started failing on some strict C compilers, as the C code
generated by the XS compiler does some suspect function pointer casts.
This commit fixes the issue by providing a more correct cast in most
cases (it still can't handle non-trivial C_ARGS values).
Background:
Before this commit, the presence of the INTERFACE keyword in this XSUB:
char*
foo(int a, int b, int c)
INTERFACE: bar baz
would cause these extra lines to be added to the XSUB's body:
dXSFUNCTION(char*);
XSFUNCTION = XSINTERFACE_FUNC(char*,cv,XSANY.any_dptr);
RETVAL = XSFUNCTION(a, b, c);
and lines like this to be added to the boot XSUB:
XSINTERFACE_FUNC_SET(cv,bar);
After macro expansion, these lines look roughly like the following:
char* (*XSFUNCTION)();
XSFUNCTION = (char* (*)()))(XSANY.any_dptr));
RETVAL = XSFUNCTION(a, b, c);
CvXSUBANY(cv).any_dxptr = (void (*) (pTHX_ void*))(bar);
The issue:
The specific error the C compiler is giving in the ticket is:
error: too many arguments to function ‘XSFUNCTION’
which is caused by this line:
RETVAL = XSFUNCTION(a, b, c);
because XSFUNCTION has been declared as a pointer to a function
which has no args, and is now being used as a pointer to a function
which takes args.
The fix:
This commit fixes this issue by adding adding a cast: but only to the
place where XSFUNCTION is used to call the function. The other places
are left untouched (so the XSFUNCTION variable itself still has the
"wrong" type). This has the advantage that the various dXSFUNCTION etc
macros in XSUB.h don't need to be modified, and so portability to older
Perls is less of an issue. It also means that INTERFACE_MACRO usage
should be unaffected.
After this commit, the code emitted to call XSFUNCTION now looks like:
RETVAL = ((char* (*)(int,int,int))(XSFUNCTION))(a, b, c);
This cast is generated based on the types of the XSUB's parameters and
return values.
Things are difficult in the presence of C_ARGS; for example,
char*
foo(int a, int b, int c)
INTERFACE: bar baz
C_ARGS: a, c
In this case, the XS parser now splits the C_ARGS line and looks up the
type of each corresponding parameter. If it can't be found, it uses
'void *' instead and hopes for the best.
For more complex C_ARGS entries such as
C_ARGS: foo(a), b+1
this doesn't work and it is likely that uncompilable C code will still
be generated,
This commit adds tests both to 001-basic.t (which just checks that the
generated C code looks as expected), but also to 002-more.t, which
actually compiles and executes the C code, and thus is more likely to
catch failures due to picky C compilers.1 parent c00171f commit 9bea2f9
File tree
4 files changed
+94
-20
lines changed- dist/ExtUtils-ParseXS
- lib/ExtUtils/ParseXS
- t
4 files changed
+94
-20
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2569 | 2569 | | |
2570 | 2570 | | |
2571 | 2571 | | |
2572 | | - | |
2573 | | - | |
| 2572 | + | |
| 2573 | + | |
| 2574 | + | |
| 2575 | + | |
| 2576 | + | |
2574 | 2577 | | |
2575 | 2578 | | |
2576 | 2579 | | |
2577 | 2580 | | |
2578 | 2581 | | |
2579 | 2582 | | |
| 2583 | + | |
2580 | 2584 | | |
2581 | 2585 | | |
2582 | 2586 | | |
| |||
2586 | 2590 | | |
2587 | 2591 | | |
2588 | 2592 | | |
| 2593 | + | |
2589 | 2594 | | |
2590 | 2595 | | |
2591 | 2596 | | |
| |||
2606 | 2611 | | |
2607 | 2612 | | |
2608 | 2613 | | |
| 2614 | + | |
| 2615 | + | |
2609 | 2616 | | |
2610 | 2617 | | |
2611 | | - | |
| 2618 | + | |
2612 | 2619 | | |
2613 | 2620 | | |
2614 | 2621 | | |
| |||
3325 | 3332 | | |
3326 | 3333 | | |
3327 | 3334 | | |
3328 | | - | |
| 3335 | + | |
| 3336 | + | |
3329 | 3337 | | |
3330 | 3338 | | |
3331 | 3339 | | |
| |||
3340 | 3348 | | |
3341 | 3349 | | |
3342 | 3350 | | |
3343 | | - | |
3344 | | - | |
3345 | | - | |
3346 | | - | |
| 3351 | + | |
| 3352 | + | |
| 3353 | + | |
| 3354 | + | |
| 3355 | + | |
| 3356 | + | |
| 3357 | + | |
| 3358 | + | |
| 3359 | + | |
| 3360 | + | |
| 3361 | + | |
| 3362 | + | |
| 3363 | + | |
| 3364 | + | |
| 3365 | + | |
| 3366 | + | |
| 3367 | + | |
| 3368 | + | |
| 3369 | + | |
| 3370 | + | |
| 3371 | + | |
| 3372 | + | |
| 3373 | + | |
| 3374 | + | |
| 3375 | + | |
| 3376 | + | |
| 3377 | + | |
| 3378 | + | |
| 3379 | + | |
3347 | 3380 | | |
3348 | 3381 | | |
3349 | 3382 | | |
| |||
3375 | 3408 | | |
3376 | 3409 | | |
3377 | 3410 | | |
3378 | | - | |
| 3411 | + | |
| 3412 | + | |
3379 | 3413 | | |
3380 | 3414 | | |
3381 | 3415 | | |
| |||
3404 | 3438 | | |
3405 | 3439 | | |
3406 | 3440 | | |
3407 | | - | |
3408 | | - | |
3409 | | - | |
| 3441 | + | |
| 3442 | + | |
| 3443 | + | |
| 3444 | + | |
| 3445 | + | |
| 3446 | + | |
| 3447 | + | |
3410 | 3448 | | |
3411 | 3449 | | |
3412 | 3450 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4811 | 4811 | | |
4812 | 4812 | | |
4813 | 4813 | | |
| 4814 | + | |
| 4815 | + | |
| 4816 | + | |
| 4817 | + | |
4814 | 4818 | | |
4815 | 4819 | | |
4816 | 4820 | | |
| |||
4825 | 4829 | | |
4826 | 4830 | | |
4827 | 4831 | | |
4828 | | - | |
| 4832 | + | |
4829 | 4833 | | |
4830 | 4834 | | |
4831 | 4835 | | |
4832 | 4836 | | |
4833 | 4837 | | |
4834 | | - | |
4835 | | - | |
4836 | | - | |
4837 | | - | |
4838 | 4838 | | |
4839 | | - | |
| 4839 | + | |
4840 | 4840 | | |
4841 | 4841 | | |
4842 | 4842 | | |
4843 | 4843 | | |
4844 | 4844 | | |
4845 | 4845 | | |
4846 | | - | |
| 4846 | + | |
| 4847 | + | |
| 4848 | + | |
| 4849 | + | |
| 4850 | + | |
| 4851 | + | |
| 4852 | + | |
| 4853 | + | |
| 4854 | + | |
| 4855 | + | |
| 4856 | + | |
| 4857 | + | |
| 4858 | + | |
| 4859 | + | |
| 4860 | + | |
| 4861 | + | |
4847 | 4862 | | |
4848 | 4863 | | |
4849 | 4864 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
116 | 119 | | |
117 | 120 | | |
118 | 121 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
81 | 90 | | |
82 | 91 | | |
83 | 92 | | |
| |||
244 | 253 | | |
245 | 254 | | |
246 | 255 | | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
247 | 265 | | |
248 | 266 | | |
249 | 267 | | |
| |||
0 commit comments