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
Created attachment 19438 [details] MICO's head preprocessed typecode.cc file
If tckind is really an enum, then the behavior of gcc is correct.
And it is. ((int)0xffffffff) is ouside the range of the enum is gcc's behavior is correct.
new TypeCode(TK_RECURSIVE); is undefined and TK_RECURSIVE will be truncated to fit the enum. That might be the issue that actually breaks this.
yes, tckind is enum. Thanks for pointing out that this is MICO code issue. If you also could be so kind and cite some C++/C language specification point which GCC follows here and which all older GCC releases "overlooked" (or does not implement support for) as does Sun's C++ and Intel C++ that would be great. I find somehow silly that while using GCC 4.4.x (1) I'm able to assign arbitrary value to enum type variable w/o any warning, (2) I'm able to use arbitrary int for comparison with enum and (3) if I set enum variable value to arbitrary integer I'm able to use this arbitrary integer in `if/else' comparison successfully so the assignment nor comparison is not truncated to enum value IMHO, yet still it does omit my arbitrary integer from switch/case. Isn't this kind of strange? Thanks!