diff options
author | Jason Merrill <jason@redhat.com> | 2009-03-07 11:21:05 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-03-07 11:21:05 -0500 |
commit | 9207099bd3b168003016ab76e5aa56c7653803f7 (patch) | |
tree | 1ead560651b9192652ee6e5795102c95a6c1982b | |
parent | 3a695389b367b19c3987d050908c6e7fb58225f0 (diff) | |
download | gcc-9207099bd3b168003016ab76e5aa56c7653803f7.zip gcc-9207099bd3b168003016ab76e5aa56c7653803f7.tar.gz gcc-9207099bd3b168003016ab76e5aa56c7653803f7.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/init.c | 114 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/new1.C | 71 |
4 files changed, 121 insertions, 75 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index dcf3158..368843f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +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 diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 85c496b..8e3e489 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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,35 +1825,15 @@ 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 + 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 @@ -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; - } - } + size = size_binop (MULT_EXPR, size, convert (sizetype, nelts)); 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) - 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: ({ @@ -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. */ - 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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 891bdb7..f424f37 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +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 diff --git a/gcc/testsuite/g++.dg/opt/new1.C b/gcc/testsuite/g++.dg/opt/new1.C new file mode 100644 index 0000000..dbcc0f8 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/new1.C @@ -0,0 +1,71 @@ +// 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()); + } + } +} |