diff --git a/cont.c b/cont.c index 1f82a7944e..e7ad79f99c 100644 --- a/cont.c +++ b/cont.c @@ -628,9 +628,9 @@ show_vm_pcs(const rb_control_frame_t *cfp, } } #endif +COMPILER_WARNING_PUSH #ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wduplicate-decl-specifier" +COMPILER_WARNING_IGNORED(-Wduplicate-decl-specifier) #endif static VALUE cont_capture(volatile int *volatile stat) @@ -694,9 +694,7 @@ cont_capture(volatile int *volatile stat) return contval; } } -#ifdef __clang__ -#pragma clang diagnostic pop -#endif +COMPILER_WARNING_POP static inline void fiber_restore_thread(rb_thread_t *th, rb_fiber_t *fib) diff --git a/dln.c b/dln.c index 6791578063..7acea5f888 100644 --- a/dln.c +++ b/dln.c @@ -1244,12 +1244,9 @@ rb_w32_check_imported(HMODULE ext, HMODULE mine) #endif #ifdef USE_DLN_DLOPEN -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpedantic" -#elif defined(__GNUC__) && (__GNUC__ >= 5) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpedantic" +COMPILER_WARNING_PUSH +#if defined(__clang__) || GCC_VERSION_SINCE(4, 2, 0) +COMPILER_WARNING_IGNORED(-Wpedantic) #endif static bool dln_incompatible_library_p(void *handle) @@ -1257,11 +1254,7 @@ dln_incompatible_library_p(void *handle) void *ex = dlsym(handle, EXTERNAL_PREFIX"ruby_xmalloc"); return ex && ex != ruby_xmalloc; } -#ifdef __clang__ -#pragma clang diagnostic pop -#elif defined(__GNUC__) && (__GNUC__ >= 5) -#pragma GCC diagnostic pop -#endif +COMPILER_WARNING_POP #endif void* diff --git a/eval_intern.h b/eval_intern.h index 5352be44f6..f4a48d8171 100644 --- a/eval_intern.h +++ b/eval_intern.h @@ -160,10 +160,10 @@ LONG WINAPI rb_w32_stack_overflow_handler(struct _EXCEPTION_POINTERS *); #if defined(USE_UNALIGNED_MEMBER_ACCESS) && USE_UNALIGNED_MEMBER_ACCESS && \ defined(__clang__) # define UNALIGNED_MEMBER_ACCESS(expr) __extension__({ \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); \ + COMPILER_WARNING_PUSH; \ + COMPILER_WARNING_IGNORED(-Waddress-of-packed-member); \ typeof(expr) unaligned_member_access_result = (expr); \ - _Pragma("GCC diagnostic pop"); \ + COMPILER_WARNING_POP; \ unaligned_member_access_result; \ }) #else diff --git a/internal.h b/internal.h index 0d5c952158..628f0d4e20 100644 --- a/internal.h +++ b/internal.h @@ -2147,6 +2147,43 @@ rb_obj_builtin_type(VALUE obj) # define BITFIELD(type) unsigned int #endif +#if defined(_MSC_VER) +# define COMPILER_WARNING_PUSH __pragma(warning(push)) +# define COMPILER_WARNING_POP __pragma(warning(pop)) +# define COMPILER_WARNING_ERROR(flag) __pragma(warning(error: flag))) +# define COMPILER_WARNING_IGNORED(flag) __pragma(warning(suppress: flag))) + +#elif defined(__clang__) /* clang 2.6 already had this feature */ +# define COMPILER_WARNING_PUSH _Pragma("clang diagnostic push") +# define COMPILER_WARNING_POP _Pragma("clang diagnostic pop") +# define COMPILER_WARNING_SPECIFIER(kind, msg) \ + clang diagnostic kind # msg +# define COMPILER_WARNING_ERROR(flag) \ + COMPILER_WARNING_PRAGMA(COMPILER_WARNING_SPECIFIER(error, flag)) +# define COMPILER_WARNING_IGNORED(flag) \ + COMPILER_WARNING_PRAGMA(COMPILER_WARNING_SPECIFIER(ignored, flag)) + +#elif GCC_VERSION_SINCE(4, 2, 0) +/* https://gcc.gnu.org/onlinedocs/gcc-4.2.0/gcc/Diagnostic-Pragmas.html */ +# define COMPILER_WARNING_PUSH _Pragma("GCC diagnostic push") +# define COMPILER_WARNING_POP _Pragma("GCC diagnostic pop") +# define COMPILER_WARNING_SPECIFIER(kind, msg) \ + GCC diagnostic kind # msg +# define COMPILER_WARNING_ERROR(flag) \ + COMPILER_WARNING_PRAGMA(COMPILER_WARNING_SPECIFIER(error, flag)) +# define COMPILER_WARNING_IGNORED(flag) \ + COMPILER_WARNING_PRAGMA(COMPILER_WARNING_SPECIFIER(ignored, flag)) + +#else /* other compilers to follow? */ +# define COMPILER_WARNING_PUSH /* nop */ +# define COMPILER_WARNING_POP /* nop */ +# define COMPILER_WARNING_ERROR(cond, flag) /* nop */ +# define COMPILER_WARNING_ignored(cond, flag) /* nop */ +#endif + +#define COMPILER_WARNING_PRAGMA(str) COMPILER_WARNING_PRAGMA_(str) +#define COMPILER_WARNING_PRAGMA_(str) _Pragma(#str) + #if defined(__cplusplus) #if 0 { /* satisfy cc-mode */ diff --git a/mjit.c b/mjit.c index 5668b1a6e9..3599aa6c9e 100644 --- a/mjit.c +++ b/mjit.c @@ -387,14 +387,13 @@ start_process(const char *path, char *const *argv) } dev_null = rb_cloexec_open(ruby_null_device, O_WRONLY, 0); + COMPILER_WARNING_PUSH; #ifdef __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" + COMPILER_WARNING_IGNORED(-Wdeprecated-declarations); #endif if ((pid = vfork()) == 0) { -#ifdef __GNUC__ -# pragma GCC diagnostic pop -#endif + COMPILER_WARNING_POP; + umask(0077); if (mjit_opts.verbose == 0) { /* CC can be started in a thread using a file which has been diff --git a/process.c b/process.c index 5ac18315ef..ec6bbf8da5 100644 --- a/process.c +++ b/process.c @@ -3972,9 +3972,9 @@ retry_fork_async_signal_safe(int *status, int *ep, while (1) { prefork(); disable_child_handler_before_fork(&old); + COMPILER_WARNING_PUSH; #ifdef __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" + COMPILER_WARNING_IGNORED(-Wdeprecated-declarations); #endif #ifdef HAVE_WORKING_VFORK if (!has_privilege()) @@ -3984,9 +3984,7 @@ retry_fork_async_signal_safe(int *status, int *ep, #else pid = fork(); #endif -#ifdef __GNUC__ -# pragma GCC diagnostic pop -#endif + COMPILER_WARNING_POP; if (pid == 0) {/* fork succeed, child process */ int ret; close(ep[0]); @@ -4055,13 +4053,13 @@ rb_fork_ruby(int *status) prefork(); disable_child_handler_before_fork(&old); before_fork_ruby(); + COMPILER_WARNING_PUSH; #ifdef __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" + COMPILER_WARNING_IGNORED(-Wdeprecated-declarations); #endif pid = fork(); #ifdef __GNUC__ -# pragma GCC diagnostic pop + COMPILER_WARNING_POP; #endif err = errno; after_fork_ruby(); diff --git a/template/prelude.c.tmpl b/template/prelude.c.tmpl index a359e45cf8..f642398921 100644 --- a/template/prelude.c.tmpl +++ b/template/prelude.c.tmpl @@ -138,9 +138,9 @@ prelude_prefix_path(VALUE self) % unless preludes.empty? #define PRELUDE_NAME(n) rb_usascii_str_new_static(prelude_name##n, sizeof(prelude_name##n)-1) #define PRELUDE_CODE(n) rb_usascii_str_new_static(prelude_code##n.L0, sizeof(prelude_code##n)) -#if defined __GNUC__ && __GNUC__ >= 5 -# pragma GCC diagnostic push -# pragma GCC diagnostic error "-Wmissing-field-initializers" +COMPILER_WARNING_PUSH +#if GCC_VERSION_SINCE(4, 2, 0) +COMPILER_WARNING_ERROR(-Wmissing-field-initializers) #endif static void prelude_eval(VALUE code, VALUE name, int line) @@ -168,9 +168,7 @@ prelude_eval(VALUE code, VALUE name, int line) NULL, ISEQ_TYPE_TOP, &optimization)); rb_ast_dispose(ast); } -#if defined __GNUC__ && __GNUC__ >= 5 -# pragma GCC diagnostic pop -#endif +COMPILER_WARNING_POP % end % if @have_sublib