diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-05-26 15:39:43 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-05-26 15:39:43 +0000 |
commit | 07d5f17cc80e03a78ddb089daea065f187eded1e (patch) | |
tree | ac44091d76493c7a6f5b132828c29fccd550c243 | |
parent | 2aebf3d0db2d15eac466bd2a25f0f0a9218230b4 (diff) | |
download | ruby-07d5f17cc80e03a78ddb089daea065f187eded1e.tar.gz |
ruby.h: fix for old clang
* include/ruby/ruby.h (rb_scan_args): add nul padding here to
apply to all references.
* include/ruby/ruby.h (rb_scan_args_verify): move length mismatch
check outside conditional operators.
Since old clang cannot optimize away string literal dereference by
an immediate index, e.g., ""[0], and both of true and false side
expressions are compiled and warned unintentionally. With such
old compilers, the check in rb_scan_args() does not work but may
result unpredictable value if the format is wrong.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55176 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | include/ruby/ruby.h | 24 |
2 files changed, 23 insertions, 9 deletions
@@ -1,3 +1,11 @@ +Fri May 27 00:39:40 2016 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * include/ruby/ruby.h (rb_scan_args): add nul padding here to + apply to all references. + + * include/ruby/ruby.h (rb_scan_args_verify): move length mismatch + check outside conditional operators. + Thu May 26 14:21:10 2016 Kazuki Yamaguchi <k@rhe.jp> * ext/openssl/ossl_pkey_dh.c (ossl_dh_compute_key): Check that the DH diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index af23b44739..b1f3e75198 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -2153,21 +2153,22 @@ int ruby_vsnprintf(char *str, size_t n, char const *fmt, va_list ap); #if defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P) && defined(__OPTIMIZE__) # define rb_scan_args(argc,argvp,fmt,...) \ __builtin_choose_expr(__builtin_constant_p(fmt), \ - rb_scan_args0(argc,argv,fmt,(sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)),((VALUE*[]){__VA_ARGS__})), \ + rb_scan_args0(argc,argv,fmt"\0\0\0\0\0\0",\ + (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \ + ((VALUE*[]){__VA_ARGS__})), \ rb_scan_args(argc,argvp,fmt,__VA_ARGS__)) # if HAVE_ATTRIBUTE_ERRORFUNC ERRORFUNC(("bad scan arg format"), int rb_scan_args_bad_format(const char*)); -ERRORFUNC(("variable argument length doesn't match"), int rb_scan_args_length_mismatch(int,int)); +ERRORFUNC(("variable argument length doesn't match"), int rb_scan_args_length_mismatch(const char*,int)); # else # define rb_scan_args_bad_format(fmt) 0 -# define rb_scan_args_length_mismatch(vari, varc) 0 +# define rb_scan_args_length_mismatch(fmt, varc) 0 # endif # define rb_scan_args_isdigit(c) ((unsigned char)((c)-'0')<10) + # define rb_scan_args_count_end(fmt, ofs, varc, vari) \ - (((varc) \ - /(!fmt[ofs] || rb_scan_args_bad_format(fmt))) \ - /((varc)==(vari) || rb_scan_args_length_mismatch(vari, varc))) + ((vari)/(!fmt[ofs] || rb_scan_args_bad_format(fmt))) # define rb_scan_args_count_block(fmt, ofs, varc, vari) \ (fmt[ofs]!='&' ? \ @@ -2194,10 +2195,15 @@ ERRORFUNC(("variable argument length doesn't match"), int rb_scan_args_length_mi rb_scan_args_count_var(fmt, ofs, varc, vari) : \ rb_scan_args_count_var(fmt, ofs+1, varc, vari+fmt[ofs]-'0')) +# define rb_scan_args_verify(fmt, varc) \ + ((!rb_scan_args_isdigit(fmt[0]) ? \ + rb_scan_args_count_var(fmt, 0, varc, 0) : \ + rb_scan_args_count_opt(fmt, 1, varc, fmt[0]-'0')) \ + == (varc) || \ + rb_scan_args_length_mismatch(fmt, varc)) + # define rb_scan_args_count(fmt, varc) \ - (!rb_scan_args_isdigit(fmt[0]) ? \ - rb_scan_args_count_var(fmt"\0\0\0\0", 0, varc, 0) : \ - rb_scan_args_count_opt(fmt"\0\0\0\0\0\0", 1, varc, fmt[0]-'0')) + ((varc)/(rb_scan_args_verify(fmt, varc))) # define rb_scan_args_lead_p(fmt) rb_scan_args_isdigit(fmt[0]) # define rb_scan_args_n_lead(fmt) (rb_scan_args_lead_p(fmt) ? fmt[0]-'0' : 0) |