* PATCH: PR c++/32346
@ 2007-07-27 17:26 Mark Mitchell
0 siblings, 0 replies; only message in thread
From: Mark Mitchell @ 2007-07-27 17:26 UTC (permalink / raw)
To: gcc-patches
This is another patch for the ongoing series of problems with
bitfields in G++.
At the point of a call, we "promote" a bitfield to its declared type
so that, for example, an "int f:3" field is promoted to full "int".
But, we don't want to promote a "long long f:32" bitfield to "long
long" if the callee is expecting "int". That case is tricky because
we will (1) promote to "long long" at the point of use of the
bitfield, then (2) convert back to "int" to match the callee type --
and that second conversion, rather than introducing another NOP_EXPR,
removes the one created by (1), leaving us with what looks like an
unadorned bitfield.
All of these problems stem from the fact that we don't have a separate
C++ lowering pass. So, we get confused about when we should use the
declared type of a bitfield -- as required for C++ type-checking,
etc. -- and the representation type -- as required by the GCC middle
end. I'm not happy about the amount of special-case handling we now
have for bitfields, but I'm not sure that there's a better way.
Anyhow, tested on x86_64-unknown-linux-gnu, applied to the mainline.
I will also backport to 4.2.
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713
2007-07-27 Mark Mitchell <mark@codesourcery.com>
PR c++/32346
* call.c (convert_for_arg_passing): Only widen bitfields to their
declared types if necessary.
2007-07-27 Mark Mitchell <mark@codesourcery.com>
PR c++/32346
* g++.dg/expr/bitfield9.C: New test.
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c (revision 126963)
+++ gcc/cp/call.c (working copy)
@@ -4752,7 +4752,27 @@ type_passed_as (tree type)
tree
convert_for_arg_passing (tree type, tree val)
{
- val = convert_bitfield_to_declared_type (val);
+ tree bitfield_type;
+
+ /* If VAL is a bitfield, then -- since it has already been converted
+ to TYPE -- it cannot have a precision greater than TYPE.
+
+ If it has a smaller precision, we must widen it here. For
+ example, passing "int f:3;" to a function expecting an "int" will
+ not result in any conversion before this point.
+
+ If the precision is the same we must not risk widening. For
+ example, the COMPONENT_REF for a 32-bit "long long" bitfield will
+ often have type "int", even though the C++ type for the field is
+ "long long". If the value is being passed to a function
+ expecting an "int", then no conversions will be required. But,
+ if we call convert_bitfield_to_declared_type, the bitfield will
+ be converted to "long long". */
+ bitfield_type = is_bitfield_expr_with_lowered_type (val);
+ if (bitfield_type
+ && TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type))
+ val = convert_to_integer (TYPE_MAIN_VARIANT (bitfield_type), val);
+
if (val == error_mark_node)
;
/* Pass classes with copy ctors by invisible reference. */
Index: gcc/testsuite/g++.dg/expr/bitfield9.C
===================================================================
--- gcc/testsuite/g++.dg/expr/bitfield9.C (revision 0)
+++ gcc/testsuite/g++.dg/expr/bitfield9.C (revision 0)
@@ -0,0 +1,25 @@
+// PR c++/32346
+// { dg-do run }
+
+extern "C" void abort();
+
+struct S {
+ long long i : 32;
+};
+
+void f(int i, int j) {
+ if (i != 0xabcdef01)
+ abort();
+ if (j != 0)
+ abort();
+}
+
+void g(S s) {
+ f(s.i, 0);
+}
+
+int main() {
+ S s;
+ s.i = 0xabcdef01;
+ g(s);
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-07-27 17:19 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-07-27 17:26 PATCH: PR c++/32346 Mark Mitchell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).