http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51405
Bug #: 51405 Summary: Passing method result to constructor treated as function declaration Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: critical Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: muhi...@gmail.com Created attachment 25984 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=25984 Testcase Passing to constructor result of method with name which was typedefed before results in treating object creation as function declaration. The following code should not compile, but it compiles on gcc 4.2.4 and newer Tested on 4.7.0 ubuntu snapshot, 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu3), 4.4.6 (Ubuntu/Linaro 4.4.6-11ubuntu2) and 4.2.4 built from source. #include <cstdio> typedef int Something; class A { public: A () { printf ("A::A\n"); } }; class B { }; int main () { printf ("start\n"); A a (B ()->Something ()); //Should produce compile error printf ("finish\n"); return 0; } This bug leads to very hard to find bugs in user code - if your class has operator -> and returned type has method with name which was typedefed. For example we have DisplayLock class which receives x11 Display* in constructor and singleton which has "Display* Display ()" method, so code DisplayLock lock (DisplaySingleton::Instance ()->Display ()); is ignored because Display typedefed as struct _XDisplay Display, and we see no errors, because there are no access to lock object after creation; For example: #include <cstdio> typedef int Something; class A { public: A (const char* arg) { printf ("A::A '%s'\n", arg); } }; class B { public: class Instance { public: Instance () { printf ("B::Instance::Instance\n"); } B* operator -> () const { static B instance; return &instance; } }; const char* Something () { return "Something"; } }; int main () { printf ("start '%s'\n", B::Instance ()->Something ()); A a (B::Instance ()->Something ()); printf ("finish\n"); return 0; } Expected to print (works on gcc 4.2.4): B::Instance::Instance start 'Something' B::Instance::Instance A::A 'Something' finish But prints (4.4.6, 4.6.1 and 4.7.0): B::Instance::Instance start 'Something' finish