This fixes part of PR52582, we need to create a cgraph node when
folding from an initializer.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2012-03-14  Richard Guenther  <rguent...@suse.de>

        PR middle-end/52582
        * gimple-fold.c (canonicalize_constructor_val): Make sure
        we have a cgraph node for a FUNCTION_DECL that comes from
        a constructor.
        (gimple_get_virt_method_for_binfo): Likewise.

Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c   (revision 185379)
--- gcc/gimple-fold.c   (working copy)
*************** canonicalize_constructor_val (tree cval)
*** 131,148 ****
    if (TREE_CODE (cval) == ADDR_EXPR)
      {
        tree base = get_base_address (TREE_OPERAND (cval, 0));
  
!       if (base
!         && (TREE_CODE (base) == VAR_DECL
!             || TREE_CODE (base) == FUNCTION_DECL)
          && !can_refer_decl_in_current_unit_p (base))
        return NULL_TREE;
!       if (base && TREE_CODE (base) == VAR_DECL)
        {
          TREE_ADDRESSABLE (base) = 1;
          if (cfun && gimple_referenced_vars (cfun))
            add_referenced_var (base);
        }
        /* Fixup types in global initializers.  */
        if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0)))
        cval = build_fold_addr_expr (TREE_OPERAND (cval, 0));
--- 131,156 ----
    if (TREE_CODE (cval) == ADDR_EXPR)
      {
        tree base = get_base_address (TREE_OPERAND (cval, 0));
+       if (!base)
+       return NULL_TREE;
  
!       if ((TREE_CODE (base) == VAR_DECL
!          || TREE_CODE (base) == FUNCTION_DECL)
          && !can_refer_decl_in_current_unit_p (base))
        return NULL_TREE;
!       if (TREE_CODE (base) == VAR_DECL)
        {
          TREE_ADDRESSABLE (base) = 1;
          if (cfun && gimple_referenced_vars (cfun))
            add_referenced_var (base);
        }
+       else if (TREE_CODE (base) == FUNCTION_DECL)
+       {
+         /* Make sure we create a cgraph node for functions we'll reference.
+            They can be non-existent if the reference comes from an entry
+            of an external vtable for example.  */
+         cgraph_get_create_node (base);
+       }
        /* Fixup types in global initializers.  */
        if (TREE_TYPE (TREE_TYPE (cval)) != TREE_TYPE (TREE_OPERAND (cval, 0)))
        cval = build_fold_addr_expr (TREE_OPERAND (cval, 0));
*************** gimple_get_virt_method_for_binfo (HOST_W
*** 3115,3120 ****
--- 3123,3133 ----
    if (!can_refer_decl_in_current_unit_p (fn))
      return NULL_TREE;
  
+   /* Make sure we create a cgraph node for functions we'll reference.
+      They can be non-existent if the reference comes from an entry
+      of an external vtable for example.  */
+   cgraph_get_create_node (fn);
+ 
    return fn;
  }
  

Reply via email to