[Bug c++/51405] New: Passing method result to constructor treated as function declaration
muhineg at gmail dot com
gcc-bugzilla@gcc.gnu.org
Sun Dec 4 01:37:00 GMT 2011
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: unassigned@gcc.gnu.org
ReportedBy: muhineg@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
More information about the Gcc-bugs
mailing list