re PR c++/16889 (ambiguity is not detected)

cp:
	PR c++/16889
	* search.c (lookup_field_queue_p): Correct check for hidden base.

	* search.c (bfs_walk): Remove.
	(lookup_member): Use dfs_walk_real.
	(dfs_walk_real): Move and adjust documentation from bfs_walk.
testsuite:
	PR c++/16889
	* g++.dg/lookup/ambig3.C: New.

From-SVN: r88037
This commit is contained in:
Nathan Sidwell 2004-09-24 14:04:58 +00:00 committed by Nathan Sidwell
parent c5466b25b4
commit 5cf447dbf1
4 changed files with 47 additions and 101 deletions

View File

@ -1,3 +1,12 @@
2004-09-24 Nathan Sidwell <nathan@codesourcery.com>
PR c++/16889
* search.c (lookup_field_queue_p): Correct check for hidden base.
* search.c (bfs_walk): Remove.
(lookup_member): Use dfs_walk_real.
(dfs_walk_real): Move and adjust documentation from bfs_walk.
2004-09-23 Zack Weinberg <zack@codesourcery.com>
* decl.c (grokfndecl): If ::main is found not to return int,

View File

@ -57,8 +57,6 @@ static tree split_conversions (tree, tree, tree, tree);
static int lookup_conversions_r (tree, int, int,
tree, tree, tree, tree, tree *, tree *);
static int look_for_overrides_r (tree, tree);
static tree bfs_walk (tree, tree (*) (tree, void *),
tree (*) (tree, int, void *), void *);
static tree lookup_field_queue_p (tree, int, void *);
static int shared_member_p (tree);
static tree lookup_field_r (tree, void *);
@ -991,7 +989,7 @@ lookup_field_queue_p (tree derived, int ix, void *data)
/* If this base class is hidden by the best-known value so far, we
don't need to look. */
if (lfi->rval_binfo && original_binfo (binfo, lfi->rval_binfo))
if (lfi->rval_binfo && derived == lfi->rval_binfo)
return NULL_TREE;
/* If this is a dependent base, don't look in it. */
@ -1256,7 +1254,8 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type)
lfi.type = type;
lfi.name = name;
lfi.want_type = want_type;
bfs_walk (basetype_path, &lookup_field_r, &lookup_field_queue_p, &lfi);
dfs_walk_real (basetype_path, &lookup_field_r, 0,
&lookup_field_queue_p, &lfi);
rval = lfi.rval;
rval_binfo = lfi.rval_binfo;
if (rval_binfo)
@ -1513,101 +1512,16 @@ adjust_result_of_qualified_name_lookup (tree decl,
}
/* Walk the class hierarchy dominated by TYPE. FN is called for each
type in the hierarchy, in a breadth-first preorder traversal.
If it ever returns a non-NULL value, that value is immediately
returned and the walk is terminated. At each node, FN is passed a
BINFO indicating the path from the currently visited base-class to
TYPE. Before each base-class is walked QFN is called. If the
value returned is nonzero, the base-class is walked; otherwise it
is not. If QFN is NULL, it is treated as a function which always
returns 1. Both FN and QFN are passed the DATA whenever they are
called.
Implementation notes: Uses a circular queue, which starts off on
the stack but gets moved to the malloc arena if it needs to be
enlarged. The underflow and overflow conditions are
indistinguishable except by context: if head == tail and we just
moved the head pointer, the queue is empty, but if we just moved
the tail pointer, the queue is full.
Start with enough room for ten concurrent base classes. That
will be enough for most hierarchies. */
#define BFS_WALK_INITIAL_QUEUE_SIZE 10
static tree
bfs_walk (tree binfo,
tree (*fn) (tree, void *),
tree (*qfn) (tree, int, void *),
void *data)
{
tree rval = NULL_TREE;
tree bases_initial[BFS_WALK_INITIAL_QUEUE_SIZE];
/* A circular queue of the base classes of BINFO. These will be
built up in breadth-first order, except where QFN prunes the
search. */
size_t head, tail;
size_t base_buffer_size = BFS_WALK_INITIAL_QUEUE_SIZE;
tree *base_buffer = bases_initial;
head = tail = 0;
base_buffer[tail++] = binfo;
while (head != tail)
{
int n_bases, ix;
tree binfo = base_buffer[head++];
if (head == base_buffer_size)
head = 0;
/* Is this the one we're looking for? If so, we're done. */
rval = fn (binfo, data);
if (rval)
goto done;
n_bases = BINFO_N_BASE_BINFOS (binfo);
for (ix = 0; ix != n_bases; ix++)
{
tree base_binfo;
if (qfn)
base_binfo = (*qfn) (binfo, ix, data);
else
base_binfo = BINFO_BASE_BINFO (binfo, ix);
if (base_binfo)
{
base_buffer[tail++] = base_binfo;
if (tail == base_buffer_size)
tail = 0;
if (tail == head)
{
tree *new_buffer = xmalloc (2 * base_buffer_size
* sizeof (tree));
memcpy (&new_buffer[0], &base_buffer[0],
tail * sizeof (tree));
memcpy (&new_buffer[head + base_buffer_size],
&base_buffer[head],
(base_buffer_size - head) * sizeof (tree));
if (base_buffer_size != BFS_WALK_INITIAL_QUEUE_SIZE)
free (base_buffer);
base_buffer = new_buffer;
head += base_buffer_size;
base_buffer_size *= 2;
}
}
}
}
done:
if (base_buffer_size != BFS_WALK_INITIAL_QUEUE_SIZE)
free (base_buffer);
return rval;
}
/* Exactly like bfs_walk, except that a depth-first traversal is
performed, and PREFN is called in preorder, while POSTFN is called
in postorder. */
/* Walk the class hierarchy within BINFO, in a depth-first traversal.
PREFN is called in preorder, while POSTFN is called in postorder.
If they ever returns a non-NULL value, that value is immediately
returned and the walk is terminated. Both PREFN and POSTFN can be
NULL. At each node, PREFN and POSTFN are passed the binfo to
examine. Before each base-binfo of BINFO is walked, QFN is called.
If the value returned is nonzero, the base-binfo is walked;
otherwise it is not. If QFN is NULL, it is treated as a function
which always returns 1. All callbacks are passed DATA whenever
they are called. */
tree
dfs_walk_real (tree binfo,
@ -1649,8 +1563,8 @@ dfs_walk_real (tree binfo,
return rval;
}
/* Exactly like bfs_walk, except that a depth-first post-order traversal is
performed. */
/* Exactly like dfs_walk_real, except that there is no pre-order
function call and FN is called in post-order. */
tree
dfs_walk (tree binfo,

View File

@ -1,3 +1,8 @@
2004-08-24 Nathan Sidwell <nathan@codesourcery.com>
PR c++/16889
* g++.dg/lookup/ambig3.C: New.
2004-09-24 Andrew Pinski <pinskia@physics.uc.edu>
PR tree-opt/17624

View File

@ -0,0 +1,18 @@
// { dg-do compile }
// Copyright (C) 2004 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 23 Sep 2004 <nathan@codesourcery.com>
// Origin: Wolfgang Bangerth <bangerth@dealii.org>
// Follow on from Bug 16889:Undetected ambiguity.
struct B {
int f(); // { dg-error "int B::f" "" }
};
struct B1 : virtual B {};
struct B2 : B {};
struct B2_2 : B2 {};
struct BB : B1, B2_2 {};
int i = BB().f(); // { dg-error "ambiguous" "" }