* C++ PATCH: Fix PR/7363, a regression
@ 2002-07-20 19:29 Gabriel Dos Reis
2002-07-21 1:45 ` Neil Booth
0 siblings, 1 reply; 5+ messages in thread
From: Gabriel Dos Reis @ 2002-07-20 19:29 UTC (permalink / raw)
To: gcc-patches; +Cc: mark, jason
Hi,
This patch fixes PR/7363 where we failed to implicitly instantiate a
specialization (if appropriate) before trying to take its
__alignof__. This is a regression from 2.95.x series.
PR/7363 is an evidence that code duplication is evil. While trying
to fix, I uncovered an instance of "inappropriate code reuse is evil." :-)
More to the point, cp/typeck.c duplicates bunch of codes in
c-typeck.c and c-common.c, especially in c_sizeof() implementation
(and nearby functions). With the result that some bugs were fixed in
the C++ version without being fixed in the C version. This patch
factorizes the commonality into c_sizeof_or_alignof_type() since the
codes to check semantic restrictions for sizeof and __alignof__ are
nearly the same.
While PR/7363 is a regression from 2.95.x, I don't request this
patch to be applied to branch -- Mark, it is up to you -- since it
touches several codes.
Bootstrapped and tested on an i686-pc-linux. No regression.
OK for mainline?
(Similar code duplication exists for expr_sizeof, but I intend to
address it in a separate patch).
-- Gaby
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.
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.c,v
retrieving revision 1.348
diff -p -r1.348 c-common.c
*** c-common.c 7 Jul 2002 22:10:16 -0000 1.348
--- c-common.c 20 Jul 2002 23:30:21 -0000
*************** c_common_get_alias_set (t)
*** 2601,2636 ****
return -1;
}
\f
! /* Implement the __alignof keyword: Return the minimum required
! alignment of TYPE, measured in bytes. */
!
tree
! c_alignof (type)
tree type;
{
! 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)
{
! type = TREE_TYPE (type);
! code = TREE_CODE (type);
}
-
- 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;
}
else
! t = size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
! return fold (build1 (NOP_EXPR, c_size_type_node, t));
}
/* Implement the __alignof keyword: Return the minimum required
--- 2601,2660 ----
return -1;
}
\f
! /* 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;
! 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 && (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)
! {
! 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
! {
! 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);
! }
! /* 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: c-common.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.h,v
retrieving revision 1.142
diff -p -r1.142 c-common.h
*** c-common.h 7 Jul 2002 22:10:17 -0000 1.142
--- c-common.h 20 Jul 2002 23:30:22 -0000
*************** extern tree c_common_signed_type PARAMS
*** 548,559 ****
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_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));
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));
--- 548,561 ----
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). */
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));
*************** extern void unsigned_conversion_warning
*** 573,578 ****
--- 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
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-typeck.c,v
retrieving revision 1.197
diff -p -r1.197 c-typeck.c
*** c-typeck.c 3 Jul 2002 09:49:45 -0000 1.197
--- c-typeck.c 20 Jul 2002 23:30:25 -0000
*************** type_lists_compatible_p (args1, args2)
*** 736,782 ****
}
}
\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;
--- 736,741 ----
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.729
diff -p -r1.729 cp-tree.h
*** cp/cp-tree.h 10 Jul 2002 18:16:23 -0000 1.729
--- cp/cp-tree.h 20 Jul 2002 23:30:36 -0000
*************** extern int compparms PARAMS ((tree, t
*** 4435,4440 ****
--- 4435,4441 ----
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 merge_types PARAMS ((tree
*** 4481,4486 ****
--- 4482,4489 ----
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));
*************** extern tree error_not_base_type PARAMS
*** 4492,4500 ****
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));
--- 4495,4500 ----
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.921
diff -p -r1.921 decl.c
*** cp/decl.c 17 Jul 2002 14:07:42 -0000 1.921
--- cp/decl.c 20 Jul 2002 23:30:43 -0000
*************** finish_destructor_body ()
*** 14064,14070 ****
if (DECL_VIRTUAL_P (current_function_decl))
{
tree if_stmt;
! tree virtual_size = c_sizeof (current_class_type);
/* [class.dtor]
--- 14064,14070 ----
if (DECL_VIRTUAL_P (current_function_decl))
{
tree if_stmt;
! tree virtual_size = cxx_sizeof (current_class_type);
/* [class.dtor]
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.545
diff -p -r1.545 decl2.c
*** cp/decl2.c 9 Jul 2002 23:31:28 -0000 1.545
--- cp/decl2.c 20 Jul 2002 23:30:46 -0000
*************** build_expr_from_tree (t)
*** 3780,3786 ****
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);
}
case MODOP_EXPR:
--- 3780,3786 ----
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:
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/semantics.c,v
retrieving revision 1.268
diff -p -r1.268 semantics.c
*** cp/semantics.c 10 Jul 2002 18:16:24 -0000 1.268
--- cp/semantics.c 20 Jul 2002 23:30:47 -0000
*************** finish_sizeof (t)
*** 2106,2112 ****
if (processing_template_decl)
return build_min_nt (SIZEOF_EXPR, t);
! return TYPE_P (t) ? c_sizeof (t) : expr_sizeof (t);
}
/* Implement the __alignof keyword: Return the minimum required
--- 2106,2112 ----
if (processing_template_decl)
return build_min_nt (SIZEOF_EXPR, t);
! return TYPE_P (t) ? cxx_sizeof (t) : expr_sizeof (t);
}
/* Implement the __alignof keyword: Return the minimum required
*************** finish_alignof (t)
*** 2119,2125 ****
if (processing_template_decl)
return build_min_nt (ALIGNOF_EXPR, t);
! return TYPE_P (t) ? c_alignof (t) : c_alignof_expr (t);
}
/* Generate RTL for the statement T, and its substatements, and any
--- 2119,2125 ----
if (processing_template_decl)
return build_min_nt (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: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.410
diff -p -r1.410 typeck.c
*** cp/typeck.c 26 Jun 2002 17:03:44 -0000 1.410
--- cp/typeck.c 20 Jul 2002 23:30:50 -0000
*************** comp_target_parms (parms1, parms2)
*** 1486,1558 ****
return warn_contravariance ? -1 : 1;
}
\f
- /* Compute the value of the `sizeof' operator. */
-
tree
! c_sizeof (type)
tree type;
{
! enum tree_code code = TREE_CODE (type);
! tree size;
if (processing_template_decl)
! return build_min_nt (SIZEOF_EXPR, 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 (pedantic || warn_pointer_arith)
! pedwarn ("ISO C++ forbids applying `sizeof' to a member function");
! size = size_one_node;
}
! else if (code == VOID_TYPE)
{
! if (pedantic || warn_pointer_arith)
! pedwarn ("ISO C++ forbids applying `sizeof' to type `void' which is an incomplete type");
! size = size_one_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));
! }
! /* 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;
}
-
tree
expr_sizeof (e)
tree e;
--- 1486,1527 ----
return warn_contravariance ? -1 : 1;
}
\f
tree
! cxx_sizeof_or_alignof_type (type, op)
tree type;
+ enum tree_code op;
{
! 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 (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 (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;
}
tree
expr_sizeof (e)
tree e;
*************** expr_sizeof (e)
*** 1582,1588 ****
if (e == error_mark_node)
return e;
! return c_sizeof (TREE_TYPE (e));
}
tree
--- 1551,1557 ----
if (e == error_mark_node)
return e;
! return cxx_sizeof (TREE_TYPE (e));
}
tree
Index: testsuite/g++.dg/ext/alignof1.C
===================================================================
RCS file: testsuite/g++.dg/ext/alignof1.C
diff -N testsuite/g++.dg/ext/alignof1.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/ext/alignof1.C 20 Jul 2002 23:40:42 -0000
***************
*** 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> >();
+ }
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: C++ PATCH: Fix PR/7363, a regression
2002-07-20 19:29 C++ PATCH: Fix PR/7363, a regression Gabriel Dos Reis
@ 2002-07-21 1:45 ` Neil Booth
2002-07-21 2:28 ` Gabriel Dos Reis
0 siblings, 1 reply; 5+ messages in thread
From: Neil Booth @ 2002-07-21 1:45 UTC (permalink / raw)
To: Gabriel Dos Reis; +Cc: gcc-patches, mark, jason
Gabriel Dos Reis wrote:-
> ! if (type_code == FUNCTION_TYPE)
> {
> ! if (op == SIZEOF_EXPR && (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);
This code implies that the result of "sizeof" depends on -pedantic or
-Wpointer-arith, which IMO is not a good idea.
Shouldn't the && part be taken inside the braces?
Neil.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: C++ PATCH: Fix PR/7363, a regression
2002-07-21 1:45 ` Neil Booth
@ 2002-07-21 2:28 ` Gabriel Dos Reis
2002-07-21 14:40 ` Mark Mitchell
0 siblings, 1 reply; 5+ messages in thread
From: Gabriel Dos Reis @ 2002-07-21 2:28 UTC (permalink / raw)
To: Neil Booth; +Cc: gcc-patches, mark, jason
Neil Booth <neil@daikokuya.co.uk> writes:
| Gabriel Dos Reis wrote:-
|
| > ! if (type_code == FUNCTION_TYPE)
| > {
| > ! if (op == SIZEOF_EXPR && (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);
|
| This code implies that the result of "sizeof" depends on -pedantic or
| -Wpointer-arith, which IMO is not a good idea.
Good catch.
| Shouldn't the && part be taken inside the braces?
Yes. Patch revised as below.
Mark, Jason, OK for mainline?
-- Gaby
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.
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.c,v
retrieving revision 1.348
diff -p -r1.348 c-common.c
*** c-common.c 7 Jul 2002 22:10:16 -0000 1.348
--- c-common.c 21 Jul 2002 08:32:45 -0000
*************** c_common_get_alias_set (t)
*** 2601,2636 ****
return -1;
}
\f
! /* Implement the __alignof keyword: Return the minimum required
! alignment of TYPE, measured in bytes. */
!
tree
! c_alignof (type)
tree type;
{
! 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)
{
! type = TREE_TYPE (type);
! code = TREE_CODE (type);
}
-
- 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;
}
else
! t = size_int (TYPE_ALIGN (type) / BITS_PER_UNIT);
! return fold (build1 (NOP_EXPR, c_size_type_node, t));
}
/* Implement the __alignof keyword: Return the minimum required
--- 2601,2661 ----
return -1;
}
\f
! /* 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;
! 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)
! {
! 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
! {
! 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);
! }
! /* 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: c-common.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-common.h,v
retrieving revision 1.142
diff -p -r1.142 c-common.h
*** c-common.h 7 Jul 2002 22:10:17 -0000 1.142
--- c-common.h 21 Jul 2002 08:32:46 -0000
*************** extern tree c_common_signed_type PARAMS
*** 548,559 ****
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_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));
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));
--- 548,561 ----
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). */
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));
*************** extern void unsigned_conversion_warning
*** 573,578 ****
--- 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
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-typeck.c,v
retrieving revision 1.197
diff -p -r1.197 c-typeck.c
*** c-typeck.c 3 Jul 2002 09:49:45 -0000 1.197
--- c-typeck.c 21 Jul 2002 08:32:49 -0000
*************** type_lists_compatible_p (args1, args2)
*** 736,782 ****
}
}
\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;
--- 736,741 ----
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.729
diff -p -r1.729 cp-tree.h
*** cp/cp-tree.h 10 Jul 2002 18:16:23 -0000 1.729
--- cp/cp-tree.h 21 Jul 2002 08:33:00 -0000
*************** extern int compparms PARAMS ((tree, t
*** 4435,4440 ****
--- 4435,4441 ----
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 merge_types PARAMS ((tree
*** 4481,4486 ****
--- 4482,4489 ----
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));
*************** extern tree error_not_base_type PARAMS
*** 4492,4500 ****
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));
--- 4495,4500 ----
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.921
diff -p -r1.921 decl.c
*** cp/decl.c 17 Jul 2002 14:07:42 -0000 1.921
--- cp/decl.c 21 Jul 2002 08:33:07 -0000
*************** finish_destructor_body ()
*** 14064,14070 ****
if (DECL_VIRTUAL_P (current_function_decl))
{
tree if_stmt;
! tree virtual_size = c_sizeof (current_class_type);
/* [class.dtor]
--- 14064,14070 ----
if (DECL_VIRTUAL_P (current_function_decl))
{
tree if_stmt;
! tree virtual_size = cxx_sizeof (current_class_type);
/* [class.dtor]
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.546
diff -p -r1.546 decl2.c
*** cp/decl2.c 21 Jul 2002 02:07:01 -0000 1.546
--- cp/decl2.c 21 Jul 2002 08:33:09 -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 TREE_CODE (t) == SIZEOF_EXPR ? c_sizeof (r) : c_alignof (r);
}
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));
}
case MODOP_EXPR:
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/semantics.c,v
retrieving revision 1.268
diff -p -r1.268 semantics.c
*** cp/semantics.c 10 Jul 2002 18:16:24 -0000 1.268
--- cp/semantics.c 21 Jul 2002 08:33:11 -0000
*************** finish_sizeof (t)
*** 2106,2112 ****
if (processing_template_decl)
return build_min_nt (SIZEOF_EXPR, t);
! return TYPE_P (t) ? c_sizeof (t) : expr_sizeof (t);
}
/* Implement the __alignof keyword: Return the minimum required
--- 2106,2112 ----
if (processing_template_decl)
return build_min_nt (SIZEOF_EXPR, t);
! return TYPE_P (t) ? cxx_sizeof (t) : expr_sizeof (t);
}
/* Implement the __alignof keyword: Return the minimum required
*************** finish_alignof (t)
*** 2119,2125 ****
if (processing_template_decl)
return build_min_nt (ALIGNOF_EXPR, t);
! return TYPE_P (t) ? c_alignof (t) : c_alignof_expr (t);
}
/* Generate RTL for the statement T, and its substatements, and any
--- 2119,2125 ----
if (processing_template_decl)
return build_min_nt (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: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.410
diff -p -r1.410 typeck.c
*** cp/typeck.c 26 Jun 2002 17:03:44 -0000 1.410
--- cp/typeck.c 21 Jul 2002 08:33:14 -0000
*************** comp_target_parms (parms1, parms2)
*** 1486,1558 ****
return warn_contravariance ? -1 : 1;
}
\f
- /* Compute the value of the `sizeof' operator. */
-
tree
! c_sizeof (type)
tree type;
{
! enum tree_code code = TREE_CODE (type);
! tree size;
if (processing_template_decl)
! return build_min_nt (SIZEOF_EXPR, 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 (pedantic || warn_pointer_arith)
! pedwarn ("ISO C++ forbids applying `sizeof' to a member function");
! size = size_one_node;
}
! else if (code == VOID_TYPE)
{
! if (pedantic || warn_pointer_arith)
! pedwarn ("ISO C++ forbids applying `sizeof' to type `void' which is an incomplete type");
! size = size_one_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));
! }
! /* 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;
}
-
tree
expr_sizeof (e)
tree e;
--- 1486,1527 ----
return warn_contravariance ? -1 : 1;
}
\f
tree
! cxx_sizeof_or_alignof_type (type, op)
tree type;
+ enum tree_code op;
{
! 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 (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 (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;
}
tree
expr_sizeof (e)
tree e;
*************** expr_sizeof (e)
*** 1582,1588 ****
if (e == error_mark_node)
return e;
! return c_sizeof (TREE_TYPE (e));
}
tree
--- 1551,1557 ----
if (e == error_mark_node)
return e;
! return cxx_sizeof (TREE_TYPE (e));
}
tree
Index: testsuite/g++.dg/ext/alignof1.C
===================================================================
RCS file: testsuite/g++.dg/ext/alignof1.C
diff -N testsuite/g++.dg/ext/alignof1.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/ext/alignof1.C 21 Jul 2002 08:33:15 -0000
***************
*** 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> >();
+ }
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: C++ PATCH: Fix PR/7363, a regression
2002-07-21 2:28 ` Gabriel Dos Reis
@ 2002-07-21 14:40 ` Mark Mitchell
2002-07-23 7:12 ` Gabriel Dos Reis
0 siblings, 1 reply; 5+ messages in thread
From: Mark Mitchell @ 2002-07-21 14:40 UTC (permalink / raw)
To: Gabriel Dos Reis, Neil Booth; +Cc: gcc-patches, jason
> Mark, Jason, OK for mainline?
Yes. It's is also OK for the GCC 3.2 branch, after it has been
created and GCC 3.2 is released.
Thanks,
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: C++ PATCH: Fix PR/7363, a regression
2002-07-21 14:40 ` Mark Mitchell
@ 2002-07-23 7:12 ` Gabriel Dos Reis
0 siblings, 0 replies; 5+ messages in thread
From: Gabriel Dos Reis @ 2002-07-23 7:12 UTC (permalink / raw)
To: Mark Mitchell; +Cc: Neil Booth, gcc-patches, jason
Mark Mitchell <mark@codesourcery.com> writes:
| > Mark, Jason, OK for mainline?
|
| Yes.
Thanks,
| It's is also OK for the GCC 3.2 branch, after it has been
| created and GCC 3.2 is released.
Will do.
Thanks,
-- Gaby
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2002-07-23 13:57 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-20 19:29 C++ PATCH: Fix PR/7363, a regression Gabriel Dos Reis
2002-07-21 1:45 ` Neil Booth
2002-07-21 2:28 ` Gabriel Dos Reis
2002-07-21 14:40 ` Mark Mitchell
2002-07-23 7:12 ` Gabriel Dos Reis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).