c++/2688: no suitable `operator delete' 3.0 regression from 2.95.2
Philip Martin
pm@ntlworld.com
Sun Apr 29 12:46:00 GMT 2001
>Number: 2688
>Category: c++
>Synopsis: no suitable `operator delete' 3.0 regression from 2.95.2
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: rejects-legal
>Submitter-Id: net
>Arrival-Date: Sun Apr 29 12:46:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Philip Martin
>Release: 3.0 20010428 (prerelease)
>Organization:
Corris Systems Ltd.
>Environment:
System: Linux debian2 2.2.19 #1 SMP Sun Apr 1 16:42:26 BST 2001 i686 unknown
Architecture: i686
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: /home/pm/gcc-cvs/gcc/configure --prefix=/usr/local/gcc-cvs --enable-languages=c,c++
>Description:
A member function operator delete with two arguments and an exception
specification doesn't get treated as a "usual deallocation function"
(section 3.7.3.2 [basic.std.dynamic.deallocation].)
$ g++ bug2.cc
bug2.cc: In function `int main()':
bug2.cc:25: no suitable `operator delete' for `X'
$ cat bug2.cc
#include <new>
extern "C" void abort();
bool new_flag = false;
bool delete_flag = false;
struct X {
void* operator new ( std::size_t n ) throw ( std::bad_alloc )
{
new_flag = true;
return ::operator new( n );
}
void operator delete( void* p, std::size_t n ) throw()
{
delete_flag = true;
::operator delete( p );
}
};
int
main()
{
X* x = new X;
delete x; // gcc 3.0 fails: "no suitable `operator delete' for `X'"
if ( ! new_flag || ! delete_flag )
::abort();
}
>How-To-Repeat:
Here is the preprocessed code:
# 1 "bug2.cc"
# 1 "/usr/local/gcc-cvs/include/g++-v3/new" 1 3
# 34 "/usr/local/gcc-cvs/include/g++-v3/new" 3
#pragma interface "new"
# 1 "/usr/local/gcc-cvs/include/g++-v3/cstddef" 1 3
# 1 "/usr/local/gcc-cvs/include/g++-v3/bits/std_cstddef.h" 1 3
# 40 "/usr/local/gcc-cvs/include/g++-v3/bits/std_cstddef.h" 3
# 1 "/usr/local/gcc-cvs/lib/gcc-lib/i686-pc-linux-gnu/3.0/include/stddef.h" 1 3
# 147 "/usr/local/gcc-cvs/lib/gcc-lib/i686-pc-linux-gnu/3.0/include/stddef.h" 3
typedef int ptrdiff_t;
# 199 "/usr/local/gcc-cvs/lib/gcc-lib/i686-pc-linux-gnu/3.0/include/stddef.h" 3
typedef unsigned int size_t;
# 41 "/usr/local/gcc-cvs/include/g++-v3/bits/std_cstddef.h" 2 3
namespace std
{
using ::ptrdiff_t;
using ::size_t;
}
# 3 "/usr/local/gcc-cvs/include/g++-v3/cstddef" 2 3
# 36 "/usr/local/gcc-cvs/include/g++-v3/new" 2 3
# 1 "/usr/local/gcc-cvs/include/g++-v3/exception" 1 3
# 34 "/usr/local/gcc-cvs/include/g++-v3/exception" 3
#pragma interface "exception"
extern "C++" {
namespace std
{
class exception
{
public:
exception() throw() { }
virtual ~exception() throw() { }
virtual const char* what() const throw();
};
class bad_exception : public exception
{
public:
bad_exception() throw() { }
virtual ~bad_exception() throw() { }
};
typedef void (*terminate_handler) ();
typedef void (*unexpected_handler) ();
terminate_handler set_terminate(terminate_handler) throw();
void terminate() __attribute__ ((__noreturn__));
unexpected_handler set_unexpected(unexpected_handler) throw();
void unexpected() __attribute__ ((__noreturn__));
bool uncaught_exception() throw();
}
}
# 37 "/usr/local/gcc-cvs/include/g++-v3/new" 2 3
extern "C++" {
namespace std
{
class bad_alloc : public exception
{
public:
virtual const char* what() const throw() { return "bad_alloc"; }
};
struct nothrow_t { };
extern const nothrow_t nothrow;
typedef void (*new_handler)();
new_handler set_new_handler(new_handler);
}
void *operator new(std::size_t) throw (std::bad_alloc);
void *operator new[](std::size_t) throw (std::bad_alloc);
void operator delete(void *) throw();
void operator delete[](void *) throw();
void *operator new(std::size_t, const std::nothrow_t&) throw();
void *operator new[](std::size_t, const std::nothrow_t&) throw();
void operator delete(void *, const std::nothrow_t&) throw();
void operator delete[](void *, const std::nothrow_t&) throw();
inline void *operator new(std::size_t, void *place) throw() { return place; }
inline void *operator new[](std::size_t, void *place) throw() { return place; }
}
# 2 "bug2.cc" 2
extern "C" void abort();
bool new_flag = false;
bool delete_flag = false;
struct X {
void* operator new ( std::size_t n ) throw ( std::bad_alloc )
{
new_flag = true;
return ::operator new( n );
}
void operator delete( void* p, std::size_t n ) throw()
{
delete_flag = true;
::operator delete( p );
}
};
int
main()
{
X* x = new X;
delete x;
if ( ! new_flag || ! delete_flag )
::abort();
}
>Fix:
Work around: remove the exception specification from Class::operator delete
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the Gcc-prs
mailing list