This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
g++.law/operators24.C and --enable-checking=gcac
- To: gcc-bugs at gcc dot gnu dot org
- Subject: g++.law/operators24.C and --enable-checking=gcac
- From: Zack Weinberg <zack at wolery dot cumb dot org>
- Date: Tue, 6 Jun 2000 10:09:22 -0700
g++.law/operators24.C reads
#include <stddef.h>
struct Link {
void* operator new(size_t, int);
friend void* __builtin_new(size_t);
};
void f() { new(2) Link; }
With GC_ALWAYS_COLLECT defined, this crashes while marking trees. The
crash comes from lang_mark_tree:
15055 if (CAN_HAVE_FULL_LANG_DECL_P (t))
15056 {
15057 ggc_mark_tree (ld->befriending_classes);
15058 ggc_mark_tree (ld->saved_tree);
15059 ggc_mark_tree (ld->cloned_function);
15060 if (!DECL_OVERLOADED_OPERATOR_P (t))
15061 * here * ggc_mark_tree (ld->u2.vtt_parm);
During initialization, we set up a decl node for operator new. It
looks something like this.
<function_decl operator new
type <function_type
type <pointer_type type <void_type void> ...>
...
arg-types <tree_list value <integer_type unsigned int>
chain <tree_list unsigned value <void_type void>>>
throws <tree_list value <record_type bad_alloc>>>
public external QI file <internal> line 0
rtl (mem:QI (symbol_ref:SI ("__builtin_new")) 0)>
DECL_OVERLOADED_OPERATOR_P is true for this decl; that is recorded in
one of the flags of the DECL_NAME. The lang_decl structure reads in
part
$14 = {decl_flags = { ... },
befriending_classes = 0x0, saved_tree = 0x0, cloned_function = 0x0,
u = { sorted_fields = 0x0, ... },
u2 = {operator_code = NEW_EXPR, vtt_parm = 0x93}}
Note that this decl has nothing to do with the local decl of operator
new in struct Link. When we reach the declaration of __builtin_new,
we construct a decl node for that, and call pushdecl. That node looks
like this:
<function_decl __builtin_new
type <function_type
type <pointer_type type <void_type void> ...>
...
arg-types <tree_list value <integer_type unsigned int>
chain <tree_list value <void_type void>>>>
public external QI operators24.C line 12
arguments <parm_decl
type <integer_type size_t>
...>
>
The DECL_ASSEMBLER_NAME of this decl is __builtin_new. The
DECL_ASSEMBLER_NAME of the original decl of operator new is also
__builtin_new. pushdecl therefore calls duplicate_decls (indirectly).
duplicate_decls decides that the two decls are almost the same, and
clobbers the original decl with the new one. It does *not* change the
lang_decl when it does that. We are therefore left with a function_decl
whose DECL_NAME does not have the OVERLOADED_OPERATOR_P flag set, but
whose lang_decl does have an operator code. lang_mark_tree tries to
dereference 0x93 and crashes.
I do not know the appropriate fix. It seems to me that pushdecl
should not consider the user's declaration of __builtin_new to have
anything to do with the automatic default declaration of operator
new. But that might have other undesirable effects. Failing that,
perhaps duplicate_decls should notice that one of these has
DECL_OVERLOADED_OPERATOR_P and one doesn't, and not regard them as
almost the same.
zw