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