You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@stdcxx.apache.org by "Stefan Teleman (Updated) (JIRA)" <ji...@apache.org> on 2012/02/05 21:35:59 UTC

[jira] [Updated] (STDCXX-1059) std::ios_base::setf() and std::ios_base::unsetf() do not set/clear the format flags correctly

     [ https://issues.apache.org/jira/browse/STDCXX-1059?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Stefan Teleman updated STDCXX-1059:
-----------------------------------

    Description: 
std::ios_base::setf (fmtflags fl) and std::ios_base::unsetf (fmtflags fl)
do not set or clear the format flags correctly:

{code:title=test.cc|borderStyle=solid}
#include <ios>
#include <iostream>
#include <fstream>

int main()
{
    std::fstream strm;
    std::ios_base::fmtflags fl;
    int ret = 0;

    fl = std::ios_base::dec;
    strm.unsetf(fl);

    fl = std::ios_base::hex;

    strm.setf(fl);
    strm.unsetf(fl);

    if (strm.flags() & fl)
    {
        std::cerr << "failure to clear hex flags" << std::endl;
        ++ret;
    }

    return ret;
}
{code}

1. Output from GCC 4.5.0:
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:19:37][1957]>> ./test-gcc 
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:20:02][1958]>> echo $status
0
{noformat}

2. Output from Sun C++ 12.2 with stlport:
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:20:24][1959]>> ./test-ss122-stlport 
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:08][1960]>> echo $status
0
{noformat}

3. Output rom Sun C++ 12.2 with our patched stdcxx:
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:09][1961]>> ./test-ss122-stdcxx 
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:44][1962]>> echo $status
0
{noformat}

4. Output from Pathscale 4.0.12.1 (which did not patch stdcxx):
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:46][1963]>> ./test-pathscale 
failure to clear hex flags
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:22:48][1964]>> echo $status
1
{noformat}

Simplified test case identifying the problem:
{code:title=flags.cc|borderStyle=solid}

#include <iostream>
#include <ios>

class BadTest
{
public:
    BadTest() : _flags(0) { }
    ~BadTest() { }

    unsigned int flags() const { return _flags; }
    unsigned int flags (unsigned int f)
    {
        unsigned int ret = _flags;
        _flags |= f;
        return ret;
    }
    unsigned int setf (unsigned int f) { return flags (flags() | f); }
    void unsetf (unsigned int f) { flags (flags() & ~f); }

private:
    unsigned int _flags;
};

class GoodTest
{
public:
    GoodTest() : _flags(0) { }
    ~GoodTest() { }

    unsigned int flags() const { return _flags; }
    unsigned int flags (unsigned int f)
    {
        unsigned int ret = _flags;
        _flags |= f;
        return ret;
    }
    unsigned int setf (unsigned int f)
    {
        unsigned int ret = _flags;
        _flags |= f;
        return ret;
    }
    void unsetf (unsigned int f) { _flags &= ~f; }

private:
    unsigned int _flags;
};

int main()
{
    BadTest bt;
    std::ios_base::fmtflags fl;

    std::cerr << "***** BadTest *****" << std::endl;
    std::cerr << "default flags: " << bt.flags() << std::endl;

    fl = std::ios_base::dec;

    bt.setf(fl);
    std::cerr << "flags: " << bt.flags() << std::endl;

    bt.unsetf(fl);
    std::cerr << "flags: " << bt.flags() << std::endl;

    fl = std::ios_base::hex;

    bt.setf(fl);
    std::cerr << "flags: " << bt.flags() << std::endl;

    bt.unsetf(fl);
    std::cerr << "flags: " << bt.flags() << std::endl;

    std::cerr << std::endl;

    GoodTest gt;
    std::cerr << "***** GoodTest *****" << std::endl;
    std::cerr << "default flags: " << gt.flags() << std::endl;

    fl = std::ios_base::dec;

    gt.setf(fl);
    std::cerr << "flags: " << gt.flags() << std::endl;

    gt.unsetf(fl);
    std::cerr << "flags: " << gt.flags() << std::endl;

    fl = std::ios_base::hex;

    gt.setf(fl);
    std::cerr << "flags: " << gt.flags() << std::endl;

    gt.unsetf(fl);
    std::cerr << "flags: " << gt.flags() << std::endl;

    return 0;
}
{code}

1. Output from GCC 4.5.0:
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:27:01][1968]>> ./flags-gcc 
***** BadTest *****
default flags: 0
flags: 2
flags: 2
flags: 10
flags: 10

***** GoodTest *****
default flags: 0
flags: 2
flags: 0
flags: 8
flags: 0
{noformat}

2. Output from Sun C++ 12.2 with stlport:
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:27:05][1969]>> ./flags-ss122-stlport 
***** BadTest *****
default flags: 0
flags: 8
flags: 8
flags: 24
flags: 24

***** GoodTest *****
default flags: 0
flags: 8
flags: 0
flags: 16
flags: 0
{noformat}

3. Output from Sun C++ 12.2. with our patched stdcxx:
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:27:12][1970]>> ./flags-ss122-stdcxx 
***** BadTest *****
default flags: 0
flags: 2
flags: 2
flags: 10
flags: 10

***** GoodTest *****
default flags: 0
flags: 2
flags: 0
flags: 8
flags: 0
{noformat}

The defect is in

{noformat}
std::ios_base::setf(fmtflags fl);
and
std::ios_base::unsetf(fmtflags fl);
{noformat}

in the original stdcxx implementation. The member function

{noformat}
fmtflags std::ios_base::flags() const;
{noformat}

returns by value. Any bitwise operations on the anon temporary created by
this function do not affect the __fmtflags data member of std::ios_base,
which remains unchanged.

Patch for stdcxx 4.2.1 to follow.



  was:
std::ios_base::setf (fmtflags fl) and std::ios_base::unsetf (fmtflags fl)
do not set or clear the format flags correctly:

{code title=test.cc|borderStyle=solid}
#include <ios>
#include <iostream>
#include <fstream>

int main()
{
    std::fstream strm;
    std::ios_base::fmtflags fl;
    int ret = 0;

    fl = std::ios_base::dec;
    strm.unsetf(fl);

    fl = std::ios_base::hex;

    strm.setf(fl);
    strm.unsetf(fl);

    if (strm.flags() & fl)
    {
        std::cerr << "failure to clear hex flags" << std::endl;
        ++ret;
    }

    return ret;
}
{code}

1. Output from GCC 4.5.0:
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:19:37][1957]>> ./test-gcc 
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:20:02][1958]>> echo $status
0
{noformat}

2. Output from Sun C++ 12.2 with stlport:
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:20:24][1959]>> ./test-ss122-stlport 
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:08][1960]>> echo $status
0
{noformat}

3. Output rom Sun C++ 12.2 with our patched stdcxx:
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:09][1961]>> ./test-ss122-stdcxx 
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:44][1962]>> echo $status
0
{noformat}

4. Output from Pathscale 4.0.12.1 (which did not patch stdcxx):
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:46][1963]>> ./test-pathscale 
failure to clear hex flags
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:22:48][1964]>> echo $status
1
{noformat}

Simplified test case identifying the problem:
{code title=flags.cc|borderStyle=solid}

#include <iostream>
#include <ios>

class BadTest
{
public:
    BadTest() : _flags(0) { }
    ~BadTest() { }

    unsigned int flags() const { return _flags; }
    unsigned int flags (unsigned int f)
    {
        unsigned int ret = _flags;
        _flags |= f;
        return ret;
    }
    unsigned int setf (unsigned int f) { return flags (flags() | f); }
    void unsetf (unsigned int f) { flags (flags() & ~f); }

private:
    unsigned int _flags;
};

class GoodTest
{
public:
    GoodTest() : _flags(0) { }
    ~GoodTest() { }

    unsigned int flags() const { return _flags; }
    unsigned int flags (unsigned int f)
    {
        unsigned int ret = _flags;
        _flags |= f;
        return ret;
    }
    unsigned int setf (unsigned int f)
    {
        unsigned int ret = _flags;
        _flags |= f;
        return ret;
    }
    void unsetf (unsigned int f) { _flags &= ~f; }

private:
    unsigned int _flags;
};

int main()
{
    BadTest bt;
    std::ios_base::fmtflags fl;

    std::cerr << "***** BadTest *****" << std::endl;
    std::cerr << "default flags: " << bt.flags() << std::endl;

    fl = std::ios_base::dec;

    bt.setf(fl);
    std::cerr << "flags: " << bt.flags() << std::endl;

    bt.unsetf(fl);
    std::cerr << "flags: " << bt.flags() << std::endl;

    fl = std::ios_base::hex;

    bt.setf(fl);
    std::cerr << "flags: " << bt.flags() << std::endl;

    bt.unsetf(fl);
    std::cerr << "flags: " << bt.flags() << std::endl;

    std::cerr << std::endl;

    GoodTest gt;
    std::cerr << "***** GoodTest *****" << std::endl;
    std::cerr << "default flags: " << gt.flags() << std::endl;

    fl = std::ios_base::dec;

    gt.setf(fl);
    std::cerr << "flags: " << gt.flags() << std::endl;

    gt.unsetf(fl);
    std::cerr << "flags: " << gt.flags() << std::endl;

    fl = std::ios_base::hex;

    gt.setf(fl);
    std::cerr << "flags: " << gt.flags() << std::endl;

    gt.unsetf(fl);
    std::cerr << "flags: " << gt.flags() << std::endl;

    return 0;
}
{code}

1. Output from GCC 4.5.0:
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:27:01][1968]>> ./flags-gcc 
***** BadTest *****
default flags: 0
flags: 2
flags: 2
flags: 10
flags: 10

***** GoodTest *****
default flags: 0
flags: 2
flags: 0
flags: 8
flags: 0
{noformat}

2. Output from Sun C++ 12.2 with stlport:
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:27:05][1969]>> ./flags-ss122-stlport 
***** BadTest *****
default flags: 0
flags: 8
flags: 8
flags: 24
flags: 24

***** GoodTest *****
default flags: 0
flags: 8
flags: 0
flags: 16
flags: 0
{noformat}

3. Output from Sun C++ 12.2. with our patched stdcxx:
{noformat}
[steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:27:12][1970]>> ./flags-ss122-stdcxx 
***** BadTest *****
default flags: 0
flags: 2
flags: 2
flags: 10
flags: 10

***** GoodTest *****
default flags: 0
flags: 2
flags: 0
flags: 8
flags: 0
{noformat}

The defect is in

{noformat}
std::ios_base::setf(fmtflags fl);
and
std::ios_base::unsetf(fmtflags fl);
{noformat}

in the original stdcxx implementation. The member function

{noformat}
fmtflags std::ios_base::flags() const;
{noformat}

returns by value. Any bitwise operations on the anon temporary created by
this function do not affect the __fmtflags data member of std::ios_base,
which remains unchanged.

Patch for stdcxx 4.2.1 to follow.



    
> std::ios_base::setf() and std::ios_base::unsetf() do not set/clear the format flags correctly
> ---------------------------------------------------------------------------------------------
>
>                 Key: STDCXX-1059
>                 URL: https://issues.apache.org/jira/browse/STDCXX-1059
>             Project: C++ Standard Library
>          Issue Type: Bug
>          Components: 27. Input/Output
>    Affects Versions: 4.2.1, 4.2.x, 4.3.x, 5.0.0
>         Environment: Solaris 10 and 11
> Red Hat Linux, OpenSuSE Linux
> Sun C++ Compilers 12.1, 12.2, 12.3
> Defect is independent of platform and/or compiler
>            Reporter: Stefan Teleman
>              Labels: conformance, runtime, standards
>             Fix For: 4.2.2, 4.2.x, 4.3.x, 5.0.0
>
>
> std::ios_base::setf (fmtflags fl) and std::ios_base::unsetf (fmtflags fl)
> do not set or clear the format flags correctly:
> {code:title=test.cc|borderStyle=solid}
> #include <ios>
> #include <iostream>
> #include <fstream>
> int main()
> {
>     std::fstream strm;
>     std::ios_base::fmtflags fl;
>     int ret = 0;
>     fl = std::ios_base::dec;
>     strm.unsetf(fl);
>     fl = std::ios_base::hex;
>     strm.setf(fl);
>     strm.unsetf(fl);
>     if (strm.flags() & fl)
>     {
>         std::cerr << "failure to clear hex flags" << std::endl;
>         ++ret;
>     }
>     return ret;
> }
> {code}
> 1. Output from GCC 4.5.0:
> {noformat}
> [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:19:37][1957]>> ./test-gcc 
> [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:20:02][1958]>> echo $status
> 0
> {noformat}
> 2. Output from Sun C++ 12.2 with stlport:
> {noformat}
> [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:20:24][1959]>> ./test-ss122-stlport 
> [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:08][1960]>> echo $status
> 0
> {noformat}
> 3. Output rom Sun C++ 12.2 with our patched stdcxx:
> {noformat}
> [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:09][1961]>> ./test-ss122-stdcxx 
> [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:44][1962]>> echo $status
> 0
> {noformat}
> 4. Output from Pathscale 4.0.12.1 (which did not patch stdcxx):
> {noformat}
> [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:21:46][1963]>> ./test-pathscale 
> failure to clear hex flags
> [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:22:48][1964]>> echo $status
> 1
> {noformat}
> Simplified test case identifying the problem:
> {code:title=flags.cc|borderStyle=solid}
> #include <iostream>
> #include <ios>
> class BadTest
> {
> public:
>     BadTest() : _flags(0) { }
>     ~BadTest() { }
>     unsigned int flags() const { return _flags; }
>     unsigned int flags (unsigned int f)
>     {
>         unsigned int ret = _flags;
>         _flags |= f;
>         return ret;
>     }
>     unsigned int setf (unsigned int f) { return flags (flags() | f); }
>     void unsetf (unsigned int f) { flags (flags() & ~f); }
> private:
>     unsigned int _flags;
> };
> class GoodTest
> {
> public:
>     GoodTest() : _flags(0) { }
>     ~GoodTest() { }
>     unsigned int flags() const { return _flags; }
>     unsigned int flags (unsigned int f)
>     {
>         unsigned int ret = _flags;
>         _flags |= f;
>         return ret;
>     }
>     unsigned int setf (unsigned int f)
>     {
>         unsigned int ret = _flags;
>         _flags |= f;
>         return ret;
>     }
>     void unsetf (unsigned int f) { _flags &= ~f; }
> private:
>     unsigned int _flags;
> };
> int main()
> {
>     BadTest bt;
>     std::ios_base::fmtflags fl;
>     std::cerr << "***** BadTest *****" << std::endl;
>     std::cerr << "default flags: " << bt.flags() << std::endl;
>     fl = std::ios_base::dec;
>     bt.setf(fl);
>     std::cerr << "flags: " << bt.flags() << std::endl;
>     bt.unsetf(fl);
>     std::cerr << "flags: " << bt.flags() << std::endl;
>     fl = std::ios_base::hex;
>     bt.setf(fl);
>     std::cerr << "flags: " << bt.flags() << std::endl;
>     bt.unsetf(fl);
>     std::cerr << "flags: " << bt.flags() << std::endl;
>     std::cerr << std::endl;
>     GoodTest gt;
>     std::cerr << "***** GoodTest *****" << std::endl;
>     std::cerr << "default flags: " << gt.flags() << std::endl;
>     fl = std::ios_base::dec;
>     gt.setf(fl);
>     std::cerr << "flags: " << gt.flags() << std::endl;
>     gt.unsetf(fl);
>     std::cerr << "flags: " << gt.flags() << std::endl;
>     fl = std::ios_base::hex;
>     gt.setf(fl);
>     std::cerr << "flags: " << gt.flags() << std::endl;
>     gt.unsetf(fl);
>     std::cerr << "flags: " << gt.flags() << std::endl;
>     return 0;
> }
> {code}
> 1. Output from GCC 4.5.0:
> {noformat}
> [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:27:01][1968]>> ./flags-gcc 
> ***** BadTest *****
> default flags: 0
> flags: 2
> flags: 2
> flags: 10
> flags: 10
> ***** GoodTest *****
> default flags: 0
> flags: 2
> flags: 0
> flags: 8
> flags: 0
> {noformat}
> 2. Output from Sun C++ 12.2 with stlport:
> {noformat}
> [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:27:05][1969]>> ./flags-ss122-stlport 
> ***** BadTest *****
> default flags: 0
> flags: 8
> flags: 8
> flags: 24
> flags: 24
> ***** GoodTest *****
> default flags: 0
> flags: 8
> flags: 0
> flags: 16
> flags: 0
> {noformat}
> 3. Output from Sun C++ 12.2. with our patched stdcxx:
> {noformat}
> [steleman@darthvader][/src/steleman/programming/stdcxx-ss122/bugfixes-sunw/fmtflags][02/05/2012 15:27:12][1970]>> ./flags-ss122-stdcxx 
> ***** BadTest *****
> default flags: 0
> flags: 2
> flags: 2
> flags: 10
> flags: 10
> ***** GoodTest *****
> default flags: 0
> flags: 2
> flags: 0
> flags: 8
> flags: 0
> {noformat}
> The defect is in
> {noformat}
> std::ios_base::setf(fmtflags fl);
> and
> std::ios_base::unsetf(fmtflags fl);
> {noformat}
> in the original stdcxx implementation. The member function
> {noformat}
> fmtflags std::ios_base::flags() const;
> {noformat}
> returns by value. Any bitwise operations on the anon temporary created by
> this function do not affect the __fmtflags data member of std::ios_base,
> which remains unchanged.
> Patch for stdcxx 4.2.1 to follow.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira