re PR c++/70393 (Miscompilation: missing constructor call for static object)
PR c++/70393 * varasm.c (output_constructor_regular_field): Flush bitfield earlier. Assert we don't want to move backwards. cp/ * constexpr.c (cxx_eval_store_expression): Keep CONSTRUCTOR elements in field order. testsuite/ * g++.dg/cpp0x/constexpr-virtual6.C: New. From-SVN: r234636
This commit is contained in:
parent
95d34b9618
commit
88504f3435
|
@ -1,3 +1,9 @@
|
|||
2016-03-31 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
PR c++/70393
|
||||
* varasm.c (output_constructor_regular_field): Flush bitfield
|
||||
earlier. Assert we don't want to move backwards.
|
||||
|
||||
2016-03-31 Kirill Yukhin <kirill.yukhin@intel.com>
|
||||
|
||||
PR target/70453
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2016-03-31 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
PR c++/70393
|
||||
* constexpr.c (cxx_eval_store_expression): Keep CONSTRUCTOR
|
||||
elements in field order.
|
||||
|
||||
2016-03-31 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c/70297
|
||||
|
|
|
@ -2959,16 +2959,39 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
|
|||
else
|
||||
{
|
||||
gcc_assert (TREE_CODE (index) == FIELD_DECL);
|
||||
for (unsigned HOST_WIDE_INT idx = 0;
|
||||
|
||||
/* We must keep the CONSTRUCTOR's ELTS in FIELD order.
|
||||
Usually we meet initializers in that order, but it is
|
||||
possible for base types to be placed not in program
|
||||
order. */
|
||||
tree fields = TYPE_FIELDS (DECL_CONTEXT (index));
|
||||
unsigned HOST_WIDE_INT idx;
|
||||
|
||||
for (idx = 0;
|
||||
vec_safe_iterate (CONSTRUCTOR_ELTS (*valp), idx, &cep);
|
||||
idx++)
|
||||
if (index == cep->index)
|
||||
break;
|
||||
if (!cep)
|
||||
idx++, fields = DECL_CHAIN (fields))
|
||||
{
|
||||
constructor_elt ce = { index, NULL_TREE };
|
||||
cep = vec_safe_push (CONSTRUCTOR_ELTS (*valp), ce);
|
||||
if (index == cep->index)
|
||||
goto found;
|
||||
|
||||
/* The field we're initializing must be on the field
|
||||
list. Look to see if it is present before the
|
||||
field the current ELT initializes. */
|
||||
for (; fields != cep->index; fields = DECL_CHAIN (fields))
|
||||
if (index == fields)
|
||||
goto insert;
|
||||
}
|
||||
|
||||
/* We fell off the end of the CONSTRUCTOR, so insert a new
|
||||
entry at the end. */
|
||||
insert:
|
||||
{
|
||||
constructor_elt ce = { index, NULL_TREE };
|
||||
|
||||
vec_safe_insert (CONSTRUCTOR_ELTS (*valp), idx, ce);
|
||||
cep = CONSTRUCTOR_ELT (*valp, idx);
|
||||
}
|
||||
found:;
|
||||
}
|
||||
valp = &cep->value;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2016-03-31 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
PR c++/70393
|
||||
* g++.dg/cpp0x/constexpr-virtual6.C: New.
|
||||
|
||||
2016-03-31 Kirill Yukhin <kirill.yukhin@intel.com>
|
||||
|
||||
PR target/70453
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
// PR c++/70393
|
||||
// { dg-do run { target c++11 } }
|
||||
|
||||
/* 'ab' has a static initializer, but we flubbed the initializer,
|
||||
because of B being the primary base. */
|
||||
|
||||
struct A
|
||||
{
|
||||
int a = 1;
|
||||
};
|
||||
|
||||
struct B
|
||||
{
|
||||
B *element = (B*)2;
|
||||
|
||||
virtual int vfunc() = 0;
|
||||
|
||||
int call_element()
|
||||
{
|
||||
return element->vfunc();
|
||||
}
|
||||
|
||||
void set_element()
|
||||
{
|
||||
element = this;
|
||||
}
|
||||
};
|
||||
|
||||
struct AB : public A, public B
|
||||
{
|
||||
int vfunc()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
static AB ab;
|
||||
|
||||
int main()
|
||||
{
|
||||
if (ab.a != 1)
|
||||
return 1;
|
||||
if (ab.element != (void*)2)
|
||||
return 2;
|
||||
|
||||
ab.set_element();
|
||||
return ab.call_element();
|
||||
}
|
||||
|
29
gcc/varasm.c
29
gcc/varasm.c
|
@ -4929,6 +4929,14 @@ output_constructor_regular_field (oc_local_state *local)
|
|||
|
||||
unsigned int align2;
|
||||
|
||||
/* Output any buffered-up bit-fields preceding this element. */
|
||||
if (local->byte_buffer_in_use)
|
||||
{
|
||||
assemble_integer (GEN_INT (local->byte), 1, BITS_PER_UNIT, 1);
|
||||
local->total_bytes++;
|
||||
local->byte_buffer_in_use = false;
|
||||
}
|
||||
|
||||
if (local->index != NULL_TREE)
|
||||
{
|
||||
/* Perform the index calculation in modulo arithmetic but
|
||||
|
@ -4945,22 +4953,19 @@ output_constructor_regular_field (oc_local_state *local)
|
|||
else
|
||||
fieldpos = 0;
|
||||
|
||||
/* Output any buffered-up bit-fields preceding this element. */
|
||||
if (local->byte_buffer_in_use)
|
||||
{
|
||||
assemble_integer (GEN_INT (local->byte), 1, BITS_PER_UNIT, 1);
|
||||
local->total_bytes++;
|
||||
local->byte_buffer_in_use = false;
|
||||
}
|
||||
|
||||
/* Advance to offset of this element.
|
||||
Note no alignment needed in an array, since that is guaranteed
|
||||
if each element has the proper size. */
|
||||
if ((local->field != NULL_TREE || local->index != NULL_TREE)
|
||||
&& fieldpos > local->total_bytes)
|
||||
if (local->field != NULL_TREE || local->index != NULL_TREE)
|
||||
{
|
||||
assemble_zeros (fieldpos - local->total_bytes);
|
||||
local->total_bytes = fieldpos;
|
||||
if (fieldpos > local->total_bytes)
|
||||
{
|
||||
assemble_zeros (fieldpos - local->total_bytes);
|
||||
local->total_bytes = fieldpos;
|
||||
}
|
||||
else
|
||||
/* Must not go backwards. */
|
||||
gcc_assert (fieldpos == local->total_bytes);
|
||||
}
|
||||
|
||||
/* Find the alignment of this element. */
|
||||
|
|
Loading…
Reference in New Issue