This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
optimization/1535: Function parameter becomes NULL during throw (optimized code only)
- To: gcc-gnats at gcc dot gnu dot org
- Subject: optimization/1535: Function parameter becomes NULL during throw (optimized code only)
- From: eytan dot segal at SanctumInc dot com
- Date: 2 Jan 2001 16:35:40 -0000
- Reply-To: eytan dot segal at SanctumInc dot com
>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);
}
}