Bug 80177
| Summary: | GCC accepts erroneous code due to wayward object construction/typecasting | ||
|---|---|---|---|
| Product: | [Retired] Red Hat Linux | Reporter: | Sysoltsev Slawa <vyatcheslav.sysoltsev> |
| Component: | gcc3 | Assignee: | Jakub Jelinek <jakub> |
| Status: | CLOSED UPSTREAM | QA Contact: | |
| Severity: | medium | Docs Contact: | |
| Priority: | medium | ||
| Version: | 8.0 | CC: | aoliva, bkoz, jason |
| Target Milestone: | --- | ||
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | Bug Fix | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2004-10-03 11:13:10 UTC | Type: | --- |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
Since one of the operands of == is a class or enumerated type [13.3.1.2]/1,
user-defined operators are candidate functions. However, to avoid the very kind
of error you've observed, paragraph 3 of the same clause, that defines how the
candidate functions are selected, says, in the second bullet:
[...] if no operand has a class type, only those non-
member functions in the lookup set that have a first parameter of
type T1 or "reference to (possibly cv-qualified) T1", when T1 is an
enumeration type, or (if there is a right operand) a second parame-
ter of type T2 or "reference to (possibly cv-qualified) T2", when T2
is an enumeration type, are candidate functions.
So this is a bug, indeed. However, I strongly recommend reporting this in the
bug tracking system at gcc.gnu.org, instead of here.
Problem persists through gcc 4.0. Pushed upstream to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17805 |
Description of problem: compiling such test case: test.cc: struct QCString { QCString( int size ) {}; QCString( const char *str ) {}; }; inline bool operator==( const QCString &s1, const QCString &s2 ) { return 0; } enum EStyle { FS_SOLID }; static EStyle getFillStyle() { return FS_SOLID; } int main() { if(getFillStyle() == "FS_SOLID") {}; // error here, FS_SOLID, not "FS_SOLID" must be } with command line: `g++ test.c` GNU C++ compiler accepts the test case without any warnings! Comparing 'enum EStyle' and 'char *' it IMPLICITLY casts enum to int, then int to QCString, from other side IMPLICITLY casts 'char *' to QCString and finally compares these using inline bool operator==( const QCString &s1, const QCString &s2 ) operator. That's incredible! Too much flexibility is used here; therefore erroneous code passed "strict" C++ checking. As a result hard-to-find run-time error will be. This test case was distilled from koffice application from Red Hat 8.0 Linux distribution. C++ compiler should do stricter checking. In this test case it should emit error about incomparable types. Version-Release number of selected component (if applicable): How reproducible: always Steps to Reproduce: 1. g++ test.cc (test.cc is in description) Actual results: Succesfully compiled ill-formed code. Expected results: Compilation error. Additional info: