This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

g++ optimization bug?


I'm think there is a bug in the g++/gcc optimizer...

The problem is, I cannot create a short example that results in the same
behaviour as the large project I'm working on.

So, I've included some short code snippets below

I'm compiling with -O3. Compiled with -O0, all is fine.

/////////////// main

//static
ulong x = strtoul(buffer,0,10);
//std::cout << "offset == " << x << std::endl;
grec = &tripdex::_get().const_group_from_offset(x);
//grec = tripdex::_get().const_group_ptr_from_offset(x);
std::cout << "set grec to " << grec << std::endl;

////////////// tripdex parts

class tripdex {
  static tripdex* _td_self;
  IO::mmap         td_group_mmap;
};

static tripdex const& _get(void) throw() { return *_td_self; }

inline SDB::group const&
SEARCHD::tripdex::const_group_from_offset(ulong _offset) const throw() {
  return *reinterpret_cast<SDB::group const*>(_offset + *td_group_mmap);
}

inline SDB::group const*
SEARCHD::tripdex::const_group_ptr_from_offset(ulong _offset) const throw() {
  return reinterpret_cast<SDB::group const*>(_offset + *td_group_mmap);
}

////////////// IO::mmap

class mmap {
  private:
    mutable void*	mm_mem;

  public:
    char const* operator*	(void) const throw() {
      return reinterpret_cast<char const*>(mm_mem);
    }
    char*	operator*	(void) throw() {
      return reinterpret_cast<char*>(mm_mem);
    }
  };
}

I've removed quite some bits that don't seem to bother.
The problem manifests itself on the 'grec = &tripdex' line. grec isn't
assigned the proper value.
Funny thing is, when either of the commented lines is uncommented, all works
right. This means making x static, printing the offset, or using the other more
direct function fixes the problem.

Below are two objdumps of the bad (const_group_from_offset) and the good 
version (const_group_ptr_from_offset):

//////////// BAD

			79: R_386_PLT32	__strtoul_internal
  7d:	5a                   	pop    %edx
  7e:	8b 83 00 00 00 00    	mov    0x0(%ebx),%eax
			80: R_386_GOT32	SEARCHD::tripdex::_td_self
  84:	8b 00                	mov    (%eax),%eax
  86:	59                   	pop    %ecx
  87:	8d 8b 0a 00 00 00    	lea    0xa(%ebx),%ecx
			89: R_386_GOTOFF	.rodata
  8d:	8b 40 24             	mov    0x24(%eax),%eax
  90:	01 85 70 ff ff ff    	add    %eax,0xffffff70(%ebp)
  96:	8b 83 00 00 00 00    	mov    0x0(%ebx),%eax
			98: R_386_GOT32	std::basic_ostream<char, std::...........

//////////// GOOD

			79: R_386_PLT32	__strtoul_internal
  7d:	5a                   	pop    %edx
  7e:	59                   	pop    %ecx
  7f:	8d 8b 0a 00 00 00    	lea    0xa(%ebx),%ecx
			81: R_386_GOTOFF	.rodata
  85:	89 85 70 ff ff ff    	mov    %eax,0xffffff70(%ebp)
		
  8b:	8b 83 00 00 00 00    	mov    0x0(%ebx),%eax
			8d: R_386_GOT32	SEARCHD::tripdex::_td_self
  91:	8b 00                	mov    (%eax),%eax
  93:	8b 40 24             	mov    0x24(%eax),%eax
  96:	01 85 70 ff ff ff    	add    %eax,0xffffff70(%ebp)
  9c:	8b 83 00 00 00 00    	mov    0x0(%ebx),%eax
			9e: R_386_GOT32	std::basic_ostream<char, std::.........

I'm no assembler expert, but it seems the bad version just doesn't store
the result from the strtoul and just overwrites %eax. The good version
stores it at line 85 and retrieves it again at line 96 after the content
of td_group_mmap is acquired.

Is this a real bug and do I need to send a bugreport to someone?

Thomas
-- 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]