Project

General

Profile

Actions

Bug #13830

closed

`rb_scan_args`'s result differs based on optimization level

Added by graywolf (Gray Wolf) almost 5 years ago. Updated almost 5 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.5.0dev (2017-08-19 trunk 59623) [x86_64-linux]
[ruby-core:82427]

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?

Actions #1

Updated by graywolf (Gray Wolf) almost 5 years ago

  • Description updated (diff)

Updated by graywolf (Gray Wolf) almost 5 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).

Actions #3

Updated by nobu (Nobuyoshi Nakada) almost 5 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.

Actions #4

Updated by nagachika (Tomoyuki Chikanaga) almost 5 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 5 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

Also available in: Atom PDF