Commit e0d1297c by Nathan Sidwell Committed by Nathan Sidwell

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
parent c6e4cc53
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> 2003-07-21 Nathan Sidwell <nathan@codesourcery.com>
* cp-tree.h (hack_identifier): Remove. * cp-tree.h (hack_identifier): Remove.
......
...@@ -1054,10 +1054,10 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags) ...@@ -1054,10 +1054,10 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags)
lvalue. */ lvalue. */
conv = build1 (IDENTITY_CONV, from, expr); conv = build1 (IDENTITY_CONV, from, expr);
conv = direct_reference_binding (rto, conv); conv = direct_reference_binding (rto, conv);
if ((lvalue_p & clk_bitfield) != 0 if ((lvalue_p & clk_bitfield) != 0
&& CP_TYPE_CONST_NON_VOLATILE_P (to)) || ((lvalue_p & clk_packed) != 0 && !TYPE_PACKED (to)))
/* For the purposes of overload resolution, we ignore the fact /* 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 [over.ics.ref] says specifically that a function with a
non-const reference parameter is viable even if the non-const reference parameter is viable even if the
argument is a bitfield.) argument is a bitfield.)
...@@ -1068,6 +1068,7 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags) ...@@ -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 a temporary, so we just issue an error when the conversion
actually occurs. */ actually occurs. */
NEED_TEMPORARY_P (conv) = 1; NEED_TEMPORARY_P (conv) = 1;
return conv; return conv;
} }
else if (CLASS_TYPE_P (from) && !(flags & LOOKUP_NO_CONVERSION)) 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, ...@@ -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)) if (NEED_TEMPORARY_P (convs) || !non_cast_lvalue_p (expr))
{ {
tree type = TREE_TYPE (TREE_OPERAND (convs, 0)); 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); expr = build_target_expr_with_type (expr, type);
} }
......
...@@ -2959,7 +2959,15 @@ check_field_decls (tree t, tree *access_decls, ...@@ -2959,7 +2959,15 @@ check_field_decls (tree t, tree *access_decls,
if (TREE_CODE (x) == FIELD_DECL) 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))) if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
/* We don't treat zero-width bitfields as making a class /* We don't treat zero-width bitfields as making a class
......
...@@ -2955,7 +2955,8 @@ typedef enum cp_lvalue_kind { ...@@ -2955,7 +2955,8 @@ typedef enum cp_lvalue_kind {
clk_none = 0, /* Things that are not an lvalue. */ clk_none = 0, /* Things that are not an lvalue. */
clk_ordinary = 1, /* An ordinary lvalue. */ clk_ordinary = 1, /* An ordinary lvalue. */
clk_class = 2, /* An rvalue of class-type. */ 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; } cp_lvalue_kind;
/* The kinds of scopes we recognize. */ /* The kinds of scopes we recognize. */
......
...@@ -100,11 +100,12 @@ lvalue_p_1 (tree ref, ...@@ -100,11 +100,12 @@ lvalue_p_1 (tree ref,
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0), op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues, treat_class_rvalues_as_lvalues,
allow_cast_as_lvalue); allow_cast_as_lvalue);
if (op1_lvalue_kind if (!op1_lvalue_kind
/* The "field" can be a FUNCTION_DECL or an OVERLOAD in some /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
situations. */ situations. */
&& TREE_CODE (TREE_OPERAND (ref, 1)) == FIELD_DECL || TREE_CODE (TREE_OPERAND (ref, 1)) != FIELD_DECL)
&& DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1))) ;
else if (DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
{ {
/* Clear the ordinary bit. If this object was a class /* Clear the ordinary bit. If this object was a class
rvalue we want to preserve that information. */ rvalue we want to preserve that information. */
...@@ -112,6 +113,9 @@ lvalue_p_1 (tree ref, ...@@ -112,6 +113,9 @@ lvalue_p_1 (tree ref,
/* The lvalue is for a btifield. */ /* The lvalue is for a btifield. */
op1_lvalue_kind |= clk_bitfield; op1_lvalue_kind |= clk_bitfield;
} }
else if (DECL_PACKED (TREE_OPERAND (ref, 1)))
op1_lvalue_kind |= clk_packed;
return op1_lvalue_kind; return op1_lvalue_kind;
case STRING_CST: case STRING_CST:
......
2003-07-22 Nathan Sidwell <nathan@codesourcery.com> 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. * gcc.dg/pack-test-3.c: New test.
2003-07-21 Janis Johnson <janis187@us.ibm.com> 2003-07-21 Janis Johnson <janis187@us.ibm.com>
......
// { 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" "" }
}
// { 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment