This is the mail archive of the gcc-bugs@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]

optimization/1535: Function parameter becomes NULL during throw (optimized code only)



>Number:         1535
>Category:       optimization
>Synopsis:       Function parameter becomes NULL during throw (optimized code only)
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jan 02 08:36:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Eytan Segal, Sanctum Inc.
>Release:        unknown-1.0
>Organization:
>Environment:
Solaris 2.6, Solaris 7, RedHat Linux.
gcc 2.95.2
>Description:
The problem occurs only in optimized compile.

See attached code.

The bad scenario occurs when I throw an exception.
The throw calls the ~B() destructor which calls the 'destroy' function with 2 parameters, the first of which is a valid pointer.
Unfortunately, the pointer becomes NULL(!) when the 'destroy' function is reached.
The bug seems to happen when the second parameter is a class instance that is passed by value - passing it by reference seems to solve the problem.
The problem only occurs in distruction prompted by 'throw'. Destruction due to loss of scope a simple delete is OK.

The attached example may not seem a very useful coding pattern, but it is a simplification of a real-world (and much more complex) third-party template library we are using (ObjectSplace Toolkit), causing segmentation faults when we compile with optimizations.
>How-To-Repeat:
Simply compile:
g++ -O ronen.cpp
and run a.ot
See the difference when you compile without optimizations.
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="ronen.cpp"
Content-Disposition: inline; filename="ronen.cpp"

#include <stdio.h>


class A
{
public:
    A() : i(0) {}
    A(const A &other) : i(other.i) {}
    ~A() {}
protected:
    int i;
};


void destroy( int* first, A a )
{
    if(first==NULL) {
        fprintf(stderr,"Destroy: ***** Bug - got NULL\n");
    } else {
        fprintf(stderr,"Destroy: OK - first=0x%p\n",first);
    }
}


class B
{
public:
    B() {first = new int;}
    ~B() {destroy(first,a);}
private:
    int *first;
    A a;
};


void main()
{
	try
	{
       B b;
       int i=5;
       fprintf(stderr, "Going to throw\n");
       throw i;
	} catch(int i){
       fprintf(stderr, "%d\n",i);
	} 
}   

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