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]

[tree-ssa] PATCH to C++ alias handling


In recent discussion of alias sets, it came up that the C++ front end
doesn't do alias analysis for classes with virtual bases.  This seems
unnecessary to me; the aliasing rules in the standard say nothing about
virtual bases, they just say which object types can be accessed through
which pointer types.  This is the same argument as for zero-size bases;
layout is not relevant.

The patch below was tested on x86_64-pc-linux-gnu and applied to the
tree-ssa branch (because it's not a bugfix).

I also tried to make pmfs work, but that turned out to be rather
complicated.  g++.dg/opt/ptrmem1.C is an example that fails if we just
remove the check for PMFs, because the type of the method and the type of
the pointer are different because of the default argument.

But the same sort of problem can crop up in C: here's a testcase which is
currently miscompiled because we don't canonicalize function types.

  typedef int foo;
  int f (foo *p) { return 1; }
  int g (int *p) { return 0; }

  void h (int (***pp2)(int *), int (**pp1)(foo *)) { *pp2 = pp1; }

  int main()
  {
    int (*p1)(foo *);
    int (**p2)(int *);

    h (&p2, &p1);
    p1 = f;
    *p2 = g;
    return p1(0);
  }

I have a patch in progress that adds canonicalized versions of function
types in their TYPE_MAIN_VARIANT; does that seem like the right approach to
other people?

2004-01-12  Jason Merrill  <jason@redhat.com>

	* cp-lang.c (ok_to_generate_alias_set_for_type): Remove.
	(cxx_get_alias_set): Allow all types.

*** cp-lang.c.~1~	2004-01-05 15:06:20.000000000 -0500
--- cp-lang.c	2004-01-12 18:50:26.000000000 -0500
*************** Boston, MA 02111-1307, USA.  */
*** 35,41 ****
  enum c_language_kind c_language = clk_cxx;
  
  static HOST_WIDE_INT cxx_get_alias_set (tree);
- static bool ok_to_generate_alias_set_for_type (tree);
  static bool cxx_warn_unused_global_decl (tree);
  static tree cp_expr_size (tree);
  static size_t cp_tree_size (enum tree_code);
--- 35,40 ----
*************** const char *const tree_code_name[] = {
*** 234,293 ****
  };
  #undef DEFTREECODE
  
- /* Check if a C++ type is safe for aliasing.
-    Return TRUE if T safe for aliasing FALSE otherwise.  */
- 
- static bool
- ok_to_generate_alias_set_for_type (tree t)
- {
-   if (TYPE_PTRMEMFUNC_P (t))
-     return true;
-   if (AGGREGATE_TYPE_P (t))
-     {
-       if ((TREE_CODE (t) == RECORD_TYPE) || (TREE_CODE (t) == UNION_TYPE))
- 	{
- 	  tree fields;
- 	  /* Backend-created structs are safe.  */
- 	  if (! CLASS_TYPE_P (t))
- 	    return true;
- 	  /* PODs are safe.  */
- 	  if (! CLASSTYPE_NON_POD_P(t))
- 	    return true;
- 	  /* Classes with virtual baseclasses are not.  */
- 	  if (TYPE_USES_VIRTUAL_BASECLASSES (t))
- 	    return false;
- 	  /* Recursively check the base classes.  */
- 	  if (TYPE_BINFO (t) != NULL && TYPE_BINFO_BASETYPES (t) != NULL)
- 	    {
- 	      int i;
- 	      for (i = 0; i < TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (t)); i++)
- 		{
- 		  tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i);
- 		  if (!ok_to_generate_alias_set_for_type (BINFO_TYPE (binfo)))
- 		    return false;
- 		}
- 	    }
- 	  /* Check all the fields.  */
- 	  for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields))
- 	    {
- 	      if (TREE_CODE (fields) != FIELD_DECL)
- 		continue;
- 	      if (! ok_to_generate_alias_set_for_type (TREE_TYPE (fields)))
- 		return false;
- 	    }
- 	  return true;
- 	}
-       else if (TREE_CODE (t) == ARRAY_TYPE)
- 	return ok_to_generate_alias_set_for_type (TREE_TYPE (t));
-       else
- 	/* This should never happen, we dealt with all the aggregate
- 	   types that can appear in C++ above.  */
- 	abort ();
-     }
-   else
-     return true;
- }
- 
  /* Special routine to get the alias set for C++.  */
  
  static HOST_WIDE_INT
--- 233,238 ----
*************** cxx_get_alias_set (tree t)
*** 300,312 ****
         complete type.  */
      return get_alias_set (TYPE_CONTEXT (t));
    
!   if (/* It's not yet safe to use alias sets for some classes in C++.  */
!       !ok_to_generate_alias_set_for_type (t)
!       /* Nor is it safe to use alias sets for pointers-to-member
! 	 functions, due to the fact that there may be more than one
! 	 RECORD_TYPE type corresponding to the same pointer-to-member
! 	 type.  */
!       || TYPE_PTRMEMFUNC_P (t))
      return 0;
  
    return c_common_get_alias_set (t);
--- 245,252 ----
         complete type.  */
      return get_alias_set (TYPE_CONTEXT (t));
    
!   /* Punt on PMFs until we canonicalize functions properly.  */
!   if (TYPE_PTRMEMFUNC_P (t))
      return 0;
  
    return c_common_get_alias_set (t);

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