This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] [PR15967] Fix ICE with ambiguous operator new
- From: "Giovanni Bajo" <giovannibajo at libero dot it>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 14 Jun 2004 12:43:47 +0200
- Subject: [C++ PATCH] [PR15967] Fix ICE with ambiguous operator new
Hello,
this ICE (regression on the trunk and the 3.4 branch) was happening in init.c
(build_new_1), while compiling a testcase with an ambiguous operator new in a
class: after having checked that the type has an operator new (with
TYPE_HAS_[ARRAY_]NEW_OPERATOR), the code was calling lookup_fnfields with
protect=2, and then checking if there was ambiguity (the return value is a
TREE_LIST of the DECLs). But the function was returning NULL_TREE, which was
not expected.
In fact, when looking up functions, lookup_member with protect=2 returns either
NULL_TREE (nothing found), TREE_LIST (ambiguity list) or BASELINK (member
function). lookup_fnfields was supposed to be a filtered version of
lookup_member which filters regular fields away (just like its opposite,
lookup_field). But, the logic of lookup_fnfields was wrong and was also
filtering away the TREE_LISTS (making protect=2 useless).
My patch makes lookup_fnfields do the right thing with the ambiguity lists
(which are TREE_LISTs with type set to ERROR_MARK_NODE, so they can be checked
with error_operand_p). For simmetry, I made sure lookup_field does the same.
Robustifying build_new_1 to check for NULL_TREEs would have not been correct,
as lookup_fnfields should never return NULL_TREE there: at that point, we
already know that there is an operator new, so the only possible problem could
be that it is ambiguous.
Tested on i686-pc-linux-gnu. OK for mainline? OK for 3.4.1 (looks trivial
enough)?
Giovanni Bajo
cp/
* search.c (lookup_field): Propagate the ambiguity list.
(lookup_fnfields): Likewise.
testsuite/
* g++.dg/lookup/crash3.C: New test.
Index: search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.291
diff -c -3 -p -r1.291 search.c
*** search.c 19 Mar 2004 14:18:27 -0000 1.291
--- search.c 14 Jun 2004 02:27:41 -0000
*************** lookup_field (tree xbasetype, tree name,
*** 1332,1339 ****
{
tree rval = lookup_member (xbasetype, name, protect, want_type);
! /* Ignore functions. */
! if (rval && BASELINK_P (rval))
return NULL_TREE;
return rval;
--- 1332,1340 ----
{
tree rval = lookup_member (xbasetype, name, protect, want_type);
! /* Ignore functions, but propagate the ambiguity list. */
! if (!error_operand_p (rval)
! && (rval && BASELINK_P (rval)))
return NULL_TREE;
return rval;
*************** lookup_fnfields (tree xbasetype, tree na
*** 1347,1354 ****
{
tree rval = lookup_member (xbasetype, name, protect, /*want_type=*/false);
! /* Ignore non-functions. */
! if (rval && !BASELINK_P (rval))
return NULL_TREE;
return rval;
--- 1348,1356 ----
{
tree rval = lookup_member (xbasetype, name, protect, /*want_type=*/false);
! /* Ignore non-functions, but propagate the ambiguity list. */
! if (!error_operand_p (rval)
! && (rval && !BASELINK_P (rval)))
return NULL_TREE;
return rval;
// { dg-do compile }
// Contributed by Wolfgang Wieser <wwieser at gmx dot de>
// PR c++/15967: ICE with ambiguous operator new
typedef unsigned int size_t;
struct A { void *operator new(size_t s){} }; // { dg-error "operator new" }
struct B { void *operator new(size_t s){} }; // { dg-error "operator new" }
struct C : A,B {};
int crash()
{
C *c=new C(); // { dg-error "ambiguous" }
}