cp-tree.h (enum cp_lvalue_kind): Add clk_packed.
authorNathan Sidwell <nathan@codesourcery.com>
Tue, 22 Jul 2003 09:53:34 +0000 (09:53 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Tue, 22 Jul 2003 09:53:34 +0000 (09:53 +0000)
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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/packed3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/packed4.C [new file with mode: 0644]

index d13909bf29b427483a4a336d308a762ba67105a7..d7a59661e24c288bb47ae600fa10e8957b109585 100644 (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.
index 013d60059a024c8d9088056908d8624d9431e175..022ac78add6044d0ef3e7560bca31ea50d261369 100644 (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);
          }
 
index b9f139fc645004e1ca1ea687e65be1a37f9a6eb3..06cb635671949afe9bf47e45b2aed9c2dafa466c 100644 (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
index 29a9f290d9baa25963181fe6e9970eea0dd55dff..8fef2deb96d1bd09e75ce1a99a2588e93a3016e2 100644 (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.  */
index 72173fe48bb6c0c481181850bc19b5dd69a9cecd..59722ac40866206977466305704d544427ea413b 100644 (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:
index 25fd05966c1071cf9c2b3db0d05bc8efd4826f86..646613a5bb733c99f9849dfd6084b6d10e76a90c 100644 (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>
diff --git a/gcc/testsuite/g++.dg/ext/packed3.C b/gcc/testsuite/g++.dg/ext/packed3.C
new file mode 100644 (file)
index 0000000..b6e891f
--- /dev/null
@@ -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" "" }
+}
diff --git a/gcc/testsuite/g++.dg/ext/packed4.C b/gcc/testsuite/g++.dg/ext/packed4.C
new file mode 100644 (file)
index 0000000..c32a0fa
--- /dev/null
@@ -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);
+}