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:
parent
c6e4cc53e5
commit
e0d1297c43
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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" "" }
|
||||
}
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue