summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-02-05 04:07:25 +0000
committershyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-02-05 04:07:25 +0000
commit779c18bf238aba630e40c26e10ce8aa278c45d61 (patch)
tree529c8339b0a3f0fa1d6fd9fafdca7091211353c1
parentbb6c0f03a7c0875c20efc79506316da2cb4c4aed (diff)
va_copy is a C99ism
Should provide appropriate fallback implementation. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62220 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--aclocal.m41
-rw-r--r--configure.ac20
-rw-r--r--internal.h19
-rw-r--r--mjit.c4
-rw-r--r--tool/m4/ruby_check_va_copy.m432
-rw-r--r--win32/Makefile.sub1
6 files changed, 73 insertions, 4 deletions
diff --git a/aclocal.m4 b/aclocal.m4
index 4c421e6aa3..365f8de91a 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -25,6 +25,7 @@ m4_include([tool/m4/ruby_check_setjmp.m4])
m4_include([tool/m4/ruby_check_signedness.m4])
m4_include([tool/m4/ruby_check_sizeof.m4])
m4_include([tool/m4/ruby_check_sysconf.m4])
+m4_include([tool/m4/ruby_check_va_copy.m4])
m4_include([tool/m4/ruby_cppoutfile.m4])
m4_include([tool/m4/ruby_decl_attribute.m4])
m4_include([tool/m4/ruby_default_arch.m4])
diff --git a/configure.ac b/configure.ac
index 9df872a845..a09b5def03 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1244,6 +1244,26 @@ AS_IF([test "$rb_cv_va_args_macro" = yes], [
AC_DEFINE(HAVE_VA_ARGS_MACRO)
])
+AC_CACHE_CHECK([appropriate way to simulate va_copy], rb_cv_va_copy, [dnl
+ RUBY_CHECK_VA_COPY([va_copy], [va_copy((dst),(src))])
+ RUBY_CHECK_VA_COPY([VA_COPY macro], [VA_COPY((dst),(src))])
+ RUBY_CHECK_VA_COPY([__va_copy], [__va_copy((dst),(src))])
+ RUBY_CHECK_VA_COPY([__builtin_va_copy], [__builtin_va_copy((dst),(src))])
+ RUBY_CHECK_VA_COPY([va_copy via struct assignment],
+ [do (dst) = (src); while (0)])
+ RUBY_CHECK_VA_COPY([va_copy via pointer assignment],
+ [do *(dst) = *(src); while (0)])
+ RUBY_CHECK_VA_COPY([va_copy via memcpy],
+ [memcpy(&(dst), &(src), sizeof(va_list))])
+])
+if test "x$rb_cv_va_copy" = x; then
+ AC_ERROR([no way to simulate va_copy])
+else
+ m4_pushdef([macro], AS_TR_CPP(HAVE_$1))
+ AC_DEFINE_UNQUOTED(macro($rb_cv_va_copy))
+ m4_popdef([macro])
+fi
+
AC_CACHE_CHECK([for alignas() syntax], rb_cv_have_alignas, [
rb_cv_have_alignas=no
RUBY_WERROR_FLAG([
diff --git a/internal.h b/internal.h
index 2c65ebcbfc..8ded0e1343 100644
--- a/internal.h
+++ b/internal.h
@@ -85,6 +85,25 @@ extern "C" {
# define STATIC_ASSERT(name, expr) typedef int static_assert_##name##_check[1 - 2*!(expr)]
#endif
+#if defined(HAVE_VA_COPY)
+/* OK, nothing to do */
+#elif defined(HAVE_VA_COPY_MACRO)
+#define va_copy(dst, src) VA_COPY((dst), (src))
+#elif defined(HAVE___VA_COPY)
+#define va_copy(dst, src) __va_copy((dst), (src))
+#elif defined(HAVE___BUILTIN_VA_COPY)
+#define va_copy(dst, src) __builtin_va_copy((dst), (src))
+#elif defined(HAVE_VA_COPY_VIA_STRUCT_ASSIGNMENT)
+#define va_copy(dst, src) do (dst) = (src); while (0)
+#elif defined(HAVE_VA_COPY_VIA_POINTER_ASSIGNMENT)
+#define va_copy(dst, src) do *(dst) = *(src); while (0)
+#elif defined(HAVE_VA_COPY_VIA_MEMCPY)
+#include <string.h>
+#define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list))
+#else
+#error >>>> no way to simuate va_copy <<<<
+#endif
+
#define SIGNED_INTEGER_TYPE_P(int_type) (0 > ((int_type)0)-1)
#define SIGNED_INTEGER_MAX(sint_type) \
(sint_type) \
diff --git a/mjit.c b/mjit.c
index 28ad5ca917..c766371860 100644
--- a/mjit.c
+++ b/mjit.c
@@ -119,10 +119,6 @@ extern int rb_thread_create_mjit_thread(void (*child_hook)(void), void (*worker_
typedef intptr_t pid_t;
#endif
-#ifndef va_copy
-#define va_copy(dest, src) ((dest) = (src))
-#endif
-
/* Atomically set function pointer if possible. */
#ifdef _WIN32
# ifdef InterlockedExchangePointer
diff --git a/tool/m4/ruby_check_va_copy.m4 b/tool/m4/ruby_check_va_copy.m4
new file mode 100644
index 0000000000..cc885e56de
--- /dev/null
+++ b/tool/m4/ruby_check_va_copy.m4
@@ -0,0 +1,32 @@
+# -*- Autoconf -*-
+m4_define(RUBY_CHECK_VA_COPY, [
+ if test "x$rb_cv_va_copy" = x; then
+ AC_TRY_RUN(
+[#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#define CONFTEST_VA_COPY(dst, src) $2
+void
+conftest(int n, ...)
+{
+ va_list ap, ap2;
+ int i;
+ va_start(ap, n);
+ CONFTEST_VA_COPY(ap2, ap);
+ for (i = 0; i < n; i++) if ((int)va_arg(ap, int) != n - i - 1) abort();
+ CONFTEST_VA_COPY(ap, ap2);
+ for (i = 0; i < n; i++) if ((int)va_arg(ap, int) != n - i - 1) abort();
+ va_end(ap);
+}
+int
+main()
+{
+ conftest(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+ exit(0);
+}],
+ rb_cv_va_copy=[$1],
+ rb_cv_va_copy="",
+ rb_cv_va_copy="")dnl
+ fi
+])dnl
+dnl
diff --git a/win32/Makefile.sub b/win32/Makefile.sub
index e94b0c98ae..a55967d12e 100644
--- a/win32/Makefile.sub
+++ b/win32/Makefile.sub
@@ -618,6 +618,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub
#define HAVE_PROTOTYPES 1
#define TOKEN_PASTE(x,y) x##y
#define HAVE_STDARG_PROTOTYPES 1
+#define HAVE_VA_COPY 1
!if $(MSC_VER) > 1100
#define NORETURN(x) __declspec(noreturn) x
!endif