Given class COtherClass having methods
class COtherClass
{
...
        inline COtherClass(unsigned int uiParam1, const char *pszParam2, const
char *pszParam3, unsigned long ulParam4, const char *pszParam5)
        {...}
        ~COtherClass();
        COtherClass &Method1();
        COtherClass &Method2(unsigned long long &ullParam);
        COtherClass &operator ()(const char *pszParam1, const void *pvParam2);
        COtherClass &operator ()(const char *pszParam1, unsigned long long
ullParam2) { ... }
};

For code 
struct CHostClass
{
public:
        unsigned long long m_ullProblemField;
        const void      *m_pvPointerField;
        const char      *m_szSzField;

        ~CHostClass()
        {
                COtherClass(5, m_szSzField, NULL, 0,
"ImmString1").Method1().Method2(m_ullProblemField)("ImmString2",
m_pvPointerField)("ImmString3", m_ullProblemField);
        }
};

GCC generated the following assembler text (debug build)
mov    0x8(%ebp),%eax // CHostClass::this
pushl  0x4(%eax) // HI(CHostClass::m_ullProblemField)
pushl  (%eax) // LO(CHostClass::m_ullProblemField)
push   $0x81f10f9 // "ImmString3"
sub    $0x8,%esp
mov    0x8(%ebp),%eax // CHostClass::this
pushl  0x8(%eax) // CHostClass::m_pvPointerField
push   $0x81f0e3a // "ImmString2"
sub    $0xc,%esp
pushl  0x8(%ebp) // CHostClass::this <=> offset CHostClass::m_ullProblemField
sub    $0xc,%esp
push   $0x81f1104 // "ImmString1"
push   $0x0 // 0
push   $0x0 // NULL
mov    0x8(%ebp),%eax // CHostClass::this
pushl  0xc(%eax) // CHostClass::m_szSzField
push   $0x5 // 5
lea    0xfffff4e8(%ebp),%eax // storage for COtherClass instance
push   %eax
call   0x804e61c // COtherClass::COtherClass constructor
add    $0x24,%esp // 6*4 params + 12 reserve made with "sub $0xc,%esp"
lea    0xfffff4e8(%ebp),%eax // instance of COtherClass
push   %eax
call   0x818e68e // COtherClass::Method1
add    $0x4,%esp // 1 param
push   %eax // instance of COtherClass
call   0x8190384 // COtherClass::Method2
add    $0x14,%esp // 2*4 params + 12 reserve made with "sub $0xc,%esp"
push   %eax // instance of COtherClass
call   0x818e85c // COtherClass::operator()(const char *, const void *)
add    $0x14,%esp // 3*4 params + 8 reserve made with "sub $0x8,%esp"
push   %eax // instance of COtherClass
call   0x804f322 // COtherClass::operator()(const char *, unsigned long long)
add    $0x10,%esp // 2*4 + 1*8 params
sub    $0xc,%esp
lea    0xfffff4e8(%ebp),%eax // instance of COtherClass
push   %eax
call   0x818e610 // COtherClass::~COtherClass
add    $0x10,%esp // 1*4 params + 12 reserve made with "sub $0xc,%esp"

The problem is that the value of m_ullProblemField is pushed to stack at the
very beginning of code while it is modified later during invocation of
COtherClass::Method2. COtherClass::operator (const char *, unsigned long long)
should receive modified value of field but it receives initial one.


-- 
           Summary: Parameter pushed to stack too soon
           Product: gcc
           Version: 3.3.5
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: oder at eleks dot lviv dot ua
 GCC build triplet: x86
  GCC host triplet: x86
GCC target triplet: x86


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29582

Reply via email to