This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/13483] New: new and delete operator calls mismatched by namespaces
- From: "s_gccbugzilla at nedprod dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 24 Dec 2003 02:39:14 -0000
- Subject: [Bug c++/13483] New: new and delete operator calls mismatched by namespaces
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
This has been causing me some problems. I use a Secure namespace for code which
handles passwords and encryption keys which wipe memory allocations on free. I
should add that I have the same problem with GCC v3.3.2 and /maybe/ in GCC v3.4
(not sure, I had major issues getting it to build).
[ned@katey TnFOX]$ g++ -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--disable-checking --with-system-zlib --enable-__cxa_atexit
--host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
[ned@katey TnFOX]$ ./test
Making Test ...
Killing Test ...
Segmentation fault
Here's the contained example:
/* Demo of namespace scoping bug in GCC
by Niall Douglas
*/
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <new>
typedef unsigned long FXuval;
// From FXSecure.h
namespace Secure
{
void *operator new(size_t size) throw();
void operator delete(void *p) throw();
}
// From FXSecure.cpp
namespace Secure {
#define SECUREHEADERC 2
#define SECUREHEADERSIZE (SECUREHEADERC*sizeof(FXuval))
#define SECUREHEADERMAGIC (*((FXuval *)"TFSCTFSC"))
void *operator new(size_t size) throw()
{
void *ret=::operator new(size+SECUREHEADERSIZE, std::nothrow);
if(!ret) return 0;
FXuval *_ret=(FXuval *) ret;
_ret[0]=size;
_ret[1]=SECUREHEADERMAGIC;
ret=(void *)(_ret+SECUREHEADERC);
::memset(ret, 0, size);
return ret;
}
void operator delete(void *p) throw()
{
if(p)
{
FXuval *_p=(FXuval *) p;
size_t size=_p[-SECUREHEADERC];
assert(_p[-1]==SECUREHEADERMAGIC);
p=(void *)(_p-SECUREHEADERC);
::memset(p, 0, size+SECUREHEADERSIZE);
}
::operator delete(p);
}
class Test
{
int *foo;
public:
Test() : foo(new int) { }
~Test() { delete foo; }
};
} // namespace
int main(void)
{
printf("Making Test ...\n");
Secure::Test *t=new Secure::Test;
printf("Killing Test ...\n");
delete t;
printf("All good!\n");
return 0;
}
The new and delete operators called by class Test's constructor and destructor
should I think come from the local namespace ie; Secure. Unfortunately, all
versions of G++ mismatch the calls (constructs using Secure, destructs using
global) thus leading the the segmentation fault.
MSVC7.1 always calls operator new and delete in the global namespace. If you
make my alternative new and delete malloc() and free() instead, MSVC7.1 suddenly
calls the Secure namespace versions instead. My reading of the ISO C++ spec is
that the versions "closest" to the calling code should always be called in
preference ie; MSVC7.1 is wrong to treat operators new and delete differently.
Let me know, this bug is preventing me releasing Linux versions of my library.
At least with MSVC they're matched so I can work around it.
Cheers,
Niall
--
Summary: new and delete operator calls mismatched by namespaces
Product: gcc
Version: 3.2.2
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: s_gccbugzilla at nedprod dot com
CC: gcc-bugs at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13483