Commit fa72b064 by Gabriel Dos Reis Committed by Gabriel Dos Reis

Fix PR/7363:

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
parent 2b773ee2
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> 2002-07-23 Jan Hubicka <jh@suse.cz>
* gcse.c (try_replace_reg): Use num_changes_pending. * gcse.c (try_replace_reg): Use num_changes_pending.
......
...@@ -2601,36 +2601,61 @@ c_common_get_alias_set (t) ...@@ -2601,36 +2601,61 @@ c_common_get_alias_set (t)
return -1; return -1;
} }
/* Implement the __alignof keyword: Return the minimum required /* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where the
alignment of TYPE, measured in bytes. */ second parameter indicates which OPERATOR is being applied. */
tree tree
c_alignof (type) c_sizeof_or_alignof_type (type, op)
tree type; tree type;
enum tree_code op;
{ {
enum tree_code code = TREE_CODE (type); const char *op_name;
tree t; tree value = NULL;
enum tree_code type_code = TREE_CODE (type);
/* In C++, sizeof applies to the referent. Handle alignof the same way. */
if (code == REFERENCE_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); if (type_code == VOID_TYPE && (pedantic || warn_pointer_arith))
code = TREE_CODE (type); 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)) else if (!COMPLETE_TYPE_P (type))
{ {
error ("__alignof__ applied to an incomplete type"); error ("invalid application of `%s' to an incomplete type", op_name);
t = size_zero_node; value = size_zero_node;
} }
else 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 /* Implement the __alignof keyword: Return the minimum required
......
...@@ -548,12 +548,14 @@ extern tree c_common_signed_type PARAMS ((tree)); ...@@ -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_signed_or_unsigned_type PARAMS ((int, tree));
extern tree c_common_truthvalue_conversion PARAMS ((tree)); extern tree c_common_truthvalue_conversion PARAMS ((tree));
extern void c_apply_type_quals_to_decl PARAMS ((int, tree)); extern void c_apply_type_quals_to_decl PARAMS ((int, tree));
extern tree c_sizeof PARAMS ((tree)); extern tree c_sizeof_or_alignof_type PARAMS ((tree, enum tree_code));
extern tree c_alignof PARAMS ((tree));
extern tree c_alignof_expr PARAMS ((tree)); extern tree c_alignof_expr PARAMS ((tree));
/* Print an error message for invalid operands to arith operation CODE. /* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */ NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error PARAMS ((enum tree_code)); 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 tree c_expand_expr_stmt PARAMS ((tree));
extern void c_expand_start_cond PARAMS ((tree, int, tree)); extern void c_expand_start_cond PARAMS ((tree, int, tree));
extern void c_finish_then PARAMS ((void)); extern void c_finish_then PARAMS ((void));
...@@ -573,6 +575,8 @@ extern void unsigned_conversion_warning PARAMS ((tree, tree)); ...@@ -573,6 +575,8 @@ extern void unsigned_conversion_warning PARAMS ((tree, tree));
/* Read the rest of the current #-directive line. */ /* Read the rest of the current #-directive line. */
extern char *get_directive_line PARAMS ((void)); extern char *get_directive_line PARAMS ((void));
#define GET_DIRECTIVE_LINE() get_directive_line () #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. /* Subroutine of build_binary_op, used for comparison operations.
See if the operands have both been converted from subword integer types See if the operands have both been converted from subword integer types
......
...@@ -736,47 +736,6 @@ type_lists_compatible_p (args1, args2) ...@@ -736,47 +736,6 @@ type_lists_compatible_p (args1, args2)
} }
} }
/* 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 tree
c_sizeof_nowarn (type) c_sizeof_nowarn (type)
tree type; tree type;
......
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> 2002-07-23 Neil Booth <neil@daikokuya.co.uk>
* class.c, method.c, pt.c, search.c: Don't define obstack macros. * class.c, method.c, pt.c, search.c: Don't define obstack macros.
...@@ -30,7 +44,7 @@ ...@@ -30,7 +44,7 @@
2002-07-20 Gabriel Dos Reis <gdr@nerim.net> 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. members with 'locus'. Adjust use throughout.
(struct feed): Likewise. (struct feed): Likewise.
(alloc_unparsed_test): Change prototype, take a 'const location_t *'. (alloc_unparsed_test): Change prototype, take a 'const location_t *'.
......
...@@ -4437,6 +4437,7 @@ extern int compparms PARAMS ((tree, tree)); ...@@ -4437,6 +4437,7 @@ extern int compparms PARAMS ((tree, tree));
extern int comp_cv_qualification PARAMS ((tree, tree)); extern int comp_cv_qualification PARAMS ((tree, tree));
extern int comp_cv_qual_signature PARAMS ((tree, tree)); extern int comp_cv_qual_signature PARAMS ((tree, tree));
extern tree expr_sizeof PARAMS ((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 c_sizeof_nowarn PARAMS ((tree));
extern tree inline_conversion PARAMS ((tree)); extern tree inline_conversion PARAMS ((tree));
extern tree decay_conversion PARAMS ((tree)); extern tree decay_conversion PARAMS ((tree));
...@@ -4483,6 +4484,8 @@ extern tree merge_types PARAMS ((tree, tree)); ...@@ -4483,6 +4484,8 @@ extern tree merge_types PARAMS ((tree, tree));
extern tree check_return_expr PARAMS ((tree)); extern tree check_return_expr PARAMS ((tree));
#define cp_build_binary_op(code, arg1, arg2) \ #define cp_build_binary_op(code, arg1, arg2) \
build_binary_op(code, arg1, arg2, 1) 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 */ /* in typeck2.c */
extern void cxx_incomplete_type_diagnostic PARAMS ((tree, tree, int)); extern void cxx_incomplete_type_diagnostic PARAMS ((tree, tree, int));
...@@ -4495,9 +4498,6 @@ extern tree binfo_or_else PARAMS ((tree, tree)); ...@@ -4495,9 +4498,6 @@ extern tree binfo_or_else PARAMS ((tree, tree));
extern void readonly_error PARAMS ((tree, const char *, int)); extern void readonly_error PARAMS ((tree, const char *, int));
extern int abstract_virtuals_error PARAMS ((tree, tree)); 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 force_store_init_value PARAMS ((tree, tree));
extern tree store_init_value PARAMS ((tree, tree)); extern tree store_init_value PARAMS ((tree, tree));
extern tree digest_init PARAMS ((tree, tree, tree *)); extern tree digest_init PARAMS ((tree, tree, tree *));
......
...@@ -14070,7 +14070,7 @@ finish_destructor_body () ...@@ -14070,7 +14070,7 @@ finish_destructor_body ()
if (DECL_VIRTUAL_P (current_function_decl)) if (DECL_VIRTUAL_P (current_function_decl))
{ {
tree if_stmt; tree if_stmt;
tree virtual_size = c_sizeof (current_class_type); tree virtual_size = cxx_sizeof (current_class_type);
/* [class.dtor] /* [class.dtor]
......
...@@ -3779,7 +3779,7 @@ build_expr_from_tree (t) ...@@ -3779,7 +3779,7 @@ build_expr_from_tree (t)
if (!TYPE_P (r)) if (!TYPE_P (r))
return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r); return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r);
else 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: case MODOP_EXPR:
......
...@@ -2106,7 +2106,7 @@ finish_sizeof (t) ...@@ -2106,7 +2106,7 @@ finish_sizeof (t)
if (processing_template_decl) if (processing_template_decl)
return build_min_nt (SIZEOF_EXPR, t); 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 /* Implement the __alignof keyword: Return the minimum required
...@@ -2119,7 +2119,7 @@ finish_alignof (t) ...@@ -2119,7 +2119,7 @@ finish_alignof (t)
if (processing_template_decl) if (processing_template_decl)
return build_min_nt (ALIGNOF_EXPR, t); 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 /* Generate RTL for the statement T, and its substatements, and any
......
...@@ -1486,73 +1486,42 @@ comp_target_parms (parms1, parms2) ...@@ -1486,73 +1486,42 @@ comp_target_parms (parms1, parms2)
return warn_contravariance ? -1 : 1; return warn_contravariance ? -1 : 1;
} }
/* Compute the value of the `sizeof' operator. */
tree tree
c_sizeof (type) cxx_sizeof_or_alignof_type (type, op)
tree type; tree type;
enum tree_code op;
{ {
enum tree_code code = TREE_CODE (type); enum tree_code type_code;
tree size; tree value;
const char *op_name;
my_friendly_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR, 20020720);
if (processing_template_decl) 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 (type_code == METHOD_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 (pedantic || warn_pointer_arith) if (pedantic || warn_pointer_arith)
pedwarn ("ISO C++ forbids applying `sizeof' to a member function"); pedwarn ("invalid application of `%s' to a member function", op_name);
size = size_one_node; value = size_one_node;
} }
else if (code == VOID_TYPE) else if (type_code == OFFSET_TYPE)
{ {
if (pedantic || warn_pointer_arith) error ("invalid application of `%s' to non-static member", op_name);
pedwarn ("ISO C++ forbids applying `sizeof' to type `void' which is an incomplete type"); value = size_zero_node;
size = size_one_node;
} }
else if (code == ERROR_MARK)
size = size_one_node;
else else
{ value = c_sizeof_or_alignof_type (complete_type (type), op);
/* 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));
}
/* SIZE will have an integer type with TYPE_IS_SIZETYPE set. return value;
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;
} }
tree tree
expr_sizeof (e) expr_sizeof (e)
tree e; tree e;
...@@ -1582,7 +1551,7 @@ expr_sizeof (e) ...@@ -1582,7 +1551,7 @@ expr_sizeof (e)
if (e == error_mark_node) if (e == error_mark_node)
return e; return e;
return c_sizeof (TREE_TYPE (e)); return cxx_sizeof (TREE_TYPE (e));
} }
tree tree
......
// { 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> >();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment