This is the mail archive of the gcc-patches@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]

[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" }
}



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