Hello,
first of all, I've tried hard to judge if MICO[1] code is wrong or GCC is wrong
in this case, but I still think GCC is wrong here, hence reporting this. I'm
not able to simplify testcase for this, but we're using following idiom:

#include <iostream>
#include <cassert>

using namespace std;

#define TK_RECURSIVE ((int)0xffffffff)

class TypeCode {
public:
    int tckind;

    TypeCode(int v)
        : tckind(v)
    {}
};

int
main(int argc, char* argv[])
{
    TypeCode* tc = NULL;
    if (argc > 5) {
        tc = new TypeCode(TK_RECURSIVE);
    }
    else {
        tc = new TypeCode(argc);
    }
    switch (tc->tckind) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        cout << "number supplied" << endl;
        break;
    case TK_RECURSIVE:
        cout << "TK_RECURSIVE is working!" << endl;
        break;
    default:
        cout << "C++ Compiler BUG!" << endl;
        assert(0);
    }
    return 0;
}


i.e. quite long switch statement of `int' where (int)0xffffffff is used as a
case label this everything done in object (C++ class). Some case blocks are
also rather large (several C++ code lines) Please note: the code above just
shows an idiom, but is not able to duplicate my issue. First problem seems to
be shown by GCC complaining with a warning like:

typecode.cc: In member function ‘CORBA::Boolean
CORBA::TypeCode::equal(CORBA::TypeCode*, CORBA::Boolean, CORBA::Boolean)
const’:
typecode.cc:750: warning: case label value is less than minimum value for type
typecode.cc: In member function ‘CORBA::Boolean
CORBA::TypeCode::equaltype(CORBA::TypeCode*,
std::set<std::pair<CORBA::TypeCode*, CORBA::TypeCode*>,
std::less<std::pair<CORBA::TypeCode*, CORBA::TypeCode*> >,
std::allocator<std::pair<CORBA::TypeCode*, CORBA::TypeCode*> > >*)’:
typecode.cc:827: warning: case label value is less than minimum value for type
typecode.cc: In member function ‘CORBA::Boolean
CORBA::TypeCode::decode(CORBA::DataDecoder&, std::map<long unsigned int,
std::pair<long unsigned int, CORBA::TypeCode*>, std::less<long unsigned int>,
std::allocator<std::pair<const long unsigned int, std::pair<long unsigned int,
CORBA::TypeCode*> > > >*, CORBA::ULong)’:
typecode.cc:1672: warning: case label value is less than minimum value for type
typecode.cc: In member function ‘void
CORBA::TypeCode::encode(CORBA::DataEncoder&, std::map<const CORBA::TypeCode*,
long unsigned int, std::less<const CORBA::TypeCode*>,
std::allocator<std::pair<const CORBA::TypeCode* const, long unsigned int> > >*)
const’:
typecode.cc:1913: warning: case label value is less than minimum value for type

so GCC does not like our code that much, although I think it's completely legal
(the same code is well compilable by GCC up to 4.3.x version, Sun C++ up to
5.10 and Intel C++, the issue starts with GCC 4.4.x).
The second problem seems to be that GCC completely omits generating code for
this as it thinks bad case label block. This results in a switch statement code
being corrupted and application not working well. Concretely I'm seeing asserts
done in default switch block.
I've tested simple workaround which is moving problematic case block in front
of the switch block into simple `if' statement and this works well. Fully
preprocessed source code is attached for your reference, you can find
appropriate lines following warnings above inside it.
Thanks for looking into it!
Karel
[1]: www.mico.org


-- 
           Summary: GCC miscompiles switch statement (omits case
                    label/block)
           Product: gcc
           Version: 4.4.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: kgardas at objectsecurity dot com
 GCC build triplet: i386-pc-solaris2.11
  GCC host triplet: i386-pc-solaris2.11
GCC target triplet: i386-pc-solaris2.11


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42576

Reply via email to