Index | Thread | Search

From:
Jeremy Evans <jeremy@openbsd.org>
Subject:
Re: fix ruby 3.3 crash on sparc64 with gcc15
To:
ports@openbsd.org
Date:
Wed, 26 Nov 2025 08:48:08 -0800

Download raw body.

Thread
On 11/26 02:18, Claudio Jeker wrote:
> Long story short gcc15 misscompiles rstring.h in ruby 3.3 and causes
> miniruby to crash during build.
> 
> I found https://bugs.ruby-lang.org/issues/21655 and especially
> https://github.com/ruby/ruby/pull/15113 which workaround the gcc15
> misscompilation.
> 
> With this ruby3.3 builds and seems to work well enough.
> ruby 3.4 should have the same bug but the compiler is tickled by something
> and does not do the bad optimisation. The diff was committed to the
> ruby master branch so I think it will show up in an upcomming release.

OK jeremy@

> 
> -- 
> :wq Claudio
> 
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/lang/ruby/3.3/Makefile,v
> diff -u -p -r1.18 Makefile
> --- Makefile	24 Oct 2025 13:26:13 -0000	1.18
> +++ Makefile	26 Nov 2025 13:10:02 -0000
> @@ -1,4 +1,5 @@
>  VERSION =		3.3.10
> +REVISION =		0
>  DISTNAME =		ruby-${VERSION}
>  PKGNAME-main =		ruby-${VERSION}
>  PKGNAME-ri_docs =	ruby${BINREV}-ri_docs-${VERSION}
> Index: patches/patch-include_ruby_internal_core_rstring_h
> ===================================================================
> RCS file: patches/patch-include_ruby_internal_core_rstring_h
> diff -N patches/patch-include_ruby_internal_core_rstring_h
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ patches/patch-include_ruby_internal_core_rstring_h	25 Nov 2025 19:38:45 -0000
> @@ -0,0 +1,98 @@
> +gcc15 workaround: https://github.com/ruby/ruby/pull/15113
> +
> +Index: include/ruby/internal/core/rstring.h
> +--- include/ruby/internal/core/rstring.h.orig
> ++++ include/ruby/internal/core/rstring.h
> +@@ -369,43 +369,8 @@ RSTRING_LEN(VALUE str)
> +     return RSTRING(str)->len;
> + }
> + 
> +-RBIMPL_WARNING_PUSH()
> +-#if RBIMPL_COMPILER_IS(Intel)
> +-RBIMPL_WARNING_IGNORED(413)
> +-#endif
> +-
> +-RBIMPL_ATTR_PURE_UNLESS_DEBUG()
> + RBIMPL_ATTR_ARTIFICIAL()
> + /**
> +- * @private
> +- *
> +- * "Expands" an embedded  string into an ordinal one.  This  is a function that
> +- * returns aggregated type.   The returned struct always  has its `as.heap.len`
> +- * an `as.heap.ptr` fields set appropriately.
> +- *
> +- * This is an implementation detail that 3rd parties should never bother.
> +- */
> +-static inline struct RString
> +-rbimpl_rstring_getmem(VALUE str)
> +-{
> +-    RBIMPL_ASSERT_TYPE(str, RUBY_T_STRING);
> +-
> +-    if (RB_FL_ANY_RAW(str, RSTRING_NOEMBED)) {
> +-        return *RSTRING(str);
> +-    }
> +-    else {
> +-        /* Expecting compilers to optimize this on-stack struct away. */
> +-        struct RString retval = {RBASIC_INIT};
> +-        retval.len = RSTRING_LEN(str);
> +-        retval.as.heap.ptr = RSTRING(str)->as.embed.ary;
> +-        return retval;
> +-    }
> +-}
> +-
> +-RBIMPL_WARNING_POP()
> +-
> +-RBIMPL_ATTR_ARTIFICIAL()
> +-/**
> +  * Queries the contents pointer of the string.
> +  *
> +  * @param[in]  str  String in question.
> +@@ -415,7 +380,9 @@ RBIMPL_ATTR_ARTIFICIAL()
> + static inline char *
> + RSTRING_PTR(VALUE str)
> + {
> +-    char *ptr = rbimpl_rstring_getmem(str).as.heap.ptr;
> ++    char *ptr = RB_FL_TEST_RAW(str, RSTRING_NOEMBED) ?
> ++        RSTRING(str)->as.heap.ptr :
> ++        RSTRING(str)->as.embed.ary;
> + 
> +     if (RUBY_DEBUG && RB_UNLIKELY(! ptr)) {
> +         /* :BEWARE: @shyouhei thinks  that currently, there are  rooms for this
> +@@ -441,14 +408,17 @@ RBIMPL_ATTR_ARTIFICIAL()
> + static inline char *
> + RSTRING_END(VALUE str)
> + {
> +-    struct RString buf = rbimpl_rstring_getmem(str);
> ++    char *ptr = RB_FL_TEST_RAW(str, RSTRING_NOEMBED) ?
> ++       RSTRING(str)->as.heap.ptr :
> ++        RSTRING(str)->as.embed.ary;
> ++    long len = RSTRING_LEN(str);
> + 
> +-    if (RUBY_DEBUG && RB_UNLIKELY(! buf.as.heap.ptr)) {
> ++    if (RUBY_DEBUG && RB_UNLIKELY(!ptr)) {
> +         /* Ditto. */
> +         rb_debug_rstring_null_ptr("RSTRING_END");
> +     }
> + 
> +-    return &buf.as.heap.ptr[buf.len];
> ++    return &ptr[len];
> + }
> + 
> + RBIMPL_ATTR_ARTIFICIAL()
> +@@ -477,16 +447,7 @@ RSTRING_LENINT(VALUE str)
> +  * @param  ptrvar  Variable where its contents is stored.
> +  * @param  lenvar  Variable where its length is stored.
> +  */
> +-#ifdef HAVE_STMT_AND_DECL_IN_EXPR
> + # define RSTRING_GETMEM(str, ptrvar, lenvar) \
> +-    __extension__ ({ \
> +-        struct RString rbimpl_str = rbimpl_rstring_getmem(str); \
> +-        (ptrvar) = rbimpl_str.as.heap.ptr; \
> +-        (lenvar) = rbimpl_str.len; \
> +-    })
> +-#else
> +-# define RSTRING_GETMEM(str, ptrvar, lenvar) \
> +     ((ptrvar) = RSTRING_PTR(str),           \
> +      (lenvar) = RSTRING_LEN(str))
> +-#endif /* HAVE_STMT_AND_DECL_IN_EXPR */
> + #endif /* RBIMPL_RSTRING_H */