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> 2009-03-06 H.J. Lu <hongjiu.lu@intel.com>
PR c++/37520 PR c++/37520
......
...@@ -1787,23 +1787,14 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, ...@@ -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 /* True iff this is a call to "operator new[]" instead of just
"operator new". */ "operator new". */
bool array_p = false; bool array_p = false;
/* True iff ARRAY_P is true and the bound of the array type is /* If ARRAY_P is true, the element type of the array. This is never
not necessarily a compile time constant. For example, VLA_P is an ARRAY_TYPE; for something like "new int[3][4]", the
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
ELT_TYPE is "int". If ARRAY_P is false, this is the same type as ELT_TYPE is "int". If ARRAY_P is false, this is the same type as
FULL_TYPE. */ TYPE. */
tree elt_type; tree elt_type;
/* The type of the new-expression. (This type is always a pointer /* The type of the new-expression. (This type is always a pointer
type.) */ type.) */
tree pointer_type; tree pointer_type;
/* A pointer type pointing to the FULL_TYPE. */
tree full_pointer_type;
tree outer_nelts = NULL_TREE; tree outer_nelts = NULL_TREE;
tree alloc_call, alloc_expr; tree alloc_call, alloc_expr;
/* The address returned by the call to "operator new". This node is /* The address returned by the call to "operator new". This node is
...@@ -1834,35 +1825,15 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, ...@@ -1834,35 +1825,15 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
if (nelts) if (nelts)
{ {
tree index;
outer_nelts = nelts; outer_nelts = nelts;
array_p = true; 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 else if (TREE_CODE (type) == ARRAY_TYPE)
{ {
full_type = type; array_p = true;
if (TREE_CODE (type) == ARRAY_TYPE) nelts = array_type_nelts_top (type);
{ outer_nelts = nelts;
array_p = true; type = TREE_TYPE (type);
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 /* If our base type is an array, then make sure we know how many elements
...@@ -1897,21 +1868,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, ...@@ -1897,21 +1868,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
size = size_in_bytes (elt_type); size = size_in_bytes (elt_type);
if (array_p) if (array_p)
{ size = size_binop (MULT_EXPR, size, convert (sizetype, nelts));
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; alloc_fn = NULL_TREE;
...@@ -2139,8 +2096,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, ...@@ -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. */ /* Now use a pointer to the type we've actually allocated. */
full_pointer_type = build_pointer_type (full_type); data_addr = fold_convert (pointer_type, data_addr);
data_addr = fold_convert (full_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 /* Now initialize the allocated object. Note that we preevaluate the
initialization expression, apart from the actual constructor call or initialization expression, apart from the actual constructor call or
...@@ -2152,8 +2110,6 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, ...@@ -2152,8 +2110,6 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
bool stable; bool stable;
bool explicit_value_init_p = false; bool explicit_value_init_p = false;
init_expr = cp_build_indirect_ref (data_addr, NULL, complain);
if (init == void_zero_node) if (init == void_zero_node)
{ {
init = NULL_TREE; init = NULL_TREE;
...@@ -2170,7 +2126,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, ...@@ -2170,7 +2126,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
return error_mark_node; return error_mark_node;
} }
init_expr init_expr
= build_vec_init (init_expr, = build_vec_init (data_addr,
cp_build_binary_op (input_location, cp_build_binary_op (input_location,
MINUS_EXPR, outer_nelts, MINUS_EXPR, outer_nelts,
integer_one_node, integer_one_node,
...@@ -2187,6 +2143,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, ...@@ -2187,6 +2143,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
} }
else else
{ {
init_expr = cp_build_indirect_ref (data_addr, NULL, complain);
if (TYPE_NEEDS_CONSTRUCTING (type) && !explicit_value_init_p) if (TYPE_NEEDS_CONSTRUCTING (type) && !explicit_value_init_p)
{ {
init_expr = build_special_member_call (init_expr, init_expr = build_special_member_call (init_expr,
...@@ -2198,8 +2156,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, ...@@ -2198,8 +2156,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
else if (explicit_value_init_p) else if (explicit_value_init_p)
{ {
/* Something like `new int()'. */ /* Something like `new int()'. */
init_expr = build2 (INIT_EXPR, full_type, init_expr = build2 (INIT_EXPR, type,
init_expr, build_value_init (full_type)); init_expr, build_value_init (type));
} }
else else
{ {
...@@ -2240,7 +2198,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, ...@@ -2240,7 +2198,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
functions that we use for finding allocation functions. */ functions that we use for finding allocation functions. */
cleanup = (build_op_delete_call cleanup = (build_op_delete_call
(dcode, (dcode,
fold_convert (full_pointer_type, alloc_node), alloc_node,
size, size,
globally_qualified_p, globally_qualified_p,
placement_allocation_fn_p ? alloc_call : NULL_TREE, placement_allocation_fn_p ? alloc_call : NULL_TREE,
...@@ -2323,9 +2281,6 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, ...@@ -2323,9 +2281,6 @@ build_new_1 (tree placement, tree type, tree nelts, tree init,
if (init_preeval_expr) if (init_preeval_expr)
rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_preeval_expr, rval); 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. */ /* A new-expression is never an lvalue. */
gcc_assert (!lvalue_p (rval)); gcc_assert (!lvalue_p (rval));
...@@ -2665,9 +2620,10 @@ get_temp_regvar (tree type, tree init) ...@@ -2665,9 +2620,10 @@ get_temp_regvar (tree type, tree init)
/* `build_vec_init' returns tree structure that performs /* `build_vec_init' returns tree structure that performs
initialization of a vector of aggregate types. 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 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. TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE.
INIT is the (possibly NULL) initializer. INIT is the (possibly NULL) initializer.
...@@ -2692,7 +2648,7 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -2692,7 +2648,7 @@ build_vec_init (tree base, tree maxindex, tree init,
tree size; tree size;
tree itype = NULL_TREE; tree itype = NULL_TREE;
tree iterator; tree iterator;
/* The type of the array. */ /* The type of BASE. */
tree atype = TREE_TYPE (base); tree atype = TREE_TYPE (base);
/* The type of an element in the array. */ /* The type of an element in the array. */
tree type = TREE_TYPE (atype); tree type = TREE_TYPE (atype);
...@@ -2708,7 +2664,7 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -2708,7 +2664,7 @@ build_vec_init (tree base, tree maxindex, tree init,
int num_initialized_elts = 0; int num_initialized_elts = 0;
bool is_global; bool is_global;
if (TYPE_DOMAIN (atype)) if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype))
maxindex = array_type_nelts (atype); maxindex = array_type_nelts (atype);
if (maxindex == NULL_TREE || maxindex == error_mark_node) if (maxindex == NULL_TREE || maxindex == error_mark_node)
...@@ -2717,7 +2673,7 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -2717,7 +2673,7 @@ build_vec_init (tree base, tree maxindex, tree init,
if (explicit_value_init_p) if (explicit_value_init_p)
gcc_assert (!init); gcc_assert (!init);
inner_elt_type = strip_array_types (atype); inner_elt_type = strip_array_types (type);
if (init if (init
&& (from_array == 2 && (from_array == 2
? (!CLASS_TYPE_P (inner_elt_type) ? (!CLASS_TYPE_P (inner_elt_type)
...@@ -2734,15 +2690,20 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -2734,15 +2690,20 @@ build_vec_init (tree base, tree maxindex, tree init,
brace-enclosed initializers. In this case, digest_init and brace-enclosed initializers. In this case, digest_init and
store_constructor will handle the semantics for us. */ store_constructor will handle the semantics for us. */
gcc_assert (TREE_CODE (atype) == ARRAY_TYPE);
stmt_expr = build2 (INIT_EXPR, atype, base, init); stmt_expr = build2 (INIT_EXPR, atype, base, init);
return stmt_expr; return stmt_expr;
} }
maxindex = cp_convert (ptrdiff_type_node, maxindex); maxindex = cp_convert (ptrdiff_type_node, maxindex);
ptype = build_pointer_type (type);
size = size_in_bytes (type); size = size_in_bytes (type);
if (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE) if (TREE_CODE (atype) == ARRAY_TYPE)
base = cp_convert (ptype, decay_conversion (base)); {
ptype = build_pointer_type (type);
base = cp_convert (ptype, decay_conversion (base));
}
else
ptype = atype;
/* The code we are generating looks like: /* The code we are generating looks like:
({ ({
...@@ -2954,10 +2915,13 @@ build_vec_init (tree base, tree maxindex, tree init, ...@@ -2954,10 +2915,13 @@ build_vec_init (tree base, tree maxindex, tree init,
stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt); 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. */
atype = build_pointer_type (atype); if (TREE_CODE (atype) == ARRAY_TYPE)
stmt_expr = build1 (NOP_EXPR, atype, stmt_expr); {
stmt_expr = cp_build_indirect_ref (stmt_expr, NULL, complain); 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; current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
return stmt_expr; 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> 2009-03-06 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/33492 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