re PR c++/38007 (g++ instantiate same operator twice due to bitfield in -O0 mode, causing symbol already defined assembler error)

PR c++/38007                                                                                     
gcc/cp/                                                                                                  
        * typeck.c (cp_build_modify_expr): Update bitfield handling.                                     
gcc/                                                                                                     
        * c-common.c (c_common_signed_or_unsigned_type): Remove C++                                      
        special casing.                                                                                  
gcc/testsuite/                                                                                           
        * g++.dg/conversion/bitfield10.C: New test.                                                      
        * g++.dg/warn/pr35635.C (func1): Accept additional warning.                                      
        * g++.old-deja/g++.mike/enum1.C: Expect warn about assignment.                                   
        * g++.dg/expr/bitfield9.C: Pass -Wno-overflow.

From-SVN: r141800
This commit is contained in:
Jason Merrill 2008-11-12 15:50:45 -05:00 committed by Jason Merrill
parent dea4e8d064
commit 41b81065ae
9 changed files with 61 additions and 63 deletions

View file

@ -1,3 +1,9 @@
2008-11-12 Jason Merrill <jason@redhat.com>
PR c++/38007
* c-common.c (c_common_signed_or_unsigned_type): Remove C++
special casing.
2008-11-12 Anatoly Sokolov <aesok@post.ru>
* config/avr/avr.c (avr_mcu_t): Add atmega16hvb, atmega32hvb,

View file

@ -2719,7 +2719,7 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type)
#define TYPE_OK(node) \
(TYPE_MODE (type) == TYPE_MODE (node) \
&& (c_dialect_cxx () || TYPE_PRECISION (type) == TYPE_PRECISION (node)))
&& TYPE_PRECISION (type) == TYPE_PRECISION (node))
if (TYPE_OK (signed_char_type_node))
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
if (TYPE_OK (integer_type_node))
@ -2749,10 +2749,7 @@ c_common_signed_or_unsigned_type (int unsignedp, tree type)
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
#undef TYPE_OK
if (c_dialect_cxx ())
return type;
else
return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp);
return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp);
}
/* Build a bit-field integer type for the given WIDTH and UNSIGNEDP. */

View file

@ -1,3 +1,8 @@
2008-11-12 Jason Merrill <jason@redhat.com>
PR c++/38007
* typeck.c (cp_build_modify_expr): Update bitfield handling.
2008-11-12 Jakub Jelinek <jakub@redhat.com>
PR c++/34269

View file

@ -5801,7 +5801,6 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
tree newrhs = rhs;
tree lhstype = TREE_TYPE (lhs);
tree olhstype = lhstype;
tree olhs = NULL_TREE;
bool plain_assign = (modifycode == NOP_EXPR);
/* Avoid duplicate error messages from operands that had errors. */
@ -6005,35 +6004,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
return error_mark_node;
}
/* If storing into a structure or union member, it has probably been
given type `int'. Compute the type that would go with the actual
amount of storage the member occupies. */
/* If storing into a structure or union member, it may have been given a
lowered bitfield type. We need to convert to the declared type first,
so retrieve it now. */
if (TREE_CODE (lhs) == COMPONENT_REF
&& (TREE_CODE (lhstype) == INTEGER_TYPE
|| TREE_CODE (lhstype) == REAL_TYPE
|| TREE_CODE (lhstype) == ENUMERAL_TYPE))
{
lhstype = TREE_TYPE (get_unwidened (lhs, 0));
/* If storing in a field that is in actuality a short or narrower
than one, we must store in the field in its actual type. */
if (lhstype != TREE_TYPE (lhs))
{
/* Avoid warnings converting integral types back into enums for
enum bit fields. */
if (TREE_CODE (lhstype) == INTEGER_TYPE
&& TREE_CODE (olhstype) == ENUMERAL_TYPE)
{
if (TREE_SIDE_EFFECTS (lhs))
lhs = stabilize_reference (lhs);
olhs = lhs;
}
lhs = copy_node (lhs);
TREE_TYPE (lhs) = lhstype;
}
}
olhstype = unlowered_expr_type (lhs);
/* Convert new value to destination type. */
@ -6073,22 +6048,18 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
}
if (modifycode == INIT_EXPR)
newrhs = convert_for_initialization (lhs, lhstype, newrhs, LOOKUP_NORMAL,
newrhs = convert_for_initialization (lhs, olhstype, newrhs, LOOKUP_NORMAL,
"initialization", NULL_TREE, 0,
complain);
else
newrhs = convert_for_assignment (olhstype, newrhs, "assignment",
NULL_TREE, 0, complain);
if (!same_type_p (lhstype, olhstype))
newrhs = cp_convert_and_check (lhstype, newrhs);
if (modifycode != INIT_EXPR)
{
/* Avoid warnings on enum bit fields. */
if (TREE_CODE (olhstype) == ENUMERAL_TYPE
&& TREE_CODE (lhstype) == INTEGER_TYPE)
{
newrhs = convert_for_assignment (olhstype, newrhs, "assignment",
NULL_TREE, 0, complain);
newrhs = convert_force (lhstype, newrhs, 0);
}
else
newrhs = convert_for_assignment (lhstype, newrhs, "assignment",
NULL_TREE, 0, complain);
if (TREE_CODE (newrhs) == CALL_EXPR
&& TYPE_NEEDS_CONSTRUCTING (lhstype))
newrhs = build_cplus_new (lhstype, newrhs);
@ -6120,21 +6091,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
if (!plain_assign)
TREE_NO_WARNING (result) = 1;
/* If we got the LHS in a different type for storing in,
convert the result back to the nominal type of LHS
so that the value we return always has the same type
as the LHS argument. */
if (olhstype == TREE_TYPE (result))
return result;
if (olhs)
{
result = build2 (COMPOUND_EXPR, olhstype, result, olhs);
TREE_NO_WARNING (result) = 1;
return result;
}
return convert_for_assignment (olhstype, result, "assignment",
NULL_TREE, 0, complain);
return result;
}
tree

View file

@ -1,3 +1,11 @@
2008-11-12 Jason Merrill <jason@redhat.com>
PR c++/38007
* g++.dg/conversion/bitfield10.C: New test.
* g++.dg/warn/pr35635.C (func1): Accept additional warning.
* g++.old-deja/g++.mike/enum1.C: Expect warn about assignment.
* g++.dg/expr/bitfield9.C: Pass -Wno-overflow.
2008-11-12 Tobias Burnus <burnus@net-b.de>
PR fortran/38065

View file

@ -0,0 +1,24 @@
// PR c++/38007
// We need to use the conversion function to the declared type of a bitfield,
// not the lowered bitfield type.
// { dg-do link }
struct A
{
operator unsigned int() { return 42; }
operator unsigned char();
};
struct B
{
unsigned int b : 8;
};
int
main ()
{
A u;
unsigned int v = u;
B w;
w.b = u;
}

View file

@ -1,5 +1,6 @@
// PR c++/32346
// { dg-do run }
// { dg-options "-Wno-overflow" }
extern "C" void abort();

View file

@ -32,7 +32,7 @@ void func1()
/* At least one branch of ? does not fit in the destination, thus
warn. */
unsigned_bit.x = bar != 0 ? 2 : 0; /* { dg-warning "conversion" } */
unsigned_bit.x = bar != 0 ? 0 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
unsigned_bit.x = bar != 0 ? 0 : -1; /* { dg-warning "conver" } */
}
void func2()

View file

@ -8,4 +8,4 @@ struct Type {
void setBTK();
};
void Type::setBTK() { kind = DTK; }
void Type::setBTK() { kind = DTK; } // { dg-warning "truncate" }