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

[Bug c++/26757] [4.1 regression] ICE (Segmentation fault) building 3ddesktop source



------- Comment #10 from amacleod at redhat dot com  2006-04-06 21:05 -------
using the program from comment #5, I get IL for load_background_image that
looks like:

void load_background_image() ()
{
  int D.1767;
  int D.1766;
  struct Config * cfg.2;
  int D.1764;
  int D.1763;
  struct Config * cfg.1;

<bb 0>:
  cfg.1 = cfg;
  D.1763 = cfg.1->bg_size;
  D.1764 = D.1763 + 1;
  cfg.1->bg_size = D.1764;
  cfg.2 = cfg;
  D.1766 = cfg.2->autoacquire;
  D.1767 = D.1766 + 1;
  cfg.2->autoacquire = D.1767;
  return;

}

THe two assignments of cfg into temps,  (cfg.1 and cfg.2) are using DIFFERENT
cfg variables (ie, different addresses) on the RHS with the same UID.  very
bad.  either they should be the same var_decl (which I presume is what is
intended), or they should have different UIDs.  

This patchlet provides an assert the triggers when it happens:

Index: tree-dfa.c
===================================================================
*** tree-dfa.c  (revision 112248)
--- tree-dfa.c  (working copy)
*************** referenced_var_insert (unsigned int uid,
*** 610,615 ****
--- 610,619 ----
    h->uid = uid;
    h->to = to;
    loc = htab_find_slot_with_hash (referenced_vars, h, uid, INSERT);
+   /* This assert can only trigger is a variable with the same UID has been
+      inserted already, but has a different pointer value. ie, we have 2
+      different variables with the same UID.  Bug 26757.  */
+   gcc_assert ((*(struct int_tree_map **)loc) == NULL);
    *(struct int_tree_map **)  loc = h;
  }


what happens is that the referenced_var list hashes based on the UID of a
variable. referenced_var_insert is only called when a new variable is
discovered, so it presumes that the hash slot is already empty.

add_referenced_var calls referenced_var_insert when it sees a new variable, and
it determines a variable is new by hashing on the address of the variable in
the walk_state->vars_found table. 

since there are 2 different 'cfg' vars, referenced_var_insert overwrote the
first 'cfg''s address when it looked up the UID. 

WHen we go out of ssa, delete_tree_ssa removes all the var annotations of
referenced vars. The original 'cfg' no longer occurs in the referenced var
list, so it is not cleared.

Along comes the next function, and it is using the original 'cfg', and voila,
it still has a var_annotation, complete with current_def and lots of fun things
set.


I havent tracked down where the cfg variable is created, but Im willing to bet
a C++ front end person knows right off the bat by looking at the function.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26757


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