cp-tree.h (enum cp_lvalue_kind): Add clk_packed.

cp:
	* cp-tree.h (enum cp_lvalue_kind): Add clk_packed.
	* tree.c (lvalue_p_1): Set it.
	* class.c (check_field): Don't allow non-packed non-POD fields to
	be packed.
	* call.c (reference_binding): Need a temporary for all bitfield
	and packed fields.
	(convert_like_real): Check it is ok to make a temporary here.
testsuite:
	* g++.dg/ext/packed3.C: New test.
	* g++.dg/ext/packed4.C: New test.

From-SVN: r69669
This commit is contained in:
Nathan Sidwell 2003-07-22 09:53:34 +00:00 committed by Nathan Sidwell
parent c6e4cc53e5
commit e0d1297c43
8 changed files with 159 additions and 10 deletions

View File

@ -1,3 +1,13 @@
2003-07-22 Nathan Sidwell <nathan@codesourcery.com>
* cp-tree.h (enum cp_lvalue_kind): Add clk_packed.
* tree.c (lvalue_p_1): Set it.
* class.c (check_field): Don't allow non-packed non-POD fields to
be packed.
* call.c (reference_binding): Need a temporary for all bitfield
and packed fields.
(convert_like_real): Check it is ok to make a temporary here.
2003-07-21 Nathan Sidwell <nathan@codesourcery.com>
* cp-tree.h (hack_identifier): Remove.

View File

@ -1054,10 +1054,10 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags)
lvalue. */
conv = build1 (IDENTITY_CONV, from, expr);
conv = direct_reference_binding (rto, conv);
if ((lvalue_p & clk_bitfield) != 0
&& CP_TYPE_CONST_NON_VOLATILE_P (to))
if ((lvalue_p & clk_bitfield) != 0
|| ((lvalue_p & clk_packed) != 0 && !TYPE_PACKED (to)))
/* For the purposes of overload resolution, we ignore the fact
this expression is a bitfield. (In particular,
this expression is a bitfield or packed field. (In particular,
[over.ics.ref] says specifically that a function with a
non-const reference parameter is viable even if the
argument is a bitfield.)
@ -1068,6 +1068,7 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags)
a temporary, so we just issue an error when the conversion
actually occurs. */
NEED_TEMPORARY_P (conv) = 1;
return conv;
}
else if (CLASS_TYPE_P (from) && !(flags & LOOKUP_NO_CONVERSION))
@ -4172,6 +4173,23 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
if (NEED_TEMPORARY_P (convs) || !non_cast_lvalue_p (expr))
{
tree type = TREE_TYPE (TREE_OPERAND (convs, 0));
if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)))
{
/* If the reference is volatile or non-const, we
cannot create a temporary. */
cp_lvalue_kind lvalue = real_lvalue_p (expr);
if (lvalue & clk_bitfield)
error ("cannot bind bitfield `%E' to `%T'",
expr, ref_type);
else if (lvalue & clk_packed)
error ("cannot bind packed field `%E' to `%T'",
expr, ref_type);
else
my_friendly_assert (0, 20030715);
return error_mark_node;
}
expr = build_target_expr_with_type (expr, type);
}

View File

@ -2959,7 +2959,15 @@ check_field_decls (tree t, tree *access_decls,
if (TREE_CODE (x) == FIELD_DECL)
{
DECL_PACKED (x) |= TYPE_PACKED (t);
if (TYPE_PACKED (t))
{
if (!pod_type_p (TREE_TYPE (x)) && !TYPE_PACKED (TREE_TYPE (x)))
cp_warning_at
("ignoring packed attribute on unpacked non-POD field `%#D'",
x);
else
DECL_PACKED (x) = 1;
}
if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
/* We don't treat zero-width bitfields as making a class

View File

@ -2955,7 +2955,8 @@ typedef enum cp_lvalue_kind {
clk_none = 0, /* Things that are not an lvalue. */
clk_ordinary = 1, /* An ordinary lvalue. */
clk_class = 2, /* An rvalue of class-type. */
clk_bitfield = 4 /* An lvalue for a bit-field. */
clk_bitfield = 4, /* An lvalue for a bit-field. */
clk_packed = 8 /* An lvalue for a packed field. */
} cp_lvalue_kind;
/* The kinds of scopes we recognize. */

View File

@ -100,11 +100,12 @@ lvalue_p_1 (tree ref,
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues,
allow_cast_as_lvalue);
if (op1_lvalue_kind
/* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
situations. */
&& TREE_CODE (TREE_OPERAND (ref, 1)) == FIELD_DECL
&& DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
if (!op1_lvalue_kind
/* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
situations. */
|| TREE_CODE (TREE_OPERAND (ref, 1)) != FIELD_DECL)
;
else if (DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
{
/* Clear the ordinary bit. If this object was a class
rvalue we want to preserve that information. */
@ -112,6 +113,9 @@ lvalue_p_1 (tree ref,
/* The lvalue is for a btifield. */
op1_lvalue_kind |= clk_bitfield;
}
else if (DECL_PACKED (TREE_OPERAND (ref, 1)))
op1_lvalue_kind |= clk_packed;
return op1_lvalue_kind;
case STRING_CST:

View File

@ -1,5 +1,8 @@
2003-07-22 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/ext/packed3.C: New test.
* g++.dg/ext/packed4.C: New test.
* gcc.dg/pack-test-3.c: New test.
2003-07-21 Janis Johnson <janis187@us.ibm.com>

View File

@ -0,0 +1,25 @@
// { dg-do compile }
// Copyright (C) 2003 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 15 Jul 2003 <nathan@codesourcery.com>
// Packed fields are unsuitable for direct reference binding.
struct Unpacked { int i; };
void Ref (int &p);
void Ref (Unpacked &p);
struct __attribute__ ((packed)) Packed
{
char c;
int i;
Unpacked u;
};
void Foo (Packed &p)
{
Ref (p.i); // { dg-error "cannot bind packed field" "" }
Ref (p.u.i); // { dg-error "cannot bind packed field" "" }
Ref (p.u); // { dg-error "cannot bind packed field" "" }
}

View File

@ -0,0 +1,80 @@
// { dg-do run }
// Copyright (C) 2003 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 15 Jul 2003 <nathan@codesourcery.com>
// Packed fields are unsuitable for direct reference binding.
struct Unpacked { int i; };
int ConstRef (int const &p, int const *ptr, int v)
{
if (p != v)
return 1;
if (&p == ptr)
return 2;
return 0;
}
int ConstRef (Unpacked const &p, Unpacked const *ptr, int v)
{
if (p.i != v)
return 1;
if (&p == ptr)
return 2;
return 0;
}
int Val (int p, int v)
{
if (p != v)
return 1;
return 0;
}
int Val (Unpacked p, int v)
{
if (p.i != v)
return 1;
return 0;
}
struct __attribute__ ((packed)) Packed
{
char c;
int i;
Unpacked u;
char t;
};
int Foo (Packed &p, int i, int ui)
{
int r;
if ((r = Val (p.i, i)))
return r;
if ((r = Val (p.u.i, ui)))
return r + 2;
if ((r = Val (p.u, ui)))
return r + 4;
if ((r = ConstRef (p.i, &p.i, i)))
return r + 6;
if ((r = ConstRef (p.u.i, &p.u.i, ui)))
return r + 8;
if ((r = ConstRef (p.u, &p.u, ui)))
return r + 10;
return 0;
}
int main ()
{
Packed p;
p.c = 0x12;
p.i = 0x3456789a;
p.u.i = 0xbcdef00f;
p.t = 0xed;
return Foo (p, 0x3456789a, 0xbcdef00f);
}