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