re PR middle-end/27793 (num_ssa_names inconsistent or immediate use iterator wrong)
PR middle-end/27793 * cp-tree.h (cxx_int_tree_map): New struct. (struct language_function): Add extern_decl_map field. * name-lookup.c (pushdecl_maybe_friend): Add x -> t mapping to cp_function_chain->extern_decl_map hash table instead of copying over DECL_UID. * cp-gimplify.c (cxx_int_tree_map_eq, cxx_int_tree_map_hash): New functions. (cp_genericize_r): Remap DECL_EXTERN local decls using cp_function_chain->extern_decl_map hash table. * decl.c (finish_function): Clear extern_decl_map. PR c++/26757 PR c++/27894 * g++.dg/tree-ssa/pr26757.C: New test. * g++.dg/tree-ssa/pr27894.C: New test. From-SVN: r114607
This commit is contained in:
parent
cd8d4e24e0
commit
10827cd8b3
8 changed files with 214 additions and 6 deletions
|
@ -1,3 +1,17 @@
|
|||
2006-06-13 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/27793
|
||||
* cp-tree.h (cxx_int_tree_map): New struct.
|
||||
(struct language_function): Add extern_decl_map field.
|
||||
* name-lookup.c (pushdecl_maybe_friend): Add x -> t mapping
|
||||
to cp_function_chain->extern_decl_map hash table instead of
|
||||
copying over DECL_UID.
|
||||
* cp-gimplify.c (cxx_int_tree_map_eq, cxx_int_tree_map_hash): New
|
||||
functions.
|
||||
(cp_genericize_r): Remap DECL_EXTERN local decls using
|
||||
cp_function_chain->extern_decl_map hash table.
|
||||
* decl.c (finish_function): Clear extern_decl_map.
|
||||
|
||||
2006-06-12 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||
|
||||
PR c++/27601
|
||||
|
|
|
@ -601,6 +601,24 @@ is_invisiref_parm (tree t)
|
|||
&& DECL_BY_REFERENCE (t));
|
||||
}
|
||||
|
||||
/* Return true if the uid in both int tree maps are equal. */
|
||||
|
||||
int
|
||||
cxx_int_tree_map_eq (const void *va, const void *vb)
|
||||
{
|
||||
const struct cxx_int_tree_map *a = (const struct cxx_int_tree_map *) va;
|
||||
const struct cxx_int_tree_map *b = (const struct cxx_int_tree_map *) vb;
|
||||
return (a->uid == b->uid);
|
||||
}
|
||||
|
||||
/* Hash a UID in a cxx_int_tree_map. */
|
||||
|
||||
unsigned int
|
||||
cxx_int_tree_map_hash (const void *item)
|
||||
{
|
||||
return ((const struct cxx_int_tree_map *)item)->uid;
|
||||
}
|
||||
|
||||
/* Perform any pre-gimplification lowering of C++ front end trees to
|
||||
GENERIC. */
|
||||
|
||||
|
@ -620,6 +638,25 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Map block scope extern declarations to visible declarations with the
|
||||
same name and type in outer scopes if any. */
|
||||
if (cp_function_chain->extern_decl_map
|
||||
&& (TREE_CODE (stmt) == FUNCTION_DECL || TREE_CODE (stmt) == VAR_DECL)
|
||||
&& DECL_EXTERNAL (stmt))
|
||||
{
|
||||
struct cxx_int_tree_map *h, in;
|
||||
in.uid = DECL_UID (stmt);
|
||||
h = (struct cxx_int_tree_map *)
|
||||
htab_find_with_hash (cp_function_chain->extern_decl_map,
|
||||
&in, in.uid);
|
||||
if (h)
|
||||
{
|
||||
*stmt_p = h->to;
|
||||
*walk_subtrees = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Other than invisiref parms, don't walk the same tree twice. */
|
||||
if (pointer_set_contains (p_set, stmt))
|
||||
{
|
||||
|
|
|
@ -721,6 +721,15 @@ struct saved_scope GTY(())
|
|||
|
||||
extern GTY(()) struct saved_scope *scope_chain;
|
||||
|
||||
struct cxx_int_tree_map GTY(())
|
||||
{
|
||||
unsigned int uid;
|
||||
tree to;
|
||||
};
|
||||
|
||||
extern unsigned int cxx_int_tree_map_hash (const void *);
|
||||
extern int cxx_int_tree_map_eq (const void *, const void *);
|
||||
|
||||
/* Global state pertinent to the current function. */
|
||||
|
||||
struct language_function GTY(())
|
||||
|
@ -747,6 +756,7 @@ struct language_function GTY(())
|
|||
htab_t GTY((param_is(struct named_label_entry))) x_named_labels;
|
||||
struct cp_binding_level *bindings;
|
||||
VEC(tree,gc) *x_local_names;
|
||||
htab_t GTY((param_is (struct cxx_int_tree_map))) extern_decl_map;
|
||||
};
|
||||
|
||||
/* The current C++-specific per-function global variables. */
|
||||
|
|
|
@ -11102,6 +11102,7 @@ finish_function (int flags)
|
|||
f->x_vtt_parm = NULL;
|
||||
f->x_return_value = NULL;
|
||||
f->bindings = NULL;
|
||||
f->extern_decl_map = NULL;
|
||||
|
||||
/* Handle attribute((warn_unused_result)). Relies on gimple input. */
|
||||
c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
|
||||
|
|
|
@ -670,14 +670,28 @@ pushdecl_maybe_friend (tree x, bool is_friend)
|
|||
if (decls_match (x, t))
|
||||
/* The standard only says that the local extern
|
||||
inherits linkage from the previous decl; in
|
||||
particular, default args are not shared. We must
|
||||
also tell cgraph to treat these decls as the same,
|
||||
or we may neglect to emit an "unused" static - we
|
||||
do this by making the DECL_UIDs equal, which should
|
||||
be viewed as a kludge. FIXME. */
|
||||
particular, default args are not shared. Add
|
||||
the decl into a hash table to make sure only
|
||||
the previous decl in this case is seen by the
|
||||
middle end. */
|
||||
{
|
||||
struct cxx_int_tree_map *h;
|
||||
void **loc;
|
||||
|
||||
TREE_PUBLIC (x) = TREE_PUBLIC (t);
|
||||
DECL_UID (x) = DECL_UID (t);
|
||||
|
||||
if (cp_function_chain->extern_decl_map == NULL)
|
||||
cp_function_chain->extern_decl_map
|
||||
= htab_create_ggc (20, cxx_int_tree_map_hash,
|
||||
cxx_int_tree_map_eq, NULL);
|
||||
|
||||
h = GGC_NEW (struct cxx_int_tree_map);
|
||||
h->uid = DECL_UID (x);
|
||||
h->to = t;
|
||||
loc = htab_find_slot_with_hash
|
||||
(cp_function_chain->extern_decl_map, h,
|
||||
h->uid, INSERT);
|
||||
*(struct cxx_int_tree_map **) loc = h;
|
||||
}
|
||||
}
|
||||
else if (TREE_CODE (t) == PARM_DECL)
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2006-06-13 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/27894
|
||||
* g++.dg/tree-ssa/pr26757.C: New test.
|
||||
* g++.dg/tree-ssa/pr27894.C: New test.
|
||||
|
||||
2006-06-13 Maxim Kuvyrkov <mkuvyrkov@ispras.ru>
|
||||
|
||||
* gcc.c-torture/compile/20060609-1.c: New test.
|
||||
|
|
44
gcc/testsuite/g++.dg/tree-ssa/pr26757.C
Normal file
44
gcc/testsuite/g++.dg/tree-ssa/pr26757.C
Normal file
|
@ -0,0 +1,44 @@
|
|||
// PR c++/26757
|
||||
// { dg-do run }
|
||||
// { dg-options "-O" }
|
||||
|
||||
extern "C" void abort ();
|
||||
|
||||
typedef struct A
|
||||
{
|
||||
int c;
|
||||
int d;
|
||||
} A;
|
||||
|
||||
A *b;
|
||||
|
||||
void
|
||||
foo ()
|
||||
{
|
||||
b->c++;
|
||||
extern A *b;
|
||||
b->d++;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
bar ()
|
||||
{
|
||||
if (b->d)
|
||||
b->c++;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
A a = { 0, 0 };
|
||||
b = &a;
|
||||
foo ();
|
||||
bar ();
|
||||
if (b->c != 2)
|
||||
abort ();
|
||||
if (b->d != 1)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
82
gcc/testsuite/g++.dg/tree-ssa/pr27894.C
Normal file
82
gcc/testsuite/g++.dg/tree-ssa/pr27894.C
Normal file
|
@ -0,0 +1,82 @@
|
|||
// PR c++/27894
|
||||
// { dg-do compile }
|
||||
// { dg-options "-O" }
|
||||
|
||||
class A;
|
||||
struct B
|
||||
{
|
||||
B (unsigned long);
|
||||
int b2 () const;
|
||||
A *b1 () const;
|
||||
};
|
||||
|
||||
enum { P = 0 };
|
||||
enum O { Q = 75, };
|
||||
class C;
|
||||
struct D { A *d; };
|
||||
struct E
|
||||
{
|
||||
B e1 (int) const;
|
||||
A *e2 (const B &) const;
|
||||
D e3[4096];
|
||||
};
|
||||
|
||||
inline A *
|
||||
E::e2 (const B & x) const
|
||||
{
|
||||
const D *w = &e3[x.b2 ()];
|
||||
return (A *) w->d;
|
||||
}
|
||||
|
||||
extern E *e;
|
||||
|
||||
inline A *
|
||||
B::b1 () const
|
||||
{
|
||||
extern E *e;
|
||||
return e->e2 (*this);
|
||||
}
|
||||
|
||||
template <class T> struct F : public B
|
||||
{
|
||||
F (const B &);
|
||||
T *b1 () const;
|
||||
};
|
||||
|
||||
template < class T > inline T * F <T>::b1 () const
|
||||
{
|
||||
return (T *) B::b1 ();
|
||||
};
|
||||
|
||||
typedef F <C> N;
|
||||
|
||||
class G {};
|
||||
class H : public G {};
|
||||
class I : public H {};
|
||||
class J {};
|
||||
class K {};
|
||||
struct L
|
||||
{
|
||||
void l (J *, C *, int, const char *, O);
|
||||
};
|
||||
class M : public K, public I
|
||||
{
|
||||
void m (J &, int, const char *);
|
||||
void m (J &, int, int, const char *, float);
|
||||
};
|
||||
|
||||
void
|
||||
M::m (J &x, int y, const char *z)
|
||||
{
|
||||
L *w = new L;
|
||||
N v = e->e1 (y);
|
||||
w->l (&x, v.b1 (), P, z, Q);
|
||||
}
|
||||
|
||||
void
|
||||
M::m (J &x, int y, int s, const char *z, float t)
|
||||
{
|
||||
L *w = new L;
|
||||
N v = e->e1 (y);
|
||||
w->l (&x, v.b1 (), s, z, (O) (int) ((t) ? (50 + 20 / (float) t) : 0));
|
||||
}
|
Loading…
Add table
Reference in a new issue