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-bugs mailing list