cp-tree.h (TYPE_NOTHROW_P): New macro.
* cp-tree.h (TYPE_NOTHROW_P): New macro. * decl2.c (delete_sanity): Warn on deleting void *. * init.c (build_new_1): Use TYPE_NOTHROW_P. * typeck.c (c_expand_return): cp_pedwarn on returning NULL from throwing operator new. From-SVN: r26692
This commit is contained in:
parent
9939c435d2
commit
7f477e818a
|
@ -1,3 +1,11 @@
|
|||
1999-04-29 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* cp-tree.h (TYPE_NOTHROW_P): New macro.
|
||||
* decl2.c (delete_sanity): Warn on deleting void *.
|
||||
* init.c (build_new_1): Use TYPE_NOTHROW_P.
|
||||
* typeck.c (c_expand_return): cp_pedwarn on returning NULL from
|
||||
throwing operator new.
|
||||
|
||||
1999-04-28 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* cp-tree.h (build_component_addr): Remove prototype.
|
||||
|
|
|
@ -1130,6 +1130,11 @@ struct lang_type
|
|||
equivalently, no throw specification. */
|
||||
#define TYPE_RAISES_EXCEPTIONS(NODE) TYPE_NONCOPIED_PARTS (NODE)
|
||||
|
||||
/* For FUNCTION_TYPE or METHOD_TYPE, return 1 iff it is declared `throw()'. */
|
||||
#define TYPE_NOTHROW_P(NODE) \
|
||||
(TYPE_RAISES_EXCEPTIONS (NODE) \
|
||||
&& TREE_VALUE (TYPE_RAISES_EXCEPTIONS (NODE)) == NULL_TREE)
|
||||
|
||||
/* The binding level associated with the namespace. */
|
||||
#define NAMESPACE_LEVEL(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.level)
|
||||
|
||||
|
|
|
@ -1212,6 +1212,10 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
|
|||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Deleting ptr to void is undefined behaviour [expr.delete/3]. */
|
||||
if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE)
|
||||
cp_warning ("`%T' is not a pointer-to-object type", type);
|
||||
|
||||
/* An array can't have been allocated by new, so complain. */
|
||||
if (TREE_CODE (t) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL
|
||||
|
|
|
@ -2260,10 +2260,7 @@ build_new_1 (exp)
|
|||
tree t = TREE_OPERAND (rval, 0);
|
||||
/* The function. */
|
||||
t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
|
||||
t = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (t));
|
||||
|
||||
if (t && TREE_VALUE (t) == NULL_TREE)
|
||||
nothrow = 1;
|
||||
nothrow = TYPE_NOTHROW_P (TREE_TYPE (t));
|
||||
}
|
||||
check_new = (flag_check_new || nothrow) && ! use_java_new;
|
||||
|
||||
|
|
|
@ -7307,6 +7307,13 @@ c_expand_return (retval)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Only operator new(...) throw(), can return NULL [expr.new/13]. */
|
||||
if ((DECL_NAME (current_function_decl) == ansi_opname[(int) NEW_EXPR]
|
||||
|| DECL_NAME (current_function_decl) == ansi_opname[(int) VEC_NEW_EXPR])
|
||||
&& !TYPE_NOTHROW_P (TREE_TYPE (current_function_decl))
|
||||
&& null_ptr_cst_p (retval))
|
||||
cp_pedwarn ("operator new should throw an exception, not return NULL");
|
||||
|
||||
if (retval == NULL_TREE)
|
||||
{
|
||||
/* A non-named return value does not count. */
|
||||
|
|
|
@ -4,11 +4,11 @@ int size = 0;
|
|||
|
||||
struct X {
|
||||
int x;
|
||||
void *operator new[](size_t sz) {
|
||||
void *operator new[](size_t sz) throw() {
|
||||
size = sz;
|
||||
return 0;
|
||||
}
|
||||
void operator delete[] (void *vp) { ::delete[] vp; }
|
||||
void operator delete[] (void *vp) { ::operator delete(vp); }
|
||||
};
|
||||
int main()
|
||||
{
|
||||
|
|
|
@ -1,23 +1,37 @@
|
|||
// PRMS Id: 6037
|
||||
// Special g++ Options: -fcheck-new
|
||||
// Special g++ Options: -fcheck-new -pedantic
|
||||
|
||||
extern "C" void * malloc (__SIZE_TYPE__);
|
||||
|
||||
int ena = 0;
|
||||
|
||||
struct A {
|
||||
int i;
|
||||
A () { i = 2; }
|
||||
void * operator new (__SIZE_TYPE__ s)
|
||||
{
|
||||
if (ena)
|
||||
return 0; // WARNING - returning NULL
|
||||
return malloc (s);
|
||||
}
|
||||
};
|
||||
|
||||
int ena = 0;
|
||||
void * operator new (__SIZE_TYPE__ s)
|
||||
{
|
||||
if (ena)
|
||||
return 0;
|
||||
return malloc (s);
|
||||
}
|
||||
struct B {
|
||||
int i;
|
||||
B () { i = 2; }
|
||||
void * operator new (__SIZE_TYPE__ s) throw()
|
||||
{
|
||||
if (ena)
|
||||
return 0;
|
||||
return malloc (s);
|
||||
}
|
||||
};
|
||||
|
||||
main ()
|
||||
int main ()
|
||||
{
|
||||
ena = 1;
|
||||
A* ap = new A;
|
||||
A *ap = new A;
|
||||
B *bp = new B;
|
||||
|
||||
return ap || bp ;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ extern "C" int printf(const char* ...);
|
|||
int delete_counter = -1;
|
||||
|
||||
struct T{
|
||||
void operator delete (void * p) {delete_counter ++; ::delete p;}
|
||||
void operator delete (void * p) {delete_counter ++; ::operator delete(p);}
|
||||
};
|
||||
|
||||
int main(void)
|
||||
|
|
|
@ -13,7 +13,7 @@ class blah {
|
|||
int j;
|
||||
public:
|
||||
blah();
|
||||
void *operator new(size_t size);
|
||||
void *operator new(size_t size) throw();
|
||||
};
|
||||
|
||||
inline blah::blah() : j(0) {
|
||||
|
@ -21,7 +21,7 @@ inline blah::blah() : j(0) {
|
|||
}
|
||||
|
||||
|
||||
void *blah::operator new(size_t size) {
|
||||
void *blah::operator new(size_t size) throw(){
|
||||
printf ("FAIL\n");
|
||||
exit (1);
|
||||
return NULL;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
class X {
|
||||
private:
|
||||
void* operator new(size_t) {// ERROR - .*
|
||||
void* operator new(size_t) throw(){// ERROR - .*
|
||||
printf("Inside private new().\n");
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
// Build don't link:
|
||||
|
||||
// Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
// Contributed by Nathan Sidwell 15 Apr 1999 <nathan@acm.org>
|
||||
|
||||
// delete (void *)e and delete[] (void *)e result in undefined behaviour
|
||||
// [expr.delete/3]. Check we warn about them
|
||||
// operator new functions can only return NULL, if their exceptions
|
||||
// specification is `throw()'. All other cases must return a non-null pointer
|
||||
// [expr.new/13].
|
||||
|
||||
void *operator new(unsigned)
|
||||
{
|
||||
return 0; // ERROR - cannot return NULL
|
||||
}
|
||||
void *operator new[](unsigned)
|
||||
{
|
||||
return 0; // ERROR - cannot return NULL
|
||||
}
|
||||
|
||||
struct X
|
||||
{
|
||||
void *operator new(unsigned)
|
||||
{
|
||||
return 0; // ERROR - cannot return NULL
|
||||
}
|
||||
void *operator new[](unsigned)
|
||||
{
|
||||
return 0; // ERROR - cannot return NULL
|
||||
}
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
void *operator new(unsigned) throw()
|
||||
{
|
||||
return 0; // ok
|
||||
}
|
||||
void *operator new[](unsigned) throw()
|
||||
{
|
||||
return 0; // ok
|
||||
}
|
||||
};
|
||||
|
||||
void fn(double *d, void *v)
|
||||
{
|
||||
delete d; // ok
|
||||
delete v; // WARNING - deleting void
|
||||
delete[] d; // ok
|
||||
delete[] v; // WARNING - deleting void
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
// Contributed by Nathan Sidwell 15 Apr 1999 <nathan@acm.org>
|
||||
|
||||
struct X
|
||||
{
|
||||
int i;
|
||||
|
||||
X():i(){}
|
||||
void *operator new(unsigned)
|
||||
{
|
||||
return 0; // WARNING - cannot return NULL
|
||||
}
|
||||
void *operator new[](unsigned)
|
||||
{
|
||||
return 0; // WARNING - cannot return NULL
|
||||
}
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
int i;
|
||||
|
||||
Y():i(){}
|
||||
void *operator new(unsigned) throw()
|
||||
{
|
||||
return 0; // ok
|
||||
}
|
||||
void *operator new[](unsigned) throw()
|
||||
{
|
||||
return 0; // ok
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Y *yp = new Y;
|
||||
|
||||
return yp != 0;
|
||||
}
|
|
@ -863,7 +863,7 @@ inline ios::~ios() {
|
|||
|
||||
|
||||
|
||||
if (_arrays) delete [] _arrays;
|
||||
operator delete(_arrays);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue