Fix PR/7363:
authorGabriel Dos Reis <gdr@nerim.net>
Tue, 23 Jul 2002 13:54:06 +0000 (13:54 +0000)
committerGabriel Dos Reis <gdr@gcc.gnu.org>
Tue, 23 Jul 2002 13:54:06 +0000 (13:54 +0000)
2002-07-21  Gabriel Dos Reis  <gdr@nerim.net>

        Fix PR/7363:
        * c-common.c (c_sizeof_or_alignof_type): New function.
        (c_alignof): Remove definition.
        * c-common.h (c_sizeof, c_alignof): Define as macros.
        (c_sizeof_or_alignof_type): Declare.
        (my_friendly_assert): Moved from cp/cp-tree.h
        * c-typeck.c (c_sizeof): Remove definition.

cp/

2002-07-21  Gabriel Dos Reis  <gdr@nerim.net>

        Fix PR/7363:
        * typeck.c (cxx_sizeof_or_alignof_type): New function.
        (c_sizeof): Remove definition.
        (expr_sizeof): Use cxx_sizeof.
        * decl2.c (build_expr_from_tree): Use cxx_sizeof_or_alignof_type.
        * decl.c (finish_destructor_body): Use cxx_sizeof.
        * semantics.c (finish_alignof): Likewise.
        (finish_alignof): Use cxx_alignof.
        * cp-tree.h (cxx_sizeof, cxx_alignof): New macros.
        (cxx_sizeof_or_alignof_type): Declare.
        (my_friendly_assert): Move to ../c-common.h.

From-SVN: r55678

gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/ext/alignof1.C [new file with mode: 0644]

index b66163379c3a7b148fa8c66507261dd4ae79d615..aeb15c44913895afd660b2355428ed8f252698bc 100644 (file)
@@ -1,3 +1,13 @@
+2002-07-23  Gabriel Dos Reis  <gdr@nerim.net>
+
+       Fix PR/7363:
+       * c-common.c (c_sizeof_or_alignof_type): New function.
+       (c_alignof): Remove definition.
+       * c-common.h (c_sizeof, c_alignof): Define as macros.
+       (c_sizeof_or_alignof_type): Declare.
+       (my_friendly_assert): Moved from cp/cp-tree.h
+       * c-typeck.c (c_sizeof): Remove definition.
+
 2002-07-23  Jan Hubicka  <jh@suse.cz>
 
        * gcse.c (try_replace_reg): Use num_changes_pending.
index a948959da703bea665efc7f68396b273165f95ab..d7be6c812d1f46d755cdc59f45c7e0ee6f424e8d 100644 (file)
@@ -2601,36 +2601,61 @@ c_common_get_alias_set (t)
   return -1;
 }
 \f
-/* Implement the __alignof keyword: Return the minimum required
-   alignment of TYPE, measured in bytes.  */
-
+/* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where the
+   second parameter indicates which OPERATOR is being applied.  */
 tree
-c_alignof (type)
+c_sizeof_or_alignof_type (type, op)
      tree type;
+     enum tree_code op;
 {
-  enum tree_code code = TREE_CODE (type);
-  tree t;
-
-  /* In C++, sizeof applies to the referent.  Handle alignof the same way.  */
-  if (code == REFERENCE_TYPE)
+  const char *op_name;
+  tree value = NULL;
+  enum tree_code type_code = TREE_CODE (type);
+  
+  my_friendly_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR, 20020720);
+  op_name = op == SIZEOF_EXPR ? "sizeof" : "__alignof__";
+  
+  if (type_code == FUNCTION_TYPE)
+    {
+      if (op == SIZEOF_EXPR)
+       {
+         if (pedantic || warn_pointer_arith)
+           pedwarn ("invalid application of `sizeof' to a function type");
+         value = size_one_node;
+       }
+      else
+       value = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
+    }
+  else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
     {
-      type = TREE_TYPE (type);
-      code = TREE_CODE (type);
+      if (type_code == VOID_TYPE && (pedantic || warn_pointer_arith))
+       pedwarn ("invalid application of `%s' to a void type", op_name);
+      value = size_one_node;
     }
-
-  if (code == FUNCTION_TYPE)
-    t = size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT);
-  else if (code == VOID_TYPE || code == ERROR_MARK)
-    t = size_one_node;
   else if (!COMPLETE_TYPE_P (type))
     {
-      error ("__alignof__ applied to an incomplete type");
-      t = size_zero_node;
+      error ("invalid application of `%s' to an incomplete type", op_name);
+      value = size_zero_node;
     }
   else
-    t = size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
+    {
+      if (op == SIZEOF_EXPR)
+       /* Convert in case a char is more than one unit.  */
+       value = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
+                           size_int (TYPE_PRECISION (char_type_node)
+                                     / BITS_PER_UNIT));
+      else
+       value = size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
+    }
 
-  return fold (build1 (NOP_EXPR, c_size_type_node, t));
+  /* VALUE will have an integer type with TYPE_IS_SIZETYPE set.
+     TYPE_IS_SIZETYPE means that certain things (like overflow) will
+     never happen.  However, this node should really have type
+     `size_t', which is just a typedef for an ordinary integer type.  */
+  value = fold (build1 (NOP_EXPR, c_size_type_node, value));
+  my_friendly_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (value)), 20001021);
+  
+  return value;
 }
 
 /* Implement the __alignof keyword: Return the minimum required
index 8aac85761a6fa7f3ead1b9fbff86e4ce34d10d66..fabfb1642a1f2c01026f7f8a6222f50091e7c6df 100644 (file)
@@ -548,12 +548,14 @@ extern tree c_common_signed_type          PARAMS ((tree));
 extern tree c_common_signed_or_unsigned_type   PARAMS ((int, tree));
 extern tree c_common_truthvalue_conversion     PARAMS ((tree));
 extern void c_apply_type_quals_to_decl         PARAMS ((int, tree));
-extern tree c_sizeof                           PARAMS ((tree));
-extern tree c_alignof                          PARAMS ((tree));
+extern tree c_sizeof_or_alignof_type   PARAMS ((tree, enum tree_code));
 extern tree c_alignof_expr                     PARAMS ((tree));
 /* Print an error message for invalid operands to arith operation CODE.
    NOP_EXPR is used as a special case (see truthvalue_conversion).  */
 extern void binary_op_error                    PARAMS ((enum tree_code));
+#define my_friendly_assert(EXP, N) (void) \
+ (((EXP) == 0) ? (fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0) : 0)
+
 extern tree c_expand_expr_stmt                 PARAMS ((tree));
 extern void c_expand_start_cond                        PARAMS ((tree, int, tree));
 extern void c_finish_then                       PARAMS ((void));
@@ -573,6 +575,8 @@ extern void unsigned_conversion_warning             PARAMS ((tree, tree));
 /* Read the rest of the current #-directive line.  */
 extern char *get_directive_line                        PARAMS ((void));
 #define GET_DIRECTIVE_LINE() get_directive_line ()
+#define c_sizeof(T)  c_sizeof_or_alignof_type (T, SIZEOF_EXPR)
+#define c_alignof(T) c_sizeof_or_alignof_type (T, ALIGNOF_EXPR)
 
 /* Subroutine of build_binary_op, used for comparison operations.
    See if the operands have both been converted from subword integer types
index 48b421313d6a05299384ed6e0d0f9721e26568f9..f6e8d538d7531a5229bda9e011d47a91c3e56a40 100644 (file)
@@ -736,47 +736,6 @@ type_lists_compatible_p (args1, args2)
     }
 }
 \f
-/* Compute the value of the `sizeof' operator.  */
-
-tree
-c_sizeof (type)
-     tree type;
-{
-  enum tree_code code = TREE_CODE (type);
-  tree size;
-
-  if (code == FUNCTION_TYPE)
-    {
-      if (pedantic || warn_pointer_arith)
-       pedwarn ("sizeof applied to a function type");
-      size = size_one_node;
-    }
-  else if (code == VOID_TYPE)
-    {
-      if (pedantic || warn_pointer_arith)
-       pedwarn ("sizeof applied to a void type");
-      size = size_one_node;
-    }
-  else if (code == ERROR_MARK)
-    size = size_one_node;
-  else if (!COMPLETE_TYPE_P (type))
-    {
-      error ("sizeof applied to an incomplete type");
-      size = size_zero_node;
-    }
-  else
-    /* Convert in case a char is more than one unit.  */
-    size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
-                      size_int (TYPE_PRECISION (char_type_node)
-                                / BITS_PER_UNIT));
-
-  /* SIZE will have an integer type with TYPE_IS_SIZETYPE set.
-     TYPE_IS_SIZETYPE means that certain things (like overflow) will
-     never happen.  However, this node should really have type
-     `size_t', which is just a typedef for an ordinary integer type.  */
-  return fold (build1 (NOP_EXPR, c_size_type_node, size));
-}
-
 tree
 c_sizeof_nowarn (type)
      tree type;
index 4a63bc6939288c71bb18952d09e02bf4f753ae7c..3cb8bd6b0de2df464336df4ff414802da14743e0 100644 (file)
@@ -1,3 +1,17 @@
+2002-07-23  Gabriel Dos Reis  <gdr@nerim.net>
+
+       Fix PR/7363:
+       * typeck.c (cxx_sizeof_or_alignof_type): New function.
+       (c_sizeof): Remove definition.
+       (expr_sizeof): Use cxx_sizeof.
+       * decl2.c (build_expr_from_tree): Use cxx_sizeof_or_alignof_type.
+       * decl.c (finish_destructor_body): Use cxx_sizeof.
+       * semantics.c (finish_alignof): Likewise.
+       (finish_alignof): Use cxx_alignof.
+       * cp-tree.h (cxx_sizeof, cxx_alignof): New macros.
+       (cxx_sizeof_or_alignof_type): Declare.
+       (my_friendly_assert): Move to ../c-common.h.
+
 2002-07-23  Neil Booth  <neil@daikokuya.co.uk>
 
        * class.c, method.c, pt.c, search.c: Don't define obstack macros.
@@ -30,7 +44,7 @@
 
 2002-07-20  Gabriel Dos Reis  <gdr@nerim.net>
 
-       * spew.c (struct uinparsed_test): Replace 'filename' and 'lineno'
+       * spew.c (struct unparsed_test): Replace 'filename' and 'lineno'
        members with 'locus'.  Adjust use throughout.
        (struct feed):  Likewise.
        (alloc_unparsed_test): Change prototype, take a 'const location_t *'.
index 0f4bf9081cf3db86b110887d85ac9512eadc071c..fa7243dc5a7217b0114c3ff75ca9391e71d06d9a 100644 (file)
@@ -4437,6 +4437,7 @@ extern int compparms                              PARAMS ((tree, tree));
 extern int comp_cv_qualification                PARAMS ((tree, tree));
 extern int comp_cv_qual_signature               PARAMS ((tree, tree));
 extern tree expr_sizeof                                PARAMS ((tree));
+extern tree cxx_sizeof_or_alignof_type    PARAMS ((tree, enum tree_code));
 extern tree c_sizeof_nowarn                    PARAMS ((tree));
 extern tree inline_conversion                  PARAMS ((tree));
 extern tree decay_conversion                   PARAMS ((tree));
@@ -4483,6 +4484,8 @@ extern tree merge_types                           PARAMS ((tree, tree));
 extern tree check_return_expr                   PARAMS ((tree));
 #define cp_build_binary_op(code, arg1, arg2) \
   build_binary_op(code, arg1, arg2, 1)
+#define cxx_sizeof(T)  cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR)
+#define cxx_alignof(T) cxx_sizeof_or_alignof_type (T, ALIGNOF_EXPR)
 
 /* in typeck2.c */
 extern void cxx_incomplete_type_diagnostic     PARAMS ((tree, tree, int));
@@ -4495,9 +4498,6 @@ extern tree binfo_or_else                 PARAMS ((tree, tree));
 extern void readonly_error                     PARAMS ((tree, const char *, int));
 extern int abstract_virtuals_error             PARAMS ((tree, tree));
 
-#define my_friendly_assert(EXP, N) (void) \
- (((EXP) == 0) ? (fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0) : 0)
-
 extern tree force_store_init_value             PARAMS ((tree, tree));
 extern tree store_init_value                   PARAMS ((tree, tree));
 extern tree digest_init                                PARAMS ((tree, tree, tree *));
index e4897953e3e9effe5a0edc74b7758a8be961754d..337107baf62d84930b35f0a0c81dffc390a9760a 100644 (file)
@@ -14070,7 +14070,7 @@ finish_destructor_body ()
   if (DECL_VIRTUAL_P (current_function_decl))
     {
       tree if_stmt;
-      tree virtual_size = c_sizeof (current_class_type);
+      tree virtual_size = cxx_sizeof (current_class_type);
 
       /* [class.dtor]
 
index 9a18586b8b62a864ade5e820bda7d5733fb2851b..66922b19de30f3e1a8c671bf539a96338522ebca 100644 (file)
@@ -3779,7 +3779,7 @@ build_expr_from_tree (t)
        if (!TYPE_P (r))
          return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r);
        else
-         return TREE_CODE (t) == SIZEOF_EXPR ? c_sizeof (r) : c_alignof (r);
+         return cxx_sizeof_or_alignof_type (r, TREE_CODE (t));
       }
 
     case MODOP_EXPR:
index bedd97936fb050b9292b80e3c81971725bde6bb3..ad127bf174709932a3d20788c4ecbe799052f90a 100644 (file)
@@ -2106,7 +2106,7 @@ finish_sizeof (t)
   if (processing_template_decl)
     return build_min_nt (SIZEOF_EXPR, t);
 
-  return TYPE_P (t) ? c_sizeof (t) : expr_sizeof (t);
+  return TYPE_P (t) ? cxx_sizeof (t) : expr_sizeof (t);
 }
 
 /* Implement the __alignof keyword: Return the minimum required
@@ -2119,7 +2119,7 @@ finish_alignof (t)
   if (processing_template_decl)
     return build_min_nt (ALIGNOF_EXPR, t);
 
-  return TYPE_P (t) ? c_alignof (t) : c_alignof_expr (t);
+  return TYPE_P (t) ? cxx_alignof (t) : c_alignof_expr (t);
 }
 
 /* Generate RTL for the statement T, and its substatements, and any
index 30d8cac9a79ddac7dcd230422e69aa139f88f65d..6d810f592ae61a3063e3514b2ebecbf10608dbdb 100644 (file)
@@ -1486,73 +1486,42 @@ comp_target_parms (parms1, parms2)
   return warn_contravariance ? -1 : 1;
 }
 \f
-/* Compute the value of the `sizeof' operator.  */
-
 tree
-c_sizeof (type)
+cxx_sizeof_or_alignof_type (type, op)
      tree type;
+     enum tree_code op;
 {
-  enum tree_code code = TREE_CODE (type);
-  tree size;
+  enum tree_code type_code;
+  tree value;
+  const char *op_name;
 
+  my_friendly_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR, 20020720);
   if (processing_template_decl)
-    return build_min_nt (SIZEOF_EXPR, type);
+    return build_min_nt (op, type);
+  
+  op_name = operator_name_info[(int) op].name;
+  
+  if (TREE_CODE (type) == REFERENCE_TYPE)
+    type = TREE_TYPE (type);
+  type_code = TREE_CODE (type);
 
-  if (code == FUNCTION_TYPE)
-    {
-      if (pedantic || warn_pointer_arith)
-       pedwarn ("ISO C++ forbids applying `sizeof' to a function type");
-      size = size_one_node;
-    }
-  else if (code == METHOD_TYPE)
+  if (type_code == METHOD_TYPE)
     {
       if (pedantic || warn_pointer_arith)
-       pedwarn ("ISO C++ forbids applying `sizeof' to a member function");
-      size = size_one_node;
+       pedwarn ("invalid application of `%s' to a member function", op_name);
+      value = size_one_node;
     }
-  else if (code == VOID_TYPE)
+  else if (type_code == OFFSET_TYPE)
     {
-      if (pedantic || warn_pointer_arith)
-       pedwarn ("ISO C++ forbids applying `sizeof' to type `void' which is an incomplete type");
-      size = size_one_node;
+      error ("invalid application of `%s' to non-static member", op_name);
+      value = size_zero_node;
     }
-  else if (code == ERROR_MARK)
-    size = size_one_node;
   else
-    {
-      /* ARM $5.3.2: ``When applied to a reference, the result is the
-        size of the referenced object.'' */
-      if (code == REFERENCE_TYPE)
-       type = TREE_TYPE (type);
-
-      if (code == OFFSET_TYPE)
-       {
-         error ("`sizeof' applied to non-static member");
-         size = size_zero_node;
-       }
-      else if (!COMPLETE_TYPE_P (complete_type (type)))
-       {
-         error ("`sizeof' applied to incomplete type `%T'", type);
-         size = size_zero_node;
-       }
-      else
-       /* Convert in case a char is more than one unit.  */
-       size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
-                          size_int (TYPE_PRECISION (char_type_node)
-                                    / BITS_PER_UNIT));
-    }
+    value = c_sizeof_or_alignof_type (complete_type (type), op);
 
-  /* SIZE will have an integer type with TYPE_IS_SIZETYPE set.
-     TYPE_IS_SIZETYPE means that certain things (like overflow) will
-     never happen.  However, this node should really have type
-     `size_t', which is just a typedef for an ordinary integer type.  */
-  size = fold (build1 (NOP_EXPR, c_size_type_node, size));
-  my_friendly_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (size)), 
-                     20001021);
-  return size;
+  return value;
 }
 
-
 tree
 expr_sizeof (e)
      tree e;
@@ -1582,7 +1551,7 @@ expr_sizeof (e)
   if (e == error_mark_node)
     return e;
 
-  return c_sizeof (TREE_TYPE (e));
+  return cxx_sizeof (TREE_TYPE (e));
 }
   
 tree
diff --git a/gcc/testsuite/g++.dg/ext/alignof1.C b/gcc/testsuite/g++.dg/ext/alignof1.C
new file mode 100644 (file)
index 0000000..9e930ed
--- /dev/null
@@ -0,0 +1,19 @@
+// { dg-do run }
+
+// Copyright (C) 2002 Free Software Foundation, Inc.
+// Contributed by Gabriel Dos Reis <gdr@codesourcery.com>, 2002-07-20
+// Bug PR/7363.
+
+template<typename T>
+int my_alignof()
+{
+  return __alignof__ (T);
+}
+
+template<typename>
+  struct X { };
+
+int main()
+{
+  return my_alignof<X<void> >();
+}