Commit 9207099b by Jason Merrill Committed by Jason Merrill

re PR c++/39367 (ICE at tree-inline.c:1042 with -O)

        PR c++/39367
        * init.c (build_new_1): Don't use a VLA type.
        (build_vec_init): Handle getting a pointer for BASE.

From-SVN: r144697
parent 3a695389
2009-03-07 Jason Merrill <jason@redhat.com>
PR c++/39367
* init.c (build_new_1): Don't use a VLA type.
(build_vec_init): Handle getting a pointer for BASE.
2009-03-06 H.J. Lu <hongjiu.lu@intel.com>
PR c++/37520
......
......@@ -1787,23 +1787,14 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
/* True iff this is a call to "operator new[]" instead of just
"operator new". */
bool array_p = false;
/* True iff ARRAY_P is true and the bound of the array type is
not necessarily a compile time constant. For example, VLA_P is
true for "new int[f()]". */
bool vla_p = false;
/* The type being allocated. If ARRAY_P is true, this will be an
ARRAY_TYPE. */
tree full_type;
/* If ARRAY_P is true, the element type of the array. This is an
never ARRAY_TYPE; for something like "new int[3][4]", the
/* If ARRAY_P is true, the element type of the array. This is never
an ARRAY_TYPE; for something like "new int[3][4]", the
ELT_TYPE is "int". If ARRAY_P is false, this is the same type as
FULL_TYPE. */
TYPE. */
tree elt_type;
/* The type of the new-expression. (This type is always a pointer
type.) */
tree pointer_type;
/* A pointer type pointing to the FULL_TYPE. */
tree full_pointer_type;
tree outer_nelts = NULL_TREE;
tree alloc_call, alloc_expr;
/* The address returned by the call to "operator new". This node is
......@@ -1834,36 +1825,16 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
if (nelts)
{
tree index;
outer_nelts = nelts;
array_p = true;
/* ??? The middle-end will error on us for building a VLA outside a
function context. Methinks that's not it's purvey. So we'll do
our own VLA layout later. */
vla_p = true;
index = convert (sizetype, nelts);
index = size_binop (MINUS_EXPR, index, size_one_node);
index = build_index_type (index);
full_type = build_cplus_array_type (type, NULL_TREE);
/* We need a copy of the type as build_array_type will return a shared copy
of the incomplete array type. */
full_type = build_distinct_type_copy (full_type);
TYPE_DOMAIN (full_type) = index;
SET_TYPE_STRUCTURAL_EQUALITY (full_type);
}
else
{
full_type = type;
if (TREE_CODE (type) == ARRAY_TYPE)
else if (TREE_CODE (type) == ARRAY_TYPE)
{
array_p = true;
nelts = array_type_nelts_top (type);
outer_nelts = nelts;
type = TREE_TYPE (type);
}
}
/* If our base type is an array, then make sure we know how many elements
it has. */
......@@ -1897,21 +1868,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
size = size_in_bytes (elt_type);
if (array_p)
{
size = size_binop (MULT_EXPR, size, convert (sizetype, nelts));
if (vla_p)
{
tree n, bitsize;
/* Do our own VLA layout. Setting TYPE_SIZE/_UNIT is
necessary in order for the <INIT_EXPR <*foo> <CONSTRUCTOR
...>> to be valid. */
TYPE_SIZE_UNIT (full_type) = size;
n = convert (bitsizetype, nelts);
bitsize = size_binop (MULT_EXPR, TYPE_SIZE (elt_type), n);
TYPE_SIZE (full_type) = bitsize;
}
}
alloc_fn = NULL_TREE;
......@@ -2139,8 +2096,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
}
/* Now use a pointer to the type we've actually allocated. */
full_pointer_type = build_pointer_type (full_type);
data_addr = fold_convert (full_pointer_type, data_addr);
data_addr = fold_convert (pointer_type, data_addr);
/* Any further uses of alloc_node will want this type, too. */
alloc_node = fold_convert (pointer_type, alloc_node);
/* Now initialize the allocated object. Note that we preevaluate the
initialization expression, apart from the actual constructor call or
......@@ -2152,8 +2110,6 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
bool stable;
bool explicit_value_init_p = false;
init_expr = cp_build_indirect_ref (data_addr, NULL, complain);
if (init == void_zero_node)
{
init = NULL_TREE;
......@@ -2170,7 +2126,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
return error_mark_node;
}
init_expr
= build_vec_init (init_expr,
= build_vec_init (data_addr,
cp_build_binary_op (input_location,
MINUS_EXPR, outer_nelts,
integer_one_node,
......@@ -2187,6 +2143,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
}
else
{
init_expr = cp_build_indirect_ref (data_addr, NULL, complain);
if (TYPE_NEEDS_CONSTRUCTING (type) && !explicit_value_init_p)
{
init_expr = build_special_member_call (init_expr,
......@@ -2198,8 +2156,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
else if (explicit_value_init_p)
{
/* Something like `new int()'. */
init_expr = build2 (INIT_EXPR, full_type,
init_expr, build_value_init (full_type));
init_expr = build2 (INIT_EXPR, type,
init_expr, build_value_init (type));
}
else
{
......@@ -2240,7 +2198,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
functions that we use for finding allocation functions. */
cleanup = (build_op_delete_call
(dcode,
fold_convert (full_pointer_type, alloc_node),
alloc_node,
size,
globally_qualified_p,
placement_allocation_fn_p ? alloc_call : NULL_TREE,
......@@ -2323,9 +2281,6 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
if (init_preeval_expr)
rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_preeval_expr, rval);
/* Convert to the final type. */
rval = build_nop (pointer_type, rval);
/* A new-expression is never an lvalue. */
gcc_assert (!lvalue_p (rval));
......@@ -2665,9 +2620,10 @@ get_temp_regvar (tree type, tree init)
/* `build_vec_init' returns tree structure that performs
initialization of a vector of aggregate types.
BASE is a reference to the vector, of ARRAY_TYPE.
BASE is a reference to the vector, of ARRAY_TYPE, or a pointer
to the first element, of POINTER_TYPE.
MAXINDEX is the maximum index of the array (one less than the
number of elements). It is only used if
number of elements). It is only used if BASE is a pointer or
TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE.
INIT is the (possibly NULL) initializer.
......@@ -2692,7 +2648,7 @@ build_vec_init (tree base, tree maxindex, tree init,
tree size;
tree itype = NULL_TREE;
tree iterator;
/* The type of the array. */
/* The type of BASE. */
tree atype = TREE_TYPE (base);
/* The type of an element in the array. */
tree type = TREE_TYPE (atype);
......@@ -2708,7 +2664,7 @@ build_vec_init (tree base, tree maxindex, tree init,
int num_initialized_elts = 0;
bool is_global;
if (TYPE_DOMAIN (atype))
if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype))
maxindex = array_type_nelts (atype);
if (maxindex == NULL_TREE || maxindex == error_mark_node)
......@@ -2717,7 +2673,7 @@ build_vec_init (tree base, tree maxindex, tree init,
if (explicit_value_init_p)
gcc_assert (!init);
inner_elt_type = strip_array_types (atype);
inner_elt_type = strip_array_types (type);
if (init
&& (from_array == 2
? (!CLASS_TYPE_P (inner_elt_type)
......@@ -2734,15 +2690,20 @@ build_vec_init (tree base, tree maxindex, tree init,
brace-enclosed initializers. In this case, digest_init and
store_constructor will handle the semantics for us. */
gcc_assert (TREE_CODE (atype) == ARRAY_TYPE);
stmt_expr = build2 (INIT_EXPR, atype, base, init);
return stmt_expr;
}
maxindex = cp_convert (ptrdiff_type_node, maxindex);
ptype = build_pointer_type (type);
size = size_in_bytes (type);
if (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
if (TREE_CODE (atype) == ARRAY_TYPE)
{
ptype = build_pointer_type (type);
base = cp_convert (ptype, decay_conversion (base));
}
else
ptype = atype;
/* The code we are generating looks like:
({
......@@ -2954,10 +2915,13 @@ build_vec_init (tree base, tree maxindex, tree init,
stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
/* Now convert make the result have the correct type. */
/* Now make the result have the correct type. */
if (TREE_CODE (atype) == ARRAY_TYPE)
{
atype = build_pointer_type (atype);
stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
stmt_expr = cp_build_indirect_ref (stmt_expr, NULL, complain);
}
current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
return stmt_expr;
......
2009-03-07 Jason Merrill <jason@redhat.com>
PR c++/39367
* g++.dg/opt/new1.C: New.
2009-03-06 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/33492
......
// PR c++/39367
// { dg-options "-O" }
class QScriptEnginePrivate;
class QScriptClassInfo;
namespace QScript {
enum Type { InvalidType };
};
class QScriptValueImpl {
public:
inline QScriptValueImpl();
QScript::Type m_type;
};
namespace QScript {
namespace Ecma {
class Core {
public:
inline QScriptEnginePrivate *engine() const { }
inline QScriptClassInfo *classInfo() const { }
QScriptValueImpl publicPrototype;
};
class Boolean: public Core {
void newBoolean(QScriptValueImpl *result, bool value = false);
};
}
template <typename T> class Buffer {
public:
inline void reserve(int num);
inline void resize(int s);
T *m_data;
int m_capacity;
int m_size;
};
}
template <typename T> void QScript::Buffer<T>::resize(int s) {
if (m_capacity < s)
reserve (s << 1);
}
template <typename T> void QScript::Buffer<T>::reserve(int x) {
T *new_data = new T[m_capacity];
for (int i=0; i<m_size; ++i)
new_data[i] = m_data[i];
}
class QScriptObject {
public:
inline void reset();
QScript::Buffer<QScriptValueImpl> m_values;
};
class QScriptEnginePrivate {
public:
inline QScriptObject *allocObject() { return 0; }
inline void newObject(QScriptValueImpl *o, const QScriptValueImpl &proto,
QScriptClassInfo *oc = 0);
};
inline void QScriptEnginePrivate::newObject(QScriptValueImpl *o,
const QScriptValueImpl &proto,
QScriptClassInfo *oc)
{
QScriptObject *od = allocObject();
od->reset();
}
inline QScriptValueImpl::QScriptValueImpl() : m_type(QScript::InvalidType) { }
inline void QScriptObject::reset() { m_values.resize(0); }
namespace QScript {
namespace Ecma {
void Boolean::newBoolean(QScriptValueImpl *result, bool value)
{
engine()->newObject(result, publicPrototype, classInfo());
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment