public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/12238] New: placement delete not called on incomplete object construction if in try-block!
@ 2003-09-10 15:42 noways at aliceposta dot it
  2003-10-19 17:53 ` [Bug c++/12238] " pinskia at gcc dot gnu dot org
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: noways at aliceposta dot it @ 2003-09-10 15:42 UTC (permalink / raw)
  To: gcc-bugs

PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12238

           Summary: placement delete not called on incomplete object
                    construction if in try-block!
           Product: gcc
           Version: 3.2.3
            Status: UNCONFIRMED
          Severity: critical
          Priority: P1
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: noways at aliceposta dot it
                CC: gcc-bugs at gcc dot gnu dot org

i'm using g++ mingw compiler under win 2000 server and i found that placement 
new is supported but the relative placement delete isn't called in case of 
incomplete construction of objects(exception in ctor), any way a non placement 
delete is called, i think this a difference from the c++ spec.

i've also found that in the same situation enclosed in try-catch block:

classtag* po;
try
{
  po = new classtag(); //if exception in ctor():
                       //step1: call to "delete po;"
                       //step2: jump to catch block
  delete po;
}
catch(int ignore)
{}

the step1 isn't performed!

thx in advice :) , sorry for the english! :|

Michele

/*****************************************************************************/


ORIGINAL TEST SOURCE:

#include <stdio.h>
#include <stdlib.h>

class allocator
{
	int memb;
} globalallocator;

void* operator new(size_t s)
{
	printf("::operator new(size_t s)\n");
	return malloc(s);
}
void* operator new(size_t s,allocator a)
{
	printf("::operator new(size_t s,allocator a)\n");
	return malloc(s);
}
void* operator new[](size_t s)
{
	printf("::operator new[](size_t s)\n");
	return malloc(s);
}
void* operator new[](size_t s,allocator a)
{
	printf("::operator new[](size_t s,allocator a)\n");
	return malloc(s);
}

void operator delete(void* p,size_t s)
{
	printf("::operator delete(void* p,size_t s)\n");
	free(p);
}
void operator delete(void* p,size_t s,allocator a)
{
	printf("::operator delete(void* p,size_t s,allocator a)\n");
	free(p);
}
void operator delete[](void* p,size_t s)
{
	printf("::operator delete[](void* p,size_t s)\n");
	free(p);
}
void operator delete[](void* p,size_t s,allocator a)
{
	printf("::operator delete[](void* p,size_t s,allocator a)\n");
	free(p);
}

class test3
{
	public:

	void* operator new(size_t s)
	{
		printf("test3::operator new(size_t s)\n");
		return malloc(s);
	}
	void* operator new(size_t s,allocator a)
	{
		printf("test3::operator new(size_t s,allocator a)\n");
		return malloc(s);
	}
	void* operator new[](size_t s)
	{
		printf("test3::operator new[](size_t s)\n");
		return malloc(s);
	}
	void* operator new[](size_t s,allocator a)
	{
		printf("test3::operator new[](size_t s,allocator a)\n");
		return malloc(s);
	}

	void operator delete(void* p,size_t s)
	{
		printf("test3::operator delete(void* p,size_t s)\n");
		free(p);
	}
	void operator delete(void* p,size_t s,allocator a)
	{
		printf("test3::operator delete(void* p,size_t s,allocator a)
\n");
		free(p);
	}
	void operator delete[](void* p,size_t s)
	{
		printf("test3::operator delete[](void* p,size_t s)\n");
		free(p);
	}
	void operator delete[](void* p,size_t s,allocator a)
	{
		printf("test3::operator delete[](void* p,size_t s,allocator a)
\n");
		free(p);
	}
};

class testderiv : public test3
{
	public:
	testderiv()
	{
		printf("testderiv::ctor()\n");
	}
	testderiv(int p)
	{
		if(p)
		{
			printf("testderiv::ctor(%d) EXCEPTION\n",p);
			throw 1;
		}
		else
		{
			printf("testderiv::ctor(%d)\n",p);
		}
	}
	~testderiv()
	{
		printf("testderiv::dtor()\n");
	}
};

class testderivarray : public test3
{
	public:
	testderivarray()
	{
		printf("testderivarray::ctor() EXCEPTION\n");
		throw 1;
	}

	~testderivarray()
	{
		printf("testderivarray::dtor()\n");
	}
};

int main()
{
	testderiv* po;
	testderivarray* poa;
	try
	{
		po = new testderiv(1);
		delete po;
	}
	catch(int ignore)
	{}

	printf("\n");

	po = new testderiv(0);
	delete po;

	printf("\n");

	try
	{
		po = new(globalallocator) testderiv(1);
		delete po;
	}
	catch(int ignore)
	{}

	printf("\n");

	po = new(globalallocator) testderiv(0);
	delete po;

	printf("\n");

	try
	{
		po = new testderiv[3];
		delete[] po;
	}
	catch(int ignore)
	{}

	printf("\n");

	try
	{
		po = new(globalallocator) testderiv[3];
		delete[] po;
	}
	catch(int ignore)
	{}

	printf("\n");

	try
	{
		poa = new testderivarray[3];
		delete[] poa;
	}
	catch(int ignore)
	{}

	printf("\n");

	try
	{
		poa = new(globalallocator) testderivarray[3];
		delete[] poa;
	}
	catch(int ignore)
	{}

	return 0;
}


/* EXPECTED STANDARD C++ OUTPUT:

test3::operator new(size_t s)
testderiv::ctor(1) EXCEPTION
test3::operator delete(void* p,size_t s)

test3::operator new(size_t s)
testderiv::ctor(0)
testderiv::dtor()
test3::operator delete(void* p,size_t s)

test3::operator new(size_t s,allocator a)
testderiv::ctor(1) EXCEPTION
test3::operator delete(void* p,size_t s,allocator a)

test3::operator new(size_t s,allocator a)
testderiv::ctor(0)
testderiv::dtor()
test3::operator delete(void* p,size_t s)

test3::operator new[](size_t s)
testderiv::ctor()
testderiv::ctor()
testderiv::ctor()
testderiv::dtor()
testderiv::dtor()
testderiv::dtor()
test3::operator delete[](void* p,size_t s)

test3::operator new[](size_t s,allocator a)
testderiv::ctor()
testderiv::ctor()
testderiv::ctor()
testderiv::dtor()
testderiv::dtor()
testderiv::dtor()
test3::operator delete[](void* p,size_t s)

test3::operator new[](size_t s)
testderivarray::ctor() EXCEPTION
test3::operator delete[](void* p,size_t s)

test3::operator new[](size_t s,allocator a)
testderivarray::ctor() EXCEPTION
test3::operator delete[](void* p,size_t s,allocator a)

*/


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/12238] placement delete not called on incomplete object construction if in try-block!
  2003-09-10 15:42 [Bug c++/12238] New: placement delete not called on incomplete object construction if in try-block! noways at aliceposta dot it
@ 2003-10-19 17:53 ` pinskia at gcc dot gnu dot org
  2003-10-20 11:03 ` nathan at gcc dot gnu dot org
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2003-10-19 17:53 UTC (permalink / raw)
  To: gcc-bugs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 825 bytes --]

PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12238


pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|critical                    |normal
           Keywords|                            |wrong-code


------- Additional Comments From pinskia at gcc dot gnu dot org  2003-10-19 17:51 -------
Some Quotes from the standard (I do not quite understand it):
15.2–2:
If the object or the array was allocated in a new-expression and the new-expression 
contains a new-placement, the storage occupied by the object is deallocated only if an 
appropriate placement operator delete is found, as specified in 5.3.4.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/12238] placement delete not called on incomplete object construction if in try-block!
  2003-09-10 15:42 [Bug c++/12238] New: placement delete not called on incomplete object construction if in try-block! noways at aliceposta dot it
  2003-10-19 17:53 ` [Bug c++/12238] " pinskia at gcc dot gnu dot org
@ 2003-10-20 11:03 ` nathan at gcc dot gnu dot org
  2003-10-20 13:25 ` bangerth at dealii dot org
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: nathan at gcc dot gnu dot org @ 2003-10-20 11:03 UTC (permalink / raw)
  To: gcc-bugs

PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12238



------- Additional Comments From nathan at gcc dot gnu dot org  2003-10-20 08:35 -------
It could well be a bug. I know Mark Mitchell fixed some placement delete bugs
in the current development (and maybe 3.3.2?). Try those compilers.

It would be nice it this test case was separated into separate tests that clearly
commented on what the expected behaviour was. There's too much for me to wade
through.


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/12238] placement delete not called on incomplete object construction if in try-block!
  2003-09-10 15:42 [Bug c++/12238] New: placement delete not called on incomplete object construction if in try-block! noways at aliceposta dot it
  2003-10-19 17:53 ` [Bug c++/12238] " pinskia at gcc dot gnu dot org
  2003-10-20 11:03 ` nathan at gcc dot gnu dot org
@ 2003-10-20 13:25 ` bangerth at dealii dot org
  2003-12-31  3:25 ` rmerkert at alphatech dot com
  2004-10-06 23:56 ` giovannibajo at libero dot it
  4 siblings, 0 replies; 6+ messages in thread
From: bangerth at dealii dot org @ 2003-10-20 13:25 UTC (permalink / raw)
  To: gcc-bugs

PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12238



------- Additional Comments From bangerth at dealii dot org  2003-10-20 13:15 -------
Just from the bugtracker's side: Nathan's absolutely right about breaking
apart the testcase into smaller chunks. I looked at this PR 2 or 3 times 
and always refrained from more in depth work by the length of the code.
Make this a couple of smaller pieces that are simpler to understand,
that would then certainly accelerate us reviewing them for correctness.

Thanks
  Wolfgang


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/12238] placement delete not called on incomplete object construction if in try-block!
  2003-09-10 15:42 [Bug c++/12238] New: placement delete not called on incomplete object construction if in try-block! noways at aliceposta dot it
                   ` (2 preceding siblings ...)
  2003-10-20 13:25 ` bangerth at dealii dot org
@ 2003-12-31  3:25 ` rmerkert at alphatech dot com
  2004-10-06 23:56 ` giovannibajo at libero dot it
  4 siblings, 0 replies; 6+ messages in thread
From: rmerkert at alphatech dot com @ 2003-12-31  3:25 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From rmerkert at alphatech dot com  2003-12-31 02:39 -------
I think the code is not correct:

The corresponding placement delete for new (size_t, allocator) should be
delete (void*,allocator) and not delete(void*,size_t,allocator).

Here's a simplified version of the code (I've omitted the array version, and the
placement operators are global):
#include <cstdlib>

#define BUG

struct A
{
  A() { throw 1; } 
};

void* operator new(::size_t,double)
{
  static char memory[64];
  return memory;
}

#ifdef BUG
void operator delete(void*,size_t,double)
#else
void operator delete(void*,double)
#endif
{
  ::std::exit(0);
}

int main()
{
  try
    {
      new(0.0) A();
    }
  catch(...)
    {}

  ::std::abort();
}

If the incorrect placement delete is used, then no delete function is invoked
whatsoever. Maybe a warning is in order?

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12238


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Bug c++/12238] placement delete not called on incomplete object construction if in try-block!
  2003-09-10 15:42 [Bug c++/12238] New: placement delete not called on incomplete object construction if in try-block! noways at aliceposta dot it
                   ` (3 preceding siblings ...)
  2003-12-31  3:25 ` rmerkert at alphatech dot com
@ 2004-10-06 23:56 ` giovannibajo at libero dot it
  4 siblings, 0 replies; 6+ messages in thread
From: giovannibajo at libero dot it @ 2004-10-06 23:56 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From giovannibajo at libero dot it  2004-10-06 23:56 -------
The point is: if there is an exception while constructing an object in a 
placement new expression, a placement deallocation function is called if and 
only if it is found by lookup, and the lookup is not ambiguous. The standard is 
pretty clear that if no function is found, then nothing is done. See 
[expr.new]/17 and /19.

There is nothing we can do about this. If the user declares a wrong function, 
it is his fault. There are situations where the user wants to *not* declare a 
deallocation function because it is useless. For instance, in the example in 
comment #4, memory from a static pool is returned in the placement allocation 
function, so there is nothing to be done to free it: in this case, the user has 
very good rights to not declare a placement deallocation function and not get a 
wrong warning about it.

There is no bug in this PR, and I cannot see a way to improve the diagnostic 
either (so not even a QoI issue). Thus, I'm closing this as invalid.



-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |giovannibajo at libero dot
                   |                            |it
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12238


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-10-06 23:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-09-10 15:42 [Bug c++/12238] New: placement delete not called on incomplete object construction if in try-block! noways at aliceposta dot it
2003-10-19 17:53 ` [Bug c++/12238] " pinskia at gcc dot gnu dot org
2003-10-20 11:03 ` nathan at gcc dot gnu dot org
2003-10-20 13:25 ` bangerth at dealii dot org
2003-12-31  3:25 ` rmerkert at alphatech dot com
2004-10-06 23:56 ` giovannibajo at libero dot it

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).