-
Notifications
You must be signed in to change notification settings - Fork 577
The CommonMark module cannot be built using gcc 15 and perl 5.40.1 #23192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This looks like it's caused by a combination of gcc-15 and the |
Can someone who has access to |
In C23, the meaning of an empty function prototype has changed. It used to mean "unspecified number of arguments", but it has now changed to "no arguments". Fixes Perl#23192
GCC 15 hasn't been released yet. But anyway, this issue is because GCC 15 bumped the default C standard version to C23, and in C23 the meaning of an empty prototype has changed. |
In the presence of the INTERFACE keyword (which allows the same XSUB to
wrap multiple C functions by storing a pointer to the C function in every
CV associated with that XSUB), the C code generated by the XS parser
relies on the XSINTERFACE_CVT macro to declare a function pointer variable.
In XSUB.h, this macro is defined as:
#ifdef __cplusplus
# define XSINTERFACE_CVT(ret,name) ret (*name)(...)
#else
# define XSINTERFACE_CVT(ret,name) ret (*name)()
#endif
Presumably gcc-15 is complaining about a pointer to a function which
has non-zero number of args begin declared as
some_type (*my_function_ptr_var)()
Is there a portable way in C to tell the compiler not to complain about
this, or so we need to make the generated C code in some way include
the function arg types?
…--
"I used to be with it, but then they changed what ‘it’ was, and now what
I’m with isn’t it. And what’s ‘it’ seems weird and scary to me."
-- Grandpa Simpson
(It will happen to you too.)
|
(Moving this discussion back onto problem ticket, rather than PR #23194)
Leon wrote:
I'm not sure this fix is right (I have to dig deeper for that), but I am
very sure that the implementation of the `INTERFACE` feature is rather
broken and should probably be fixed.
xsubpp knows the types of the arguments of the function, it should be able
to cast to the right type without needing this silly macro.
It's complicated by the fact that there is also the
INTERFACE_MACRO:
XS keyword, which allows code to specify their own macros to replace the
default XSINTERFACE_FUNC and XSINTERFACE_FUNC_SET macros. I'm not sure
it would be possible to change things in a back-compat way for code which
defines its own macros.
On the other hand, the INTERFACE_MACRO appears to be almost completely
unused on CPAN: just two distros, MIME-Fast and Wx. Compared with
16(*) CPAN distros which use the INTERFACE: keyword. So perhaps breaking the
former is acceptable?
In any event, I currently have a WIP branch which has over 100 commits and
which almost completely rewrites the XS parser, and which I planned to
merge post-5.42.0 release. It would be (I imagine) a royal pain to fix
INTERFACE in blead and *then* rebase my branch over that.
On the other hand, it would be nice to get some sort of basic fix into the
5.42.0 release. Presumably over the next 2 years, gcc-15 is going to become
mainstream, and then 5.42.0 will start breaking on XS modules with
INTERFACE.
Could the proposed '...' fix or similar to XSUB.h be used now as a
stop-gap measure, then I'd fix INTERFACE properly post 5.42.0???
…--
But Pity stayed his hand. "It's a pity I've run out of bullets",
he thought. -- "Bored of the Rings"
|
That's not a good fix either, becaus vararg argument passing is not guaranteed to be the same as non-vararg argument passing. Most notably it isn't on Apple on ARM. |
Just MIME::Fast, it's commented out (with |
MIME::Fast looks to me like it needs to use PREFIX instead. But also, it hasn't been updated in 20+ years (and gnome certainly hasn't been standing still in that period), and no passing entries are known on CPAN Testers. I think we can assume it's dead. |
Yeah I don't think it was possible to write a sensible Though I'm still not quite sure when someone would ever need this feature. |
On Mon, Apr 14, 2025 at 05:12:09AM -0700, Leon Timmermans wrote:
Leont left a comment (Perl/perl5#23192)
> Could the proposed '...' fix or similar to XSUB.h be used now as a
stop-gap measure, then I'd fix INTERFACE properly post 5.42.0???
That's not a good fix either, becaus vararg argument passing is not
guaranteed to be the same as non-vararg argument passing. Most notably
it isn't on Apple on ARM.
Thinking some more: C_ARGS is going to be a problem. For example, with:
foo(int a, char *b)
INTERFACE: ......
C_ARGS: munge(b), a, FOO_SOME_FLAG
C_ARGS is just an uninterpreted string which is used as-is to generate the
call to the real C function. We have no idea what munge returns, or
whether FOO_SOME_FLAG is a int or pointer or whatever. We can't even know
the number of args: for example, munge() might be a macro which expands to
"b, strlen(b)".
So in general, the XS parser can't know the signature of the C function.
Unless there is some new C feature I don't know about which provides that
info? A sort of __FUNCTION_SIGNATURE__(some_function_name)??
We leads me to wonder: is there a viable fallback position for an
INTERFACE XSUB which also contains C_ARGS? Such as a pragma which turns
off arg checking? But if so, couldn't we just use that always?
Just out of curiosity, does any C expert one know how detailed the
function pointer declaration has to be? For example, could we just declare
all args as 'void *' or something like that? (Note: my C knowledge is
basically K&R, albeit updated with the newfangled ANSI way of declaring a
function's parameters. I don't understand all this fancy C99 and later
stuff.)
…--
This email is confidential, and now that you have read it you are legally
obliged to shoot yourself. Or shoot a lawyer, if you prefer. If you have
received this email in error, place it in its original wrapping and return
for a full refund. By opening this email, you accept that Elvis lives.
|
That is a good point. Yeah that will be hairy.
C23 actually has a
Absolutely not. In the original version of C all arguments were word sized so none of this mattered, but that has long stopped being the case. |
Perhaps instead of doing this weird function-pointer-hidden-in-CV voodoo, we could generate a separate XSUB for each function listed in INTERFACE? So basically, this:
would be equivalent to this:
(and remove INTERFACE_MACRO) |
We could do this conditionally, I created a proof of concept: #23200 (It breaks INTERFACE_MACRO) |
I suspect they were actively trying to avoid doing that (to have less code), but that does sound simple and sane. |
On Tue, Apr 15, 2025 at 12:25:05PM -0700, Leon Timmermans wrote:
Leont left a comment (Perl/perl5#23192)
> Perhaps instead of doing this weird function-pointer-hidden-in-CV voodoo, we could generate a separate XSUB for each function listed in INTERFACE?
I suspect they were actively trying to avoid doing that (to have less code), but that does sound simple and sane.
Unfortunately, generating multiple similar XSUBs from the same XSUB
declaration is almost impossible at the moment, since the current XS
parser emits code as it parses, and then immediately discards any unneeded
state. My (almost finished) rewrite of ParseXS.pm to build a per-XSUB AST
and *then* emit all the C code in one go, would make it easier.
Another approach would be to implement the INTERFACE keyword like ALIAS
is currently implemented: so instead of storing a function pointer in all
the CVs which point to the same XSUB, store an integer. Then instead
of generating an autocall line like:
dXSFUNCTION;
XSFUNCTION = [ extract the fn pointer from CvXSUBANY(cv).any_dptr ];
RETVAL = XSFUNCTION(... args ...);
generate the following:
switch (CvXSUBANY(cv).any_i32) {
case 0: RETVAL = foo(... args ...);
case 1: RETVAL = bar(... args ...);
case 2: RETVAL = baz(... args ...);
}
Slightly slower than directly calling a function pointer, but a lot
smaller than creating a separate XSUB for each interface name. And easy to
implement. I'm not sure whether the parser should just error out in the
presence of INTERFACE_MACRO, or still honour it (knowing that the
generated C code might fails to compile now).
In any case, I'm assuming anything we do to fix this will have to done
post-5.42.0.
…--
No man treats a motor car as foolishly as he treats another human being.
When the car will not go, he does not attribute its annoying behaviour to
sin, he does not say, You are a wicked motorcar, and I shall not give you
any more petrol until you go. He attempts to find out what is wrong and
set it right.
-- Bertrand Russell,
Has Religion Made Useful Contributions to Civilization?
|
Yeah, that seems wiser than rushing a solution to a problem that's caused by a change outside of our power. |
Speaking with my PSC hat on, we consider this a release blocker… for 5.44. This really needs solved but we don’t foresee the solution to be simple enough to still get into 5.42 at this late stage in the release cycle. |
As a workaround, can this problem be overcome by adding |
But should we do that, or should CommonMark do that? |
Or .... should the user attend to that ? I don't know. I was wondering what advice we would offer to someone who wants to install CommonMark-0.310100 on a perl that has been built using gcc-15, and c23. I've meddled around a bit and found that if ccflags already specifies something less than c23 (as is currently the usual case on Windows), then CommonMark builds fine. And if, on my gcc-15 build (on Windows), I remove
Nothing remarkable about that, either. (I presume I could alternatively tweak CCFLAGS at that command line, but IIRC that gets a bit messy in the cmd.exe shell.) Is that "manual" build the type of approach we would recommend for the time being ? Should the current blead test suite expose this issue (FAIL or TODO ?) when it is present ? I presently have gcc-15 on Windows 11 only. |
On Fri, Apr 25, 2025 at 10:11:08PM -0700, sisyphus wrote:
I've meddled around a bit and found that if ccflags already specifies
something less than c23 (as is currently the usual case on Windows),
then CommonMark builds fine.
So if standard builds on Windows set -std= to something which doesn't
trigger this problem, why is this a problem? (I'm not denying that it's
potentially a problem, I'm just trying to understand the scope of the
problem.)
…--
"I used to be with it, but then they changed what ‘it’ was, and now what
I’m with isn’t it. And what’s ‘it’ seems weird and scary to me."
-- Grandpa Simpson
(It will happen to you too.)
|
I don't think it's helpful in the long term to be hiding such issues under the C99 blanket. As for the "scope of the problem", it looks to me that if perl's underlying C level is at C23 && you want to call |
Module: XS
Description
Since upgrading from gcc 14 to 15, the perl-CommonMark package cannot be rebuild. This does not look like an error in the CommonMark module but one in the XS module from core.
Steps to Reproduce
Build the CommonMark module using gcc 15 and Perl 5.40.1
Expected behavior
The module should build successfully
Perl configuration
The text was updated successfully, but these errors were encountered: