[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