From 24030e4c48bd0c2c04981f223616484833c310e2 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 23 Jan 2008 02:50:45 +0100 Subject: [PATCH] re PR c++/33984 (bit-fields, references and overloads) gcc/cp/ChangeLog: PR c++/33984 * call.c (reference_binding): For bitfields use the declared bitfield type. (add_builtin_candidates): Likewise. * class.c (layout_class_type): For bitfields copy over the original type quals. gcc/testsuite/ChangeLog: PR c++/33984 * g++.dg/conversion/bitfield7.C: New test. * g++.dg/cpp0x/decltype4.C: Fixed xfail. From-SVN: r131751 --- gcc/cp/ChangeLog | 9 +++++++++ gcc/cp/call.c | 19 ++++++++++++------- gcc/cp/class.c | 14 +++++++++----- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/conversion/bitfield7.C | 16 ++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/decltype4.C | 2 +- 6 files changed, 53 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/g++.dg/conversion/bitfield7.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 45297deda43..f9971d4943d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2008-01-22 Jakub Jelinek , Alexandre Oliva + + PR c++/33984 + * call.c (reference_binding): For bitfields use the declared bitfield + type. + (add_builtin_candidates): Likewise. + * class.c (layout_class_type): For bitfields copy over the + original type quals. + 2008-01-22 Jason Merrill PR c++/34912 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f15550d7fda..1e591a61ac1 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1,6 +1,6 @@ /* Functions related to invoking methods and overloaded functions. Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) and modified by Brendan Kehoe (brendan@cygnus.com). @@ -1114,6 +1114,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) conversion *conv = NULL; tree to = TREE_TYPE (rto); tree from = rfrom; + tree tfrom; bool related_p; bool compatible_p; cp_lvalue_kind lvalue_p = clk_none; @@ -1135,16 +1136,20 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) else if (expr) lvalue_p = real_lvalue_p (expr); + tfrom = from; + if ((lvalue_p & clk_bitfield) != 0) + tfrom = unlowered_expr_type (expr); + /* Figure out whether or not the types are reference-related and reference compatible. We have do do this after stripping references from FROM. */ - related_p = reference_related_p (to, from); + related_p = reference_related_p (to, tfrom); /* If this is a C cast, first convert to an appropriately qualified type, so that we can later do a const_cast to the desired type. */ if (related_p && c_cast_p - && !at_least_as_qualified_p (to, from)) - to = build_qualified_type (to, cp_type_quals (from)); - compatible_p = reference_compatible_p (to, from); + && !at_least_as_qualified_p (to, tfrom)) + to = build_qualified_type (to, cp_type_quals (tfrom)); + compatible_p = reference_compatible_p (to, tfrom); /* Directly bind reference when target expression's type is compatible with the reference and expression is an lvalue. In DR391, the wording in @@ -1171,7 +1176,7 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) is bound to the object represented by the rvalue or to a sub-object within that object. */ - conv = build_identity_conv (from, expr); + conv = build_identity_conv (tfrom, expr); conv = direct_reference_binding (rto, conv); if (flags & LOOKUP_PREFER_RVALUE) @@ -2084,7 +2089,7 @@ add_builtin_candidates (struct z_candidate **candidates, enum tree_code code, for (i = 0; i < 3; ++i) { if (args[i]) - argtypes[i] = lvalue_type (args[i]); + argtypes[i] = unlowered_expr_type (args[i]); else argtypes[i] = NULL_TREE; } diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 6e67157a290..65e7144bfd7 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4795,14 +4795,18 @@ layout_class_type (tree t, tree *virtuals_p) must be converted to the type given the bitfield here. */ if (DECL_C_BIT_FIELD (field)) { - tree ftype; unsigned HOST_WIDE_INT width; - ftype = TREE_TYPE (field); + tree ftype = TREE_TYPE (field); width = tree_low_cst (DECL_SIZE (field), /*unsignedp=*/1); if (width != TYPE_PRECISION (ftype)) - TREE_TYPE (field) - = c_build_bitfield_integer_type (width, - TYPE_UNSIGNED (ftype)); + { + TREE_TYPE (field) + = c_build_bitfield_integer_type (width, + TYPE_UNSIGNED (ftype)); + TREE_TYPE (field) + = cp_build_qualified_type (TREE_TYPE (field), + TYPE_QUALS (ftype)); + } } /* If we needed additional padding after this field, add it diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ec42934bc9c..e0e47abbffc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2008-01-22 Jakub Jelinek + + PR c++/33984 + * g++.dg/conversion/bitfield7.C: New test. + * g++.dg/cpp0x/decltype4.C: Fixed xfail. + 2008-01-23 Bernd Schmidt From Michael Frysinger diff --git a/gcc/testsuite/g++.dg/conversion/bitfield7.C b/gcc/testsuite/g++.dg/conversion/bitfield7.C new file mode 100644 index 00000000000..1080168dce1 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/bitfield7.C @@ -0,0 +1,16 @@ +// PR c++/33984 +// { dg-do compile } + +struct S +{ + unsigned int bar : 3; +} s; + +int foo (unsigned int &); +int foo (double); + +int +main () +{ + return foo (s.bar); // { dg-error "cannot bind bitfield" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype4.C b/gcc/testsuite/g++.dg/cpp0x/decltype4.C index 18f27346811..23a34344e17 100644 --- a/gcc/testsuite/g++.dg/cpp0x/decltype4.C +++ b/gcc/testsuite/g++.dg/cpp0x/decltype4.C @@ -70,7 +70,7 @@ struct B { CHECK_DECLTYPE(decltype(bit), int); CHECK_DECLTYPE(decltype((bit)), int&); CHECK_DECLTYPE(decltype(cbit), const int); - CHECK_DECLTYPE(decltype((cbit)), const int&); // { dg-bogus "static assertion failed" "GCC gets the actual type of this expression wrong" { xfail *-*-* } 73 } + CHECK_DECLTYPE(decltype((cbit)), const int&); } }; -- 2.30.2