PR c++/16387, c++/16389

PR c++/16387, c++/16389
        * typeck.c (cxx_alignof_expr, cxx_sizeof_expr): New functions.
        (cxx_sizeof_or_alignof_expr): Split out from here.

From-SVN: r111945
This commit is contained in:
Jason Merrill 2006-03-10 17:40:41 -05:00
parent 1a919c5632
commit 229970c41d
3 changed files with 101 additions and 12 deletions

View File

@ -1,3 +1,9 @@
2006-03-09 Jason Merrill <jason@redhat.com>
PR c++/16387, c++/16389
* typeck.c (cxx_alignof_expr, cxx_sizeof_expr): New functions.
(cxx_sizeof_or_alignof_expr): Split out from here.
2006-03-09 Diego Novillo <dnovillo@redhat.com>
Merge from gomp-20050608-branch
@ -209,7 +215,8 @@
* decl.c (poplevel_named_label_1): Restore creation of the
bad_decls list.
(decl_jump_unsafe): Check for error_mark_node types.
(check_goto): Don't check cdtor_label. Don't use identify_goto. * semantics.c (finish_return_stmt): Do check_omp_return before
(check_goto): Don't check cdtor_label. Don't use identify_goto.
* semantics.c (finish_return_stmt): Do check_omp_return before
converting to cdtor_label goto.
2005-10-21 Richard Henderson <rth@redhat.com>

View File

@ -1267,20 +1267,17 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
return value;
}
/* Process a sizeof or alignof expression where the operand is an
expression. */
/* Process a sizeof expression where the operand is an expression. */
tree
cxx_sizeof_or_alignof_expr (tree e, enum tree_code op)
static tree
cxx_sizeof_expr (tree e)
{
const char *op_name = operator_name_info[(int) op].name;
if (e == error_mark_node)
return error_mark_node;
if (processing_template_decl)
{
e = build_min (op, size_type_node, e);
e = build_min (SIZEOF_EXPR, size_type_node, e);
TREE_SIDE_EFFECTS (e) = 0;
TREE_READONLY (e) = 1;
@ -1291,13 +1288,13 @@ cxx_sizeof_or_alignof_expr (tree e, enum tree_code op)
&& TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
&& DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
{
error ("invalid application of %qs to a bit-field", op_name);
error ("invalid application of %<sizeof%> to a bit-field");
e = char_type_node;
}
else if (is_overloaded_fn (e))
{
pedwarn ("ISO C++ forbids applying %qs to an expression of "
"function type", op_name);
pedwarn ("ISO C++ forbids applying %<sizeof%> to an expression of "
"function type");
e = char_type_node;
}
else if (type_unknown_p (e))
@ -1308,9 +1305,71 @@ cxx_sizeof_or_alignof_expr (tree e, enum tree_code op)
else
e = TREE_TYPE (e);
return cxx_sizeof_or_alignof_type (e, op, true);
return cxx_sizeof_or_alignof_type (e, SIZEOF_EXPR, true);
}
/* Implement the __alignof keyword: Return the minimum required
alignment of EXPR, measured in bytes. For VAR_DECL's and
FIELD_DECL's return DECL_ALIGN (which can be set from an
"aligned" __attribute__ specification). */
static tree
cxx_alignof_expr (tree e)
{
tree t;
if (e == error_mark_node)
return error_mark_node;
if (processing_template_decl)
{
e = build_min (ALIGNOF_EXPR, size_type_node, e);
TREE_SIDE_EFFECTS (e) = 0;
TREE_READONLY (e) = 1;
return e;
}
if (TREE_CODE (e) == VAR_DECL)
t = size_int (DECL_ALIGN_UNIT (e));
else if (TREE_CODE (e) == COMPONENT_REF
&& TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
&& DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
{
error ("invalid application of %<__alignof%> to a bit-field");
t = size_one_node;
}
else if (TREE_CODE (e) == COMPONENT_REF
&& TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL)
t = size_int (DECL_ALIGN_UNIT (TREE_OPERAND (e, 1)));
else if (is_overloaded_fn (e))
{
pedwarn ("ISO C++ forbids applying %<__alignof%> to an expression of "
"function type");
t = size_one_node;
}
else if (type_unknown_p (e))
{
cxx_incomplete_type_error (e, TREE_TYPE (e));
t = size_one_node;
}
else
return cxx_sizeof_or_alignof_type (TREE_TYPE (e), ALIGNOF_EXPR, true);
return fold_convert (size_type_node, t);
}
/* Process a sizeof or alignof expression where the operand is an
expression. */
tree
cxx_sizeof_or_alignof_expr (tree e, enum tree_code op)
{
if (op == SIZEOF_EXPR)
return cxx_sizeof_expr (e);
else
return cxx_alignof_expr (e);
}
/* EXPR is being used in a context that is not a function call.
Enforce:

View File

@ -0,0 +1,23 @@
// PRs 16387 and 16389
// We were treating alignof (sa.a) as alignof (typeof (sa.a)), which is
// wrong for some fields.
extern "C" void abort();
struct A
{
double a;
} sa;
struct B
{
char c;
double b;
} sb;
int main()
{
if (__alignof (sa) != __alignof (sa.a)
|| __alignof (sb) != __alignof (sb.b))
abort();
}