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]

Re: G++ PATCH: alignof incomplete type


Jason Merrill wrote:
> 
> Why did you move the function/method case?  There's no such thing as an
> incomplete function type.
I was thinking of overloaded fns, but it doesn't work that way (and
it made it easier for me to understand the code). Here's an updated
patch and test case. The differences from the previous patch are,
1) minimal changes to c_alignof. Add assert to make sure alignment is
positive. We currently return alignment of zero in some erroneous cases,
make sure it doesn't happen again.
2) grok_alignof explicitly checks for is_overloaded_fn, and returns the
function boundary alignment. The current behaviour is to hand c_alignof
an unknown type, which then gives an alignment of zero, with the previous
patch it would complain about an incomplete type.

Thus
	__alignof__(overloaded_function_name); // function boundary alignment
	__alignof__(&non_overloaded_function);  // function pointer alignment
	__alignof__(&overloaded_function_name); // incomplete type error
	__alignof__((Proc_t)&overloaded_function_name); // function pointer alignment

this one ok?

nathan

-- 
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
Never hand someone a gun unless you are sure where they will point it
nathan@acm.org  http://www.cs.bris.ac.uk/~nathan/  nathan@cs.bris.ac.uk
// Build don't link:

// Copyright (C) 1999 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 7 Dec 1999 <nathan@acm.org>

// __alignof__ shouldn't allow incomplete types, but does allow void

void fn (int);

struct X;   // ERROR - forward ref

void foo (void *vp)
{
  fn (__alignof__ (void));
  fn (__alignof__ (void *));
  fn (__alignof__ (vp));
}

void foo (X *xp)
{
  fn (__alignof__ (X));     // ERROR - incomplete
  fn (__alignof__ (X *));
  fn (__alignof__ (*xp));   // ERROR - incomplete
  fn (__alignof__ (xp));
}

void foo (X &xr)
{
  fn (__alignof__ (X &));   // ERROR - incomplete
  fn (__alignof__ (xr));    // ERROR - incomplete
}

template <class T> void baz (T);
struct Y
{
  void fn ();
  void fn (int);
};
template <class T> struct Z;
template <class T> struct W
{
  typedef void (*Fptr)(T);
};

void foo ()
{
  fn (__alignof__ (foo));
  fn (__alignof__ (&foo));  // ERROR - incomplete
  fn (__alignof__ (Y::fn));
  fn (__alignof__ (&Y::fn));// ERROR - incomplete
  fn (__alignof__ (baz));
  fn (__alignof__ (fn));
  fn (__alignof__ ((void (*)())foo));
  fn (__alignof__ (*(void (*)())foo));
  fn (__alignof__ (baz<int>));
  fn (__alignof__ ((void (Y::*)())&Y::fn));
  fn (__alignof__ (void (Z<int>)));
  fn (__alignof__ (W<int>::Fptr));
}
1999-12-09  Nathan Sidwell  <nathan@acm.org>

	* decl2.c (grok_alignof): Return function alignment for
	overloaded functions.
	
	* typeck.c (c_alignof): Don't allow incomplete types, other than
	void. Assert that alignment is sane.

Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.287
diff -c -3 -p -r1.287 decl2.c
*** decl2.c	1999/12/05 00:37:56	1.287
--- decl2.c	1999/12/09 10:06:10
*************** grok_alignof (expr)
*** 1053,1059 ****
        return c_alignof (TREE_TYPE (TREE_TYPE (best)));
      }
    else
!     return c_alignof (TREE_TYPE (expr));
  }
  
  /* Create an ARRAY_REF, checking for the user doing things backwards
--- 1053,1063 ----
        return c_alignof (TREE_TYPE (TREE_TYPE (best)));
      }
    else
!     {
!       if (is_overloaded_fn (expr))
!         return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
!       return c_alignof (TREE_TYPE (expr));
!     }
  }
  
  /* Create an ARRAY_REF, checking for the user doing things backwards
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.227
diff -c -3 -p -r1.227 typeck.c
*** typeck.c	1999/12/01 18:09:09	1.227
--- typeck.c	1999/12/09 10:06:19
*************** c_alignof (type)
*** 1659,1664 ****
--- 1659,1665 ----
  {
    enum tree_code code = TREE_CODE (type);
    tree t;
+   int alignment;
  
    if (processing_template_decl)
      return build_min (ALIGNOF_EXPR, sizetype, type);
*************** c_alignof (type)
*** 1666,1679 ****
    if (code == FUNCTION_TYPE || code == METHOD_TYPE)
      return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
  
!   if (code == VOID_TYPE || code == ERROR_MARK)
      return size_int (1);
! 
    /* C++: this is really correct!  */
    if (code == REFERENCE_TYPE)
      type = TREE_TYPE (type);
  
!   t = size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
    force_fit_type (t, 0);
    return t;
  }
--- 1667,1686 ----
    if (code == FUNCTION_TYPE || code == METHOD_TYPE)
      return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
  
!   if (code == VOID_TYPE)
      return size_int (1);
!   
    /* C++: this is really correct!  */
    if (code == REFERENCE_TYPE)
      type = TREE_TYPE (type);
  
!   type = complete_type_or_else (type, NULL_TREE);
!   if (!type)
!     return error_mark_node;
!   
!   alignment = TYPE_ALIGN (type) / BITS_PER_UNIT;
!   my_friendly_assert (alignment > 0, 19991209);
!   t = size_int (alignment);
    force_fit_type (t, 0);
    return t;
  }

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