Bug 67996 - std::ios_base::seekdir raises -Wswitch with Clang
Summary: std::ios_base::seekdir raises -Wswitch with Clang
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.6.3
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-10-16 18:52 UTC by Kim Gräsman
Modified: 2015-11-10 06:46 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kim Gräsman 2015-10-16 18:52:59 UTC
When using libstdc++ with Clang, we can't seem to form a fully-covered switch over std::ios_base::seekdir:

  void f(std::ios_base::seekdir way)
    switch(way) {
      case std::ios_base::beg:
        // ...
        break;

      case std::ios_base::cur:
        // ...
        break;

      case std::ios_base::end:
        // ...
        break;
    }
  }

...t.cc:87:12: warning: enumeration value
'_S_ios_seekdir_end' not handled in switch [-Wswitch]
                        switch (way)

This looks like it was discussed long ago in #17922, so I don't know if this has regressed or if it's something about Clang's implementation of this diagnostic that is different from GCC.

A discussion on the Clang list is available here:
http://article.gmane.org/gmane.comp.compilers.clang.devel/45198/match=overeager

What's the motivation for _S_ios_seekdir_end? Any chance it could be removed?

Thanks!
Comment 1 Jonathan Wakely 2015-10-17 00:51:21 UTC
(In reply to Kim Gräsman from comment #0)
> What's the motivation for _S_ios_seekdir_end? Any chance it could be removed?

Presumably to make sure the enum type is more than 16-bits, which could be done with a fixed underlying type in C++11, but not in C++03.

I don't think we should change this just because of a warning. The std::lib is allowed to define whatever enumerators it wants to (as long as they use reserved names).
Comment 2 Kim Gräsman 2015-10-17 05:57:56 UTC
Thanks, I figured that was why.

The warning is not a problem if I'm using <ios> directly, then I can just disable it locally.

But we ran into this with a third-party library having the code above in one of their headers. This makes it nigh-impossible for us to enable -Wswitch for our own code, as the third-party header could be indirectly included in any translation unit.

  ios:
     enum seekdir { beg, cur, end, _S_ios_seekdir_end };

  third-party.h:
    switch(seekdir) {
    case beg: break;
    case cur: break;
    case end: break;
    }

  us.cpp:
    #include "third-party.h"  // WARN

I wasn't sure if the extra enumerator was allowed by the standard, so thanks for confirming that.

We've now worked around it by patching the third-party to use an if/else chain instead, but I thought I'd raise it anyway because it creates a messy situation when the warning "leaks" like this.
Comment 3 Jonathan Wakely 2015-10-17 13:49:13 UTC
Then maybe the warning needs to be smarter, e.g. not warn for enumerators defined in system headers using the implementation's reserved names.

In any case, it's not a libstdc++ problem, our code is correct, and GCC doesn't issue any warning.
Comment 4 Kim Gräsman 2015-11-10 06:46:33 UTC
FWIW, it turns out that GCC warns, too:

    $ g++ -Iinclude -I/ssd/code/poco/CppUnit/include -I/ssd/code/poco/CppUnit/WinTestRunner/include -I/ssd/code/poco/Foundation/include -I/ssd/code/poco/XML/include -I/ssd/code/poco/Util/include -I/ssd/code/poco/Net/include -I/ssd/code/poco/Crypto/include -I/ssd/code/poco/NetSSL_OpenSSL/include -I/ssd/code/poco/Data/include -I/ssd/code/poco/Data/SQLite/include -I/ssd/code/poco/Data/ODBC/include -I/ssd/code/poco/Data/MySQL/include -I/ssd/code/poco/Zip/include -I/ssd/code/poco/PageCompiler/include -I/ssd/code/poco/PageCompiler/File2Page/include -I/ssd/code/poco/PDF/include -I/ssd/code/poco/CppParser/include -I/ssd/code/poco/MongoDB/include -I/ssd/code/poco/PocoDoc/include -I/ssd/code/poco/ProGen/include -Wall -Wno-sign-compare -DPOCO_UTIL_NO_JSONCONFIGURATION   -DPOCO_HAVE_IPv6 -D_XOPEN_SOURCE=500 -D_REENTRANT -D_THREAD_SAFE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DPOCO_HAVE_FD_EPOLL  -O2 -DNDEBUG -fPIC -c src/MemoryStream.cpp -o /ssd/code/poco/Foundation/obj/Linux/x86_64/release_shared/MemoryStream.o
In file included from src/MemoryStream.cpp:17:0:
include/Poco/MemoryStream.h: In instantiation of ‘Poco::BasicMemoryStreamBuf<ch, tr>::pos_type Poco::BasicMemoryStreamBuf<ch, tr>::seekoff(Poco::BasicMemoryStreamBuf<ch, tr>::off_type, std::ios_base::seekdir, std::ios_base::openmode) [with ch = char; tr = std::char_traits<char>; Poco::BasicMemoryStreamBuf<ch, tr>::pos_type = std::fpos<__mbstate_t>; Poco::BasicMemoryStreamBuf<ch, tr>::off_type = long int; std::ios_base::seekdir = std::_Ios_Seekdir; std::ios_base::openmode = std::_Ios_Openmode]’:
src/MemoryStream.cpp:59:1:   required from here
include/Poco/MemoryStream.h:87:4: warning: enumeration value ‘_S_ios_seekdir_end’ not handled in switch [-Wswitch]
    switch (way)
    ^
include/Poco/MemoryStream.h:113:4: warning: enumeration value ‘_S_ios_seekdir_end’ not handled in switch [-Wswitch]
    switch (way)
    ^

This is the age-old GCC 4.6.3 that we're stuck on, however, later versions may be more forgiving.