[#109115] [Ruby master Misc#18891] Expand tabs in C code — "k0kubun (Takashi Kokubun)" <noreply@...>

Issue #18891 has been reported by k0kubun (Takashi Kokubun).

13 messages 2022/07/02

[#109118] [Ruby master Bug#18893] Don't redefine memcpy(3) — "alx (Alejandro Colomar)" <noreply@...>

Issue #18893 has been reported by alx (Alejandro Colomar).

11 messages 2022/07/02

[#109152] [Ruby master Bug#18899] Inconsistent argument handling in IO#set_encoding — "javanthropus (Jeremy Bopp)" <noreply@...>

Issue #18899 has been reported by javanthropus (Jeremy Bopp).

10 messages 2022/07/06

[#109193] [Ruby master Bug#18909] ARGF.readlines reads more than current file — "JohanJosefsson (Johan Josefsson)" <noreply@...>

Issue #18909 has been reported by JohanJosefsson (Johan Josefsson).

17 messages 2022/07/13

[#109196] [Ruby master Bug#18911] Process._fork hook point is not called when Process.daemon is used — "ivoanjo (Ivo Anjo)" <noreply@...>

Issue #18911 has been reported by ivoanjo (Ivo Anjo).

9 messages 2022/07/13

[#109201] [Ruby master Bug#18912] Build failure with macOS 13 (Ventura) Beta — "hsbt (Hiroshi SHIBATA)" <noreply@...>

Issue #18912 has been reported by hsbt (Hiroshi SHIBATA).

20 messages 2022/07/14

[#109206] [Ruby master Bug#18914] Segmentation fault during Ruby test suite execution — "jprokop (Jarek Prokop)" <noreply@...>

Issue #18914 has been reported by jprokop (Jarek Prokop).

8 messages 2022/07/14

[#109207] [Ruby master Feature#18915] New error class: NotImplementedYetError or scope change for NotImplementedYet — Quintasan <noreply@...>

Issue #18915 has been reported by Quintasan (Michał Zając).

18 messages 2022/07/14

[#109260] [Ruby master Feature#18930] Officially deprecate class variables — "Eregon (Benoit Daloze)" <noreply@...>

Issue #18930 has been reported by Eregon (Benoit Daloze).

21 messages 2022/07/20

[#109314] [Ruby master Bug#18938] Backport cf7d07570f50ef9c16007019afcff11ba6500d70 — "byroot (Jean Boussier)" <noreply@...>

Issue #18938 has been reported by byroot (Jean Boussier).

8 messages 2022/07/25

[#109371] [Ruby master Feature#18949] Deprecate and remove replicate and dummy encodings — "Eregon (Benoit Daloze)" <noreply@...>

Issue #18949 has been reported by Eregon (Benoit Daloze).

35 messages 2022/07/29

[ruby-core:109140] [Ruby master Bug#18893] Don't redefine memcpy(3)

From: "alx (Alejandro Colomar)" <noreply@...>
Date: 2022-07-05 08:52:09 UTC
List: ruby-core #109140
Issue #18893 has been updated by alx (Alejandro Colomar).


nobu (Nobuyoshi Nakada) wrote in #note-5:
> Do we need to force the function to be inlined? 


You can, but it's not the best solution.

I suiggest the following patches (if you like them, I'll send them to the mailing list):

```diff
commit f9da464637f6f705d334fa5dc0da7a32f4624173 (HEAD -> master)
Author: Alejandro Colomar <alx.manpages@gmail.com>
Date:   Tue Jul 5 10:50:13 2022 +0200

    Simplify memcpy() wrapper
    
    Although ISO C specifies that memcpy(dest, NULL, 0) is Undefined
    Behavior (hence the [[gnu::nonnull]] attribute in glibc), all
    known libc implementations produce a no-op for that call, so we
    don't need to add a useless branch for that case.
    
    However, removing the branch changes the behavior for
    memcpy(dest, NULL, n).  Before, we were producing a no-op.  Now,
    it will produce UB (very likely, a program crash, by dereferencing
    NULL).  For such a programmer error, the best thing to do is to
    crash hard, so that the programmer realizes the problem.
    
    Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>

diff --git a/include/ruby/internal/memory.h b/include/ruby/internal/memory.h
index f044e61ef9..b03ec5dbfd 100644
--- a/include/ruby/internal/memory.h
+++ b/include/ruby/internal/memory.h
@@ -655,12 +655,7 @@ RBIMPL_ATTR_RETURNS_NONNULL()
 inline void *
 ruby_nonempty_memcpy(void *dest, const void *src, size_t n)
 {
-    if (n) {
-        return memcpy(dest, src, n);
-    }
-    else {
-        return dest;
-    }
+    return memcpy(dest, src, n);
 }
 RBIMPL_SYMBOL_EXPORT_END()
 #undef memcpy

commit b5a09c246703908fc39c4835d2206eb7a080a4bc
Author: Alejandro Colomar <alx.manpages@gmail.com>
Date:   Tue Jul 5 10:42:28 2022 +0200

    ruby_nonempty_memcpy(): Use C99 inline
    
    'static' should only be ever used in source (.c) files, since its
    meaning is that "this function will be private to this translation
    unit", which forces the compiler to create a different standalone
    private function for every translation unit, in cases where a
    function is not inlined by the compiler.
    
    This has triggered some warnings in code that includes our header,
    where an inline (C99 inline) function called (unknowingly) our
    memcpy() wrapper, which is ruby_nonempty_memcpy() (after the
    preprocessor).  An inline function shouldn't call a static
    function (since the compiler expects that 'static' will only be
    used in source files, not header files), and therefore the
    warning.
    
    This commit removes that warning, and also improves this function,
    by not emitting duplicate code.
    
    Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>

diff --git a/include/ruby/internal/memory.h b/include/ruby/internal/memory.h
index aa3464465d..f044e61ef9 100644
--- a/include/ruby/internal/memory.h
+++ b/include/ruby/internal/memory.h
@@ -652,7 +652,7 @@ RBIMPL_ATTR_RETURNS_NONNULL()
 /* At least since 2004, glibc's <string.h> annotates memcpy to be
  * __attribute__((__nonnull__(1, 2))).  However it is safe to pass NULL to the
  * source pointer, if n is 0.  Let's wrap memcpy. */
-static inline void *
+inline void *
 ruby_nonempty_memcpy(void *dest, const void *src, size_t n)
 {
     if (n) {
diff --git a/memory.c b/memory.c
new file mode 100644
index 0000000000..bfa080c835
--- /dev/null
+++ b/memory.c
@@ -0,0 +1,12 @@
+/**********************************************************************
+
+  memory.c - Memory
+
+  Copyright (C) 2022 Alejandro Colomar <alx.manpages@gmail.com>
+
+**********************************************************************/
+
+#include "internal/memory.h"
+
+
+extern inline void *ruby_nonempty_memcpy(void *dest, const void *src, size_t n);
```


----------------------------------------
Bug #18893: Don't redefine memcpy(3)
https://bugs.ruby-lang.org/issues/18893#change-98281

* Author: alx (Alejandro Colomar)
* Status: Open
* Priority: Normal
* Assignee: shyouhei (Shyouhei Urabe)
* ruby -v: ruby 3.0.4p208 (2022-04-12 revision 3fa771dded) [x86_64-linux-gnu]
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN
----------------------------------------
It is Undefined Behavior, by any standard ever issued.


See what I have in my system right now:


```
alx@asus5775:/usr/include$ grepc memcpy
./string.h:43:
extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
		     size_t __n) __THROW __nonnull ((1, 2));


./x86_64-linux-gnu/ruby-3.0.0/rb_mjit_min_header-3.0.4.h:1520:
extern void *memcpy (void *__restrict __dest, const void *__restrict __src,
       size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));


./x86_64-linux-gnu/ruby-3.0.0/rb_mjit_min_header-3.0.4.h:1670:
extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) void *
__attribute__ ((__nothrow__ , __leaf__)) memcpy (void *__restrict __dest, const void *__restrict __src, size_t __len)
{
  return __builtin___memcpy_chk (__dest, __src, __len,
     __builtin_object_size (__dest, 0));
}


./ruby-3.0.0/ruby/internal/memory.h:278:
#define memcpy ruby_nonempty_memcpy


./x86_64-linux-gnu/ruby-3.0.0/rb_mjit_min_header-3.0.4.h:22679:
#define memcpy ruby_nonempty_memcpy


$ grepc ruby_nonempty_memcpy
./ruby-3.0.0/ruby/internal/memory.h:266:
static inline void *
ruby_nonempty_memcpy(void *dest, const void *src, size_t n)
{
    if (n) {
        return memcpy(dest, src, n);
    }
    else {
        return dest;
    }
}


./x86_64-linux-gnu/ruby-3.0.0/rb_mjit_min_header-3.0.4.h:5673:
__attribute__((__nonnull__ (1)))
__attribute__((__returns_nonnull__))
static inline void *
ruby_nonempty_memcpy(void *dest, const void *src, size_t n)
{
    if (n) {
        return memcpy(dest, src, n);
    }
    else {
        return dest;
    }
}
```

Some code that I maintain includes some ruby headers, which end up defining memcpy(3) to that thing.  Then, my code calls memcpy(3) from a function, which happens to be inline (yes, inline, not static inline, which is a horrible thing), and I get an error from the compiler, for using a static function within a non-static inline function.

So, I'd like you to please remove that definition from public headers, and refrain from redefining any ISO C functions.
If not, please define it to something not broken (and yes, static inline is broken, as it produces duplicated code when not inlined; you could use [[gnu::always_inline]] if you want to keep static, but don't).  Just C99 inline would be reasonable.  See also: <https://www.greenend.org.uk/rjk/tech/inline.html>

Thanks,

Alex



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread