Bug 12815 - [3.3 Regression] Code compiled with optimization behaves unexpectedly
Summary: [3.3 Regression] Code compiled with optimization behaves unexpectedly
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.3.2
: P2 critical
Target Milestone: 3.3.3
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2003-10-28 15:41 UTC by Boris Kolpackov
Modified: 2004-01-14 09:06 UTC (History)
1 user (show)

See Also:
Host: i686-gnu-linux
Target: i686-gnu-linux
Build: i686-gnu-linux
Known to work:
Known to fail:
Last reconfirmed: 2003-12-16 22:12:26


Attachments
Self-contained testcase. (423 bytes, text/plain)
2003-12-03 13:55 UTC, Eric Botcazou
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Boris Kolpackov 2003-10-28 15:41:59 UTC
$ cat >test.cpp
#include <typeinfo>
#include <iostream>

using std::cerr;
using std::endl;

bool
operator== (std::type_info const* pa, std::type_info const& b)
{
  return *pa == b;
}

struct A
{
  virtual
  ~A () {}
};

struct APtr
{
  APtr (A* p)
      : p_ (p)
  {
  }

  A&
  operator* () const
  {
    return *p_;
  }

private:
  A* p_;
};

int
main ()
{
  APtr ap (new A);
  
  for(bool cont__ = true; cont__;)
  {
    cerr << "outer: cont__ " << cont__ << endl;
    
    for(std::type_info const* const exp__ ((&typeid (*ap)));
        cont__;
        cont__ = false)
    {
      cerr << "inner: cont__ " << cont__ << endl;
      
      if(cont__ &&
         exp__ == (typeid (int)) &&
         (cont__ = false, true))
      {
        cerr << "condition" << endl;        
      }
    }
  }
}

$ g++ --version
g++ (GCC) 3.3.2 (Debian)

$ g++ ./test.cpp
$ ./a.out
outer: cont__ 1
inner: cont__ 1
$ g++ -O ./test.cpp
$ ./a.out # will result in infinite loop
outer: cont__ 1
inner: cont__ 1
inner: cont__ 1
inner: cont__ 1
inner: cont__ 1
inner: cont__ 1
inner: cont__ 1
^C
$
Comment 1 Andrew Pinski 2003-10-28 16:11:10 UTC
Here is the smallest I could get it, also it is a regression from 3.0.4:
//#define __GXX_MERGED_TYPEINFO_NAMES
#include <typeinfo>

extern "C" void exit(int);
bool
operator== (std::type_info const* pa, std::type_info const& b)
{
  return *pa == b;
}
struct A
{
  virtual
  ~A () {}
};
struct APtr
{
  APtr (A* p)
      : p_ (p)
  {
  }
  A&
  operator* () const
  {
    return *p_;
  }
private:
  A* p_;
};
void f(void){exit(1);}
int
main ()
{
  APtr ap (new A);
  for(bool cont__ = true; cont__;)
  {
    for(std::type_info const* const exp__ ((&typeid (*ap)));
        cont__;
        cont__ = false)
    {
      if(cont__ &&
         exp__ == (typeid (int)))
      {
	f();
      }
    }
  }
}
Comment 2 Falk Hueffner 2003-10-28 16:28:56 UTC
A slightly smaller test case:

#include <typeinfo>
#include <iostream>

struct A { virtual ~A () {} };

struct APtr
{ 
  APtr (A* p)  : p_ (p) { }
  A& operator* () const { return *p_;  }
  A* p_;
};

int main ()
{ 
  APtr ap (new A);
  std::type_info const* const exp = &typeid (*ap);
  for (bool cont = true; cont; cont = false)
    { 
      std::cout << "inner: cont " << cont << std::endl;
      if (exp) ;
    }
}
Comment 3 Eric Botcazou 2003-12-03 13:55:10 UTC
Created attachment 5268 [details]
Self-contained testcase.
Comment 4 Eric Botcazou 2003-12-03 14:12:44 UTC
This is a C++ problem I think. It appears that the 'A' object is constructed
twice (or that two instances are constructed if this is the intended behaviour),
the first time for

  APtr ap (new A);

and the second time for

  if (exp)

The first instance is never used, only the second one through 'typeid'.


The problem is the following: because A has a vtable, a 'jump' instruction is
emitted inside the constructor to another insn of this constructor. Now the
'jump' inside the *second* constructor points to the insn which is targeted by
the 'jump' inside the *first* constructor, that is the 'label' of the first
constructor was reused for the second constructor. After that, all hell breaks
loose.
Comment 5 Andrew Pinski 2003-12-16 22:12:24 UTC
On tree-ssa, the optimization phases delete the store to cont for some reason!
Comment 6 GCC Commits 2004-01-06 00:52:16 UTC
Subject: Bug 12815

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	mmitchel@gcc.gnu.org	2004-01-06 00:52:12

Modified files:
	gcc/cp         : ChangeLog class.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/rtti: typeid4.C 

Log message:
	PR c++/12816
	* class.c (build_vtbl_ref_1): Do not unconditionally mark vtable
	references as constant.
	
	PR c++/12815
	* g++.dg/rtti/typeid4.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.3856&r2=1.3857
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/class.c.diff?cvsroot=gcc&r1=1.591&r2=1.592
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.3339&r2=1.3340
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/rtti/typeid4.C.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 7 GCC Commits 2004-01-06 00:52:41 UTC
Subject: Bug 12815

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	mmitchel@gcc.gnu.org	2004-01-06 00:52:38

Modified files:
	gcc/cp         : ChangeLog 

Log message:
	PR c++/12815
	* class.c (build_vtbl_ref_1): Do not unconditionally mark vtable
	references as constant.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.3857&r2=1.3858

Comment 8 Mark Mitchell 2004-01-06 00:55:17 UTC
Fixed in GCC 3.4.
Comment 9 GCC Commits 2004-01-13 00:01:53 UTC
Subject: Bug 12815

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	jason@gcc.gnu.org	2004-01-13 00:01:47

Modified files:
	gcc/cp         : ChangeLog class.c 

Log message:
	PR c++/12815
	* class.c (build_base_path): Do not mark vtable references as
	TREE_CONSTANT.
	(build_vtbl_ref_1): Likewise.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.3872&r2=1.3873
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/class.c.diff?cvsroot=gcc&r1=1.594&r2=1.595

Comment 10 Gabriel Dos Reis 2004-01-14 09:06:22 UTC
fixed also for 3.3.3