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]
Other format: [Raw text]

[Bug c++/13483] New: new and delete operator calls mismatched by namespaces


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


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