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:
parent
1a919c5632
commit
229970c41d
3 changed files with 101 additions and 12 deletions
|
@ -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>
|
||||
|
|
|
@ -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:
|
||||
|
|
23
gcc/testsuite/g++.dg/ext/alignof2.C
Normal file
23
gcc/testsuite/g++.dg/ext/alignof2.C
Normal 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();
|
||||
}
|
Loading…
Add table
Reference in a new issue