This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
3.3 C/C++ PATCH: Don't duplicate codes handling sizeof (T)
- From: Gabriel Dos Reis <gdr at integrable-solutions dot net>
- To: gcc-patches at gcc dot gnu dot org
- Cc: jason at redhat dot com, mark at codesourcery dot com
- Date: 25 Jul 2002 04:55:06 +0200
- Subject: 3.3 C/C++ PATCH: Don't duplicate codes handling sizeof (T)
- Organization: CodeSourcery, LLC
Hi,
As noted in an earlier patch, the C and C++ front-ends are
duplicating codes for computing 'sizeof (T)'. This patch makes more
sharing and reduces code duplication.
The C front-end has separate codes for c_sizeof_nowarn() which is
essentially the same as c_sizeof_or_alignof_type() without the
diagnostics. As far as I can tell, it isn't actually used.
The C++ front-end copied c_sizeof_nowarn() from the C front-end
-- without renaming -- and adds just check for REFERENCE_TYPE and
METHOD_TYPE. That is no good.
This patch adds a complaining flag to c{, xx}_sizeof_or_alignof_type()
and defines c{, xx}_sizeof_nowarn() in terms of the former.
Bootstrapped and tested on an i686-pc-linux. No regression.
OK for mainline?
-- Gaby
2002-07-25 Gabriel Dos Reis <gdr@nerim.net>
* c-common.c (c_sizeof_or_alignof_type): Take a third argument for
complaining.
* c-common.h (c_sizeof): Adjust definition.
(c_alignof): Likewise.
* c-tree.h (c_sizeof_nowarn): Now macro.
* c-typeck.c (c_sizeof_nowarn): Remove definition.
cp/
2002-07-25 Gabriel Dos Reis <gdr@nerim.net>
* cp-tree.h (cxx_sizeof_nowarn): Now a macro.
(cxx_sizeof_or_alignof_type): Take a third argument.
(cxx_sizeof): Adjust definition.
(cxx_alignof): Likewise.
* init.c (build_delete): Use cxx_sizeof_nowarn to reflect reality.
* typeck.c (cxx_sizeof_or_alignof_type): Take a third argument for
complaining.
(c_sizeof_nowarn): Remove definition.
(build_unary_op): Use cxx_sizeof_nowarn.
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.c,v
retrieving revision 1.349
diff -p -r1.349 c-common.c
*** c-common.c 23 Jul 2002 13:54:02 -0000 1.349
--- c-common.c 25 Jul 2002 01:43:02 -0000
*************** c_common_get_alias_set (t)
*** 2602,2612 ****
}
/* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where the
! second parameter indicates which OPERATOR is being applied. */
tree
! c_sizeof_or_alignof_type (type, op)
tree type;
enum tree_code op;
{
const char *op_name;
tree value = NULL;
--- 2602,2615 ----
}
/* Compute the value of 'sizeof (TYPE)' or '__alignof__ (TYPE)', where the
! second parameter indicates which OPERATOR is being applied. The COMPLAIN
! flag controls whether we should diagnose possibly ill-formed
! constructs or not. */
tree
! c_sizeof_or_alignof_type (type, op, complain)
tree type;
enum tree_code op;
+ int complain;
{
const char *op_name;
tree value = NULL;
*************** c_sizeof_or_alignof_type (type, op)
*** 2619,2625 ****
{
if (op == SIZEOF_EXPR)
{
! if (pedantic || warn_pointer_arith)
pedwarn ("invalid application of `sizeof' to a function type");
value = size_one_node;
}
--- 2622,2628 ----
{
if (op == SIZEOF_EXPR)
{
! if (complain && (pedantic || warn_pointer_arith))
pedwarn ("invalid application of `sizeof' to a function type");
value = size_one_node;
}
*************** c_sizeof_or_alignof_type (type, op)
*** 2628,2640 ****
}
else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
{
! if (type_code == VOID_TYPE && (pedantic || warn_pointer_arith))
pedwarn ("invalid application of `%s' to a void type", op_name);
value = size_one_node;
}
else if (!COMPLETE_TYPE_P (type))
{
! error ("invalid application of `%s' to an incomplete type", op_name);
value = size_zero_node;
}
else
--- 2631,2645 ----
}
else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
{
! if (type_code == VOID_TYPE
! && complain && (pedantic || warn_pointer_arith))
pedwarn ("invalid application of `%s' to a void type", op_name);
value = size_one_node;
}
else if (!COMPLETE_TYPE_P (type))
{
! if (complain)
! error ("invalid application of `%s' to an incomplete type", op_name);
value = size_zero_node;
}
else
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.h,v
retrieving revision 1.143
diff -p -r1.143 c-common.h
*** c-common.h 23 Jul 2002 13:54:02 -0000 1.143
--- c-common.h 25 Jul 2002 01:43:02 -0000
*************** extern tree c_common_signed_type PARAMS
*** 548,554 ****
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_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). */
--- 548,554 ----
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_or_alignof_type PARAMS ((tree, enum tree_code, int));
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 unsigned_conversion_warning
*** 575,582 ****
/* 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
--- 575,582 ----
/* 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, 1)
! #define c_alignof(T) c_sizeof_or_alignof_type (T, ALIGNOF_EXPR, 1)
/* Subroutine of build_binary_op, used for comparison operations.
See if the operands have both been converted from subword integer types
Index: c-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-tree.h,v
retrieving revision 1.100
diff -p -r1.100 c-tree.h
*** c-tree.h 16 Jul 2002 02:16:31 -0000 1.100
--- c-tree.h 25 Jul 2002 01:43:03 -0000
*************** extern bool c_warn_unused_global_decl P
*** 255,264 ****
((CONST_P) ? TYPE_QUAL_CONST : 0) | \
((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
/* in c-typeck.c */
extern tree require_complete_type PARAMS ((tree));
extern int comptypes PARAMS ((tree, tree));
- extern tree c_sizeof_nowarn PARAMS ((tree));
extern tree c_size_in_bytes PARAMS ((tree));
extern bool c_mark_addressable PARAMS ((tree));
extern void c_incomplete_type_error PARAMS ((tree, tree));
--- 255,264 ----
((CONST_P) ? TYPE_QUAL_CONST : 0) | \
((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
+ #define c_sizeof_nowarn(T) c_sizeof_or_alignof_type (T, SIZEOF_EXPR, 0)
/* in c-typeck.c */
extern tree require_complete_type PARAMS ((tree));
extern int comptypes PARAMS ((tree, tree));
extern tree c_size_in_bytes PARAMS ((tree));
extern bool c_mark_addressable PARAMS ((tree));
extern void c_incomplete_type_error PARAMS ((tree, tree));
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-typeck.c,v
retrieving revision 1.200
diff -p -r1.200 c-typeck.c
*** c-typeck.c 23 Jul 2002 13:54:02 -0000 1.200
--- c-typeck.c 25 Jul 2002 01:43:06 -0000
*************** type_lists_compatible_p (args1, args2)
*** 736,765 ****
}
}
- tree
- c_sizeof_nowarn (type)
- tree type;
- {
- enum tree_code code = TREE_CODE (type);
- tree size;
-
- if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
- size = size_one_node;
- else if (!COMPLETE_TYPE_P (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));
- }
-
/* Compute the size to increment a pointer by. */
tree
--- 736,741 ----
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.732
diff -p -r1.732 cp-tree.h
*** cp/cp-tree.h 23 Jul 2002 21:58:57 -0000 1.732
--- cp/cp-tree.h 25 Jul 2002 01:43:17 -0000
*************** extern int compparms PARAMS ((tree, t
*** 4436,4443 ****
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));
extern tree build_object_ref PARAMS ((tree, tree, tree));
--- 4436,4443 ----
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, int));
! #define cxx_sizeof_nowarn(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, false)
extern tree inline_conversion PARAMS ((tree));
extern tree decay_conversion PARAMS ((tree));
extern tree build_object_ref PARAMS ((tree, tree, tree));
*************** extern tree merge_types PARAMS ((tree
*** 4483,4490 ****
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));
--- 4483,4490 ----
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, true)
! #define cxx_alignof(T) cxx_sizeof_or_alignof_type (T, ALIGNOF_EXPR, true)
/* in typeck2.c */
extern void cxx_incomplete_type_diagnostic PARAMS ((tree, tree, int));
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.547
diff -p -r1.547 decl2.c
*** cp/decl2.c 23 Jul 2002 13:54:05 -0000 1.547
--- cp/decl2.c 25 Jul 2002 01:43:20 -0000
*************** build_expr_from_tree (t)
*** 3779,3785 ****
if (!TYPE_P (r))
return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r);
else
! return cxx_sizeof_or_alignof_type (r, TREE_CODE (t));
}
case MODOP_EXPR:
--- 3779,3785 ----
if (!TYPE_P (r))
return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r);
else
! return cxx_sizeof_or_alignof_type (r, TREE_CODE (t), true);
}
case MODOP_EXPR:
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/init.c,v
retrieving revision 1.284
diff -p -r1.284 init.c
*** cp/init.c 9 Jul 2002 23:31:28 -0000 1.284
--- cp/init.c 25 Jul 2002 01:43:21 -0000
*************** build_delete (type, addr, auto_delete, f
*** 3177,3183 ****
return void_zero_node;
return build_op_delete_call
! (DELETE_EXPR, addr, c_sizeof_nowarn (type),
LOOKUP_NORMAL | (use_global_delete * LOOKUP_GLOBAL),
NULL_TREE);
}
--- 3177,3183 ----
return void_zero_node;
return build_op_delete_call
! (DELETE_EXPR, addr, cxx_sizeof_nowarn (type),
LOOKUP_NORMAL | (use_global_delete * LOOKUP_GLOBAL),
NULL_TREE);
}
*************** build_delete (type, addr, auto_delete, f
*** 3212,3218 ****
/* Build the call. */
do_delete = build_op_delete_call (DELETE_EXPR,
addr,
! c_sizeof_nowarn (type),
LOOKUP_NORMAL,
NULL_TREE);
/* Call the complete object destructor. */
--- 3212,3218 ----
/* Build the call. */
do_delete = build_op_delete_call (DELETE_EXPR,
addr,
! cxx_sizeof_nowarn (type),
LOOKUP_NORMAL,
NULL_TREE);
/* Call the complete object destructor. */
*************** build_delete (type, addr, auto_delete, f
*** 3223,3229 ****
{
/* Make sure we have access to the member op delete, even though
we'll actually be calling it from the destructor. */
! build_op_delete_call (DELETE_EXPR, addr, c_sizeof_nowarn (type),
LOOKUP_NORMAL, NULL_TREE);
}
--- 3223,3229 ----
{
/* Make sure we have access to the member op delete, even though
we'll actually be calling it from the destructor. */
! build_op_delete_call (DELETE_EXPR, addr, cxx_sizeof_nowarn (type),
LOOKUP_NORMAL, NULL_TREE);
}
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.411
diff -p -r1.411 typeck.c
*** cp/typeck.c 23 Jul 2002 13:54:06 -0000 1.411
--- cp/typeck.c 25 Jul 2002 01:43:24 -0000
*************** comp_target_parms (parms1, parms2)
*** 1487,1495 ****
}
tree
! cxx_sizeof_or_alignof_type (type, op)
tree type;
enum tree_code op;
{
enum tree_code type_code;
tree value;
--- 1487,1496 ----
}
tree
! cxx_sizeof_or_alignof_type (type, op, complain)
tree type;
enum tree_code op;
+ int complain;
{
enum tree_code type_code;
tree value;
*************** cxx_sizeof_or_alignof_type (type, op)
*** 1507,1523 ****
if (type_code == METHOD_TYPE)
{
! if (pedantic || warn_pointer_arith)
pedwarn ("invalid application of `%s' to a member function", op_name);
value = size_one_node;
}
else if (type_code == OFFSET_TYPE)
{
! error ("invalid application of `%s' to non-static member", op_name);
value = size_zero_node;
}
else
! value = c_sizeof_or_alignof_type (complete_type (type), op);
return value;
}
--- 1508,1525 ----
if (type_code == METHOD_TYPE)
{
! if (complain && (pedantic || warn_pointer_arith))
pedwarn ("invalid application of `%s' to a member function", op_name);
value = size_one_node;
}
else if (type_code == OFFSET_TYPE)
{
! if (complain)
! error ("invalid application of `%s' to non-static member", op_name);
value = size_zero_node;
}
else
! value = c_sizeof_or_alignof_type (complete_type (type), op, complain);
return value;
}
*************** expr_sizeof (e)
*** 1554,1594 ****
return cxx_sizeof (TREE_TYPE (e));
}
- tree
- c_sizeof_nowarn (type)
- tree type;
- {
- enum tree_code code = TREE_CODE (type);
- tree size;
-
- if (code == FUNCTION_TYPE
- || code == METHOD_TYPE
- || code == VOID_TYPE
- || code == ERROR_MARK)
- size = size_one_node;
- else
- {
- if (code == REFERENCE_TYPE)
- type = TREE_TYPE (type);
-
- if (!COMPLETE_TYPE_P (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. */
- size = fold (build1 (NOP_EXPR, c_size_type_node, size));
- my_friendly_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (size)),
- 20001021);
- return size;
- }
/* Perform the array-to-pointer and function-to-pointer conversions
for EXP.
--- 1556,1561 ----
*************** build_unary_op (code, xarg, noconvert)
*** 4377,4383 ****
((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
? "increment" : "decrement"), argtype);
! inc = c_sizeof_nowarn (TREE_TYPE (argtype));
}
else
inc = integer_one_node;
--- 4344,4350 ----
((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
? "increment" : "decrement"), argtype);
! inc = cxx_sizeof_nowarn (TREE_TYPE (argtype));
}
else
inc = integer_one_node;