Actions
Bug #13830
closed`rb_scan_args`'s result differs based on optimization level
Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.5.0dev (2017-08-19 trunk 59623) [x86_64-linux]
Description
I think I've found bug in rb_scan_args
function. This is my testing script:
require_relative 'test'
Test.test "server", "host", "a", "b", license: "lic"
And this is implementation of my module:
#include <ruby.h>
VALUE module = Qnil;
VALUE method_test(int argc, VALUE * argv, VALUE self);
void Init_test(void) {
module = rb_define_module("Test");
rb_define_singleton_method(module, "test", method_test, -1);
}
VALUE method_test(int argc, VALUE * argv, VALUE self) {
VALUE name, host, others, hash;
name = Qnil;
host = Qnil;
others = Qnil;
hash = Qnil;
rb_scan_args(argc, argv, "11*:", &name, &host, &others, &hash);
rb_p(name);
rb_p(host);
rb_p(others);
rb_p(hash);
return Qnil;
}
However, when I run it the result differs based on optimization level.
-O0
:
$ ~/ruby_install_O0/bin/ruby do_test.rb
"server"
"host"
["a", "b"]
{:license=>"lic"}
-O1
:
"server"
"host"
["a", "b", {:license=>"lic"}]
nil
-O2
:
"server"
"host"
["a", "b", {:license=>"lic"}]
nil
-O3
:
"server"
"host"
["a", "b", {:license=>"lic"}]
nil
Configure outputs:
-O0
:
---
Configuration summary for ruby version 2.5.0
* Installation prefix: /home/wolf/ruby_install_O0
* exec prefix: ${prefix}
* arch: x86_64-linux
* site arch: ${arch}
* RUBY_BASE_NAME: ruby
* ruby lib prefix: ${libdir}/${RUBY_BASE_NAME}
* site libraries path: ${rubylibprefix}/${sitearch}
* vendor path: ${rubylibprefix}/vendor_ruby
* target OS: linux
* compiler: gcc
* with pthread: yes
* enable shared libs: no
* dynamic library ext: so
* CFLAGS: ${optflags} ${debugflags} ${warnflags}
* LDFLAGS: -L. -fstack-protector -rdynamic \
-Wl,-export-dynamic
* optflags: -O0 -fno-fast-math
* debugflags: -ggdb3 -DRUBY_DEVEL=1
* warnflags: -Wall -Wextra -Wno-unused-parameter \
-Wno-parentheses -Wno-long-long \
-Wno-missing-field-initializers \
-Wno-tautological-compare \
-Wno-parentheses-equality \
-Wno-constant-logical-operand -Wno-self-assign \
-Wunused-variable -Werror=implicit-int \
-Werror=pointer-arith -Werror=write-strings \
-Werror=declaration-after-statement \
-Werror=implicit-function-declaration \
-Werror=deprecated-declarations \
-Wno-packed-bitfield-compat \
-Wsuggest-attribute=noreturn \
-Wsuggest-attribute=format \
-Wimplicit-fallthrough=0
* strip command: strip -S -x
* install doc: yes
* man page type: doc
---
-O1
:
---
Configuration summary for ruby version 2.5.0
* Installation prefix: /home/wolf/ruby_install_O1
* exec prefix: ${prefix}
* arch: x86_64-linux
* site arch: ${arch}
* RUBY_BASE_NAME: ruby
* ruby lib prefix: ${libdir}/${RUBY_BASE_NAME}
* site libraries path: ${rubylibprefix}/${sitearch}
* vendor path: ${rubylibprefix}/vendor_ruby
* target OS: linux
* compiler: gcc
* with pthread: yes
* enable shared libs: no
* dynamic library ext: so
* CFLAGS: ${optflags} ${debugflags} ${warnflags}
* LDFLAGS: -L. -fstack-protector -rdynamic \
-Wl,-export-dynamic
* optflags: -O1 -fno-fast-math
* debugflags: -ggdb3 -DRUBY_DEVEL=1
* warnflags: -Wall -Wextra -Wno-unused-parameter \
-Wno-parentheses -Wno-long-long \
-Wno-missing-field-initializers \
-Wno-tautological-compare \
-Wno-parentheses-equality \
-Wno-constant-logical-operand -Wno-self-assign \
-Wunused-variable -Werror=implicit-int \
-Werror=pointer-arith -Werror=write-strings \
-Werror=declaration-after-statement \
-Werror=implicit-function-declaration \
-Werror=deprecated-declarations \
-Wno-packed-bitfield-compat \
-Wsuggest-attribute=noreturn \
-Wsuggest-attribute=format \
-Wimplicit-fallthrough=0
* strip command: strip -S -x
* install doc: yes
* man page type: doc
---
I think the behaviour under -O0
is the correct one?
Updated by graywolf (Gray Wolf) almost 7 years ago
Oh and in case it's relevant, here is table of how it behaves under -O3
.
rb_scan_args|Function call |Result |
============|=======================|==================================|
*: |"s", "h", license: "l" |["s", "h"], {:license=>"l"} |
------------|-----------------------|----------------------------------|
1: |"s", license: "l" |"s", {:license=>"l"} |
------------|-----------------------|----------------------------------|
1*: |"s", "h", license: "l" |"s", ["h"], {:license=>"l"} |
------------|-----------------------|----------------------------------|
11: |"s", "h", license: "l" |"s", "h", {:license=>"l"} |
------------|-----------------------|----------------------------------|
11*: |"s", "h", license: "l" |"s", "h", [{license=>"l"}], false |
-----------------------------------------------------------------------|
Afaict the 11*:
is only unexpect (at least to me).
Updated by nobu (Nobuyoshi Nakada) almost 7 years ago
- Status changed from Open to Closed
Applied in changeset trunk|r59624.
ruby.h: fix rb_scan_args_trail_idx
-
include/ruby/ruby.h (rb_scan_args_trail_idx): fix the case both
of optional and rest arguments are defined.
[ruby-core:82427] [Bug #13830] -
include/ruby/ruby.h (rb_scan_args_n_trail): ditto.
Updated by nagachika (Tomoyuki Chikanaga) almost 7 years ago
- Backport changed from 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN to 2.2: DONTNEED, 2.3: DONTNEED, 2.4: REQUIRED
Updated by nagachika (Tomoyuki Chikanaga) almost 7 years ago
- Backport changed from 2.2: DONTNEED, 2.3: DONTNEED, 2.4: REQUIRED to 2.2: DONTNEED, 2.3: DONTNEED, 2.4: DONE
ruby_2_4 r59811 merged revision(s) 59624,59626.
Actions
Like0
Like0Like0Like0Like0Like0