boostorg / spirit

Boost.org spirit module
http://boost.org/libs/spirit
393 stars 161 forks source link

Qi wrong propagation to container attribute from iterator-range #653

Closed sehe closed 3 years ago

sehe commented 3 years ago

Adding an empty sequence element (like >> "" or >> eps, or even >> omit[whatever]) makes the attribute propagation for raw[] fail.

The second assert fails, because only the first element of the iterator range is copied:

#include <boost/spirit/include/qi.hpp>
int main() {
    using namespace boost::spirit::qi;
    auto *const f = "123",
         *const l = f + 3;
    std::string a, expected { '1', '2', '3' }; // or e.g. vector<char>

    assert(parse(f, l, raw[int_], a));
    assert(a == expected);                     // pass

    a.clear();

    assert(parse(f, l, raw[int_] >> eps, a));
    assert(a == expected);                     // <- FAIL!
}

(the actual value of a is `"1", instead of "123" in the failing assert).

I chased the code down a little bit. In the correct case we hit this line in assign_to:

image

In the incorrect case we end up here:

image


Informative note: this behaviour has not changed since 1.54.0 and does not depend on compilers as far as I could see.

This sample reduced from this SO question

Kojoley commented 3 years ago

Does not work in X3 either, seems to be simple to fix in Qi though.