/* 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
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
+ else if (TREE_CODE (type) == ARRAY_TYPE)
{
- full_type = type;
- if (TREE_CODE (type) == ARRAY_TYPE)
- {
- array_p = true;
- nelts = array_type_nelts_top (type);
- outer_nelts = nelts;
- type = TREE_TYPE (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
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;
- }
- }
+ size = size_binop (MULT_EXPR, size, convert (sizetype, nelts));
alloc_fn = NULL_TREE;
}
/* 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
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;
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,
}
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,
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
{
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,
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));
/* `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.
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);
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)
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)
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)
- base = cp_convert (ptype, decay_conversion (base));
+ 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:
({
stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
- /* Now convert make the result have the correct type. */
- atype = build_pointer_type (atype);
- stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
- stmt_expr = cp_build_indirect_ref (stmt_expr, NULL, complain);
+ /* 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;
--- /dev/null
+// 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());
+ }
+ }
+}