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:
parent
dea4e8d064
commit
41b81065ae
9 changed files with 61 additions and 63 deletions
|
@ -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,
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
24
gcc/testsuite/g++.dg/conversion/bitfield10.C
Normal file
24
gcc/testsuite/g++.dg/conversion/bitfield10.C
Normal 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;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
// PR c++/32346
|
||||
// { dg-do run }
|
||||
// { dg-options "-Wno-overflow" }
|
||||
|
||||
extern "C" void abort();
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -8,4 +8,4 @@ struct Type {
|
|||
void setBTK();
|
||||
};
|
||||
|
||||
void Type::setBTK() { kind = DTK; }
|
||||
void Type::setBTK() { kind = DTK; } // { dg-warning "truncate" }
|
||||
|
|
Loading…
Add table
Reference in a new issue