Patch for alignof problems in templates

Mark Mitchell mmitchell@usa.net
Wed Jan 28 15:03:00 GMT 1998


Ulrich --

  You reported two problems using alignof in templates, one with a
homegrown alignof macro, and one with the builtin __alignof__.  The
first was already fixed in the development sources; you ran into
trouble because local classes in templates caused crashes.

  This patch fixes the problem you reported with the __alignof__
keyword, and, as a bonus, fixes a problem with both sizeof/__alignof__
in explicit template arguments where expressions like

  foo<sizeof(T) + 7>

were not being subjected to constant-folding.

-- 
Mark Mitchell		mmitchell@usa.net
Stanford University	http://www.stanford.edu

Wed Jan 28 11:51:31 1998  Mark Mitchell  <mmitchell@usa.net>

	* cp-tree.def (ALIGNOF_EXPR): New tree code.
	* decl2.c (grok_alignof): If processing_template_decl, just store
	the expression.
	* typeck.c (c_alignof): Likewise.
	* decl2.c (build_expr_from_tree): Handle ALIGNOF_EXPR.
	* error.c (dump_expr): Likewise.
	* pt.c (tsubst_copy): Likewise.
	* tree.c (cp_tree_equal): Likewise.
	
	* pt.c (uses_template_parms): Correctly determine whether or not a
	SIZEOF_EXPR/ALIGNOF_EXPR uses template parameters so that constant
	folding can be done.
	
Index: gcc/cp/cp-tree.def
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/cp-tree.def,v
retrieving revision 1.1.1.4
diff -c -p -r1.1.1.4 cp-tree.def
*** cp-tree.def	1998/01/24 04:00:03	1.1.1.4
--- cp-tree.def	1998/01/28 18:22:36
*************** DEFTREECODE (CONST_CAST_EXPR, "const_cas
*** 142,147 ****
--- 142,148 ----
  DEFTREECODE (STATIC_CAST_EXPR, "static_cast_expr", '1', 1)
  DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", '1', 1)
  DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", '1', 1)
+ DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", '1', 1)
  DEFTREECODE (ARROW_EXPR, "arrow_expr", 'e', 1)
  DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", 'e', 2)
  DEFTREECODE (TYPEID_EXPR, "typeid_expr", 'e', 1)
Index: gcc/cp/decl2.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/decl2.c,v
retrieving revision 1.7
diff -c -p -r1.7 decl2.c
*** decl2.c	1998/01/28 15:06:52	1.7
--- decl2.c	1998/01/28 18:38:30
*************** grok_alignof (expr)
*** 1119,1124 ****
--- 1119,1127 ----
    tree best, t;
    int bestalign;
  
+   if (processing_template_decl)
+     return build_min (ALIGNOF_EXPR, sizetype, expr);
+ 
    if (TREE_CODE (expr) == COMPONENT_REF
        && DECL_BIT_FIELD (TREE_OPERAND (expr, 1)))
      error ("`__alignof__' applied to a bit-field");
*************** build_expr_from_tree (t)
*** 3505,3515 ****
  			      build_expr_from_tree (TREE_OPERAND (t, 1)));
  
      case SIZEOF_EXPR:
        {
  	tree r = build_expr_from_tree (TREE_OPERAND (t, 0));
  	if (TREE_CODE_CLASS (TREE_CODE (r)) != 't')
  	  r = TREE_TYPE (r);
! 	return c_sizeof (r);
        }
  
      case MODOP_EXPR:
--- 3508,3519 ----
  			      build_expr_from_tree (TREE_OPERAND (t, 1)));
  
      case SIZEOF_EXPR:
+     case ALIGNOF_EXPR:
        {
  	tree r = build_expr_from_tree (TREE_OPERAND (t, 0));
  	if (TREE_CODE_CLASS (TREE_CODE (r)) != 't')
  	  r = TREE_TYPE (r);
! 	return TREE_CODE (t) == SIZEOF_EXPR ? c_sizeof (r) : c_alignof (r);
        }
  
      case MODOP_EXPR:
Index: gcc/cp/error.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/error.c,v
retrieving revision 1.4
diff -c -p -r1.4 error.c
*** error.c	1998/01/28 01:32:44	1.4
--- error.c	1998/01/28 18:51:28
*************** dump_expr (t, nop)
*** 1630,1636 ****
        break;
  
      case SIZEOF_EXPR:
!       OB_PUTS ("sizeof (");
        if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't')
  	dump_type (TREE_OPERAND (t, 0), 0);
        else
--- 1630,1643 ----
        break;
  
      case SIZEOF_EXPR:
!     case ALIGNOF_EXPR:
!       if (TREE_CODE (t) == SIZEOF_EXPR)
! 	OB_PUTS ("sizeof (");
!       else 
! 	{
! 	  my_friendly_assert (TREE_CODE (t) == ALIGNOF_EXPR, 0);
! 	  OB_PUTS ("__alignof__ (");
! 	}
        if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't')
  	dump_type (TREE_OPERAND (t, 0), 0);
        else
Index: gcc/cp/pt.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/pt.c,v
retrieving revision 1.17
diff -c -p -r1.17 pt.c
*** pt.c	1998/01/28 15:06:53	1.17
--- pt.c	1998/01/28 19:31:13
*************** uses_template_parms (t)
*** 2537,2548 ****
      case CONST_CAST_EXPR:
      case STATIC_CAST_EXPR:
      case DYNAMIC_CAST_EXPR:
-     case SIZEOF_EXPR:
      case ARROW_EXPR:
      case DOTSTAR_EXPR:
      case TYPEID_EXPR:
        return 1;
  
      default:
        switch (TREE_CODE_CLASS (TREE_CODE (t)))
  	{
--- 2537,2551 ----
      case CONST_CAST_EXPR:
      case STATIC_CAST_EXPR:
      case DYNAMIC_CAST_EXPR:
      case ARROW_EXPR:
      case DOTSTAR_EXPR:
      case TYPEID_EXPR:
        return 1;
  
+     case SIZEOF_EXPR:
+     case ALIGNOF_EXPR:
+       return uses_template_parms (TREE_OPERAND (t, 0));
+ 
      default:
        switch (TREE_CODE_CLASS (TREE_CODE (t)))
  	{
*************** tsubst_copy (t, args, nargs, in_decl)
*** 4003,4008 ****
--- 4006,4012 ----
      case ADDR_EXPR:
      case CONVERT_EXPR:      /* Unary + */
      case SIZEOF_EXPR:
+     case ALIGNOF_EXPR:
      case ARROW_EXPR:
      case THROW_EXPR:
      case TYPEID_EXPR:
Index: gcc/cp/tree.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/tree.c,v
retrieving revision 1.4
diff -c -p -r1.4 tree.c
*** tree.c	1998/01/28 01:32:52	1.4
--- tree.c	1998/01/28 19:01:37
*************** cp_tree_equal (t1, t2)
*** 2060,2065 ****
--- 2060,2066 ----
  	&& TEMPLATE_CONST_LEVEL (t1) == TEMPLATE_CONST_LEVEL (t2);
  
      case SIZEOF_EXPR:
+     case ALIGNOF_EXPR:
        if (TREE_CODE (TREE_OPERAND (t1, 0)) != TREE_CODE (TREE_OPERAND (t2, 0)))
  	return 0;
        if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t1, 0))) == 't')
Index: gcc/cp/typeck.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/typeck.c,v
retrieving revision 1.8
diff -c -p -r1.8 typeck.c
*** typeck.c	1998/01/28 01:32:53	1.8
--- typeck.c	1998/01/28 18:38:16
*************** c_alignof (type)
*** 1474,1479 ****
--- 1474,1482 ----
    enum tree_code code = TREE_CODE (type);
    tree t;
  
+   if (processing_template_decl)
+     return build_min (ALIGNOF_EXPR, sizetype, type);
+ 
    if (code == FUNCTION_TYPE || code == METHOD_TYPE)
      return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
  
Index: gcc/testsuite/g++.old-deja/g++.pt/alignof.C
===================================================================
RCS file: alignof.C
diff -N alignof.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- alignof.C	Wed Jan 28 10:40:28 1998
***************
*** 0 ****
--- 1,21 ----
+ extern "C" void abort();
+ 
+ struct S
+ {
+   char c;
+   double d;
+ };
+ 
+ 
+ template <class T>
+ void foo(T)
+ {
+   if (__alignof__(T) != __alignof__(S))
+     abort();
+ }
+ 
+ 
+ int main()
+ {
+   foo(S());
+ }
Index: gcc/testsuite/g++.old-deja/g++.pt/sizeof.C
===================================================================
RCS file: sizeof.C
diff -N sizeof.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- sizeof.C	Wed Jan 28 11:46:41 1998
***************
*** 0 ****
--- 1,17 ----
+ extern "C" void abort();
+ 
+ template <int I>
+ int bar() { return I; }
+ 
+ template <class T>
+ int foo(T)
+ {
+   return bar<sizeof(T) + 4>() + bar<sizeof(long) + 7>();
+ }
+ 
+ 
+ int main()
+ {
+   if (foo(2) != sizeof(int) + 4 + sizeof(long) + 7)
+     abort();
+ }



More information about the Gcc mailing list