Commit 5cc53d4e by Mark Mitchell Committed by Mark Mitchell

re PR c++/9782 (constructor not called on higher-dimensional arrays of template types)

	* cp-tree.h (rvalue): New function.
	* call.c (build_conditional_expr): Use it.
	* init.c (build_new_1): Likewise.
	* rtti.c (build_dynamic_cast_1): Likewise.
	* tree.c (rvalue): New function.
	* typeck.c (build_unary_op): Use it.
	(build_static_cast_1): Likewise.

	* g++.dg/expr/cast6.C: New test.

	PR c++/9782
	* init.c (build_new_1): Make sure the entire array type is
	complete, not just its element types.

	PR c++/9782
	* g++.dg/init/new15.C: New test.

From-SVN: r103947
parent d102ae00
2005-09-06 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (rvalue): New function.
* call.c (build_conditional_expr): Use it.
* init.c (build_new_1): Likewise.
* rtti.c (build_dynamic_cast_1): Likewise.
* tree.c (rvalue): New function.
* typeck.c (build_unary_op): Use it.
(build_static_cast_1): Likewise.
PR c++/9782
* init.c (build_new_1): Make sure the entire array type is
complete, not just its element types.
2005-09-06 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
* decl.c (check_elaborated_type_specifier): Remove redundant check.
......
......@@ -3486,7 +3486,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3)
/* If this expression is an rvalue, but might be mistaken for an
lvalue, we must add a NON_LVALUE_EXPR. */
if (!lvalue_p && real_lvalue_p (result))
result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
result = rvalue (result);
return result;
}
......
......@@ -4263,7 +4263,8 @@ extern int cp_cannot_inline_tree_fn (tree*);
extern tree cp_add_pending_fn_decls (void*,tree);
extern int cp_auto_var_in_fn_p (tree,tree);
extern tree fold_if_not_in_template (tree);
extern tree rvalue (tree);
/* in typeck.c */
extern int string_conv_p (tree, tree, int);
extern tree cp_truthvalue_conversion (tree);
......
......@@ -1838,6 +1838,9 @@ build_new_1 (tree exp)
}
}
if (!complete_type_or_else (type, exp))
return error_mark_node;
/* If our base type is an array, then make sure we know how many elements
it has. */
for (elt_type = type;
......@@ -1846,9 +1849,6 @@ build_new_1 (tree exp)
nelts = cp_build_binary_op (MULT_EXPR, nelts,
array_type_nelts_top (elt_type));
if (!complete_type_or_else (elt_type, exp))
return error_mark_node;
if (TREE_CODE (elt_type) == VOID_TYPE)
{
error ("invalid type %<void%> for new");
......@@ -2227,8 +2227,7 @@ build_new_1 (tree exp)
rval = build_nop (pointer_type, rval);
/* A new-expression is never an lvalue. */
if (real_lvalue_p (rval))
rval = build1 (NON_LVALUE_EXPR, TREE_TYPE (rval), rval);
rval = rvalue (rval);
return rval;
}
......
......@@ -555,7 +555,7 @@ build_dynamic_cast_1 (tree type, tree expr)
expr = build_base_path (PLUS_EXPR, convert_from_reference (expr),
binfo, 0);
if (TREE_CODE (exprtype) == POINTER_TYPE)
expr = non_lvalue (expr);
expr = rvalue (expr);
return expr;
}
}
......
......@@ -365,6 +365,26 @@ get_target_expr (tree init)
return build_target_expr_with_type (init, TREE_TYPE (init));
}
/* EXPR is being used in an rvalue context. Return a version of EXPR
that is marked as an rvalue. */
tree
rvalue (tree expr)
{
tree type;
if (real_lvalue_p (expr))
{
type = TREE_TYPE (expr);
/* [basic.lval]
Non-class rvalues always have cv-unqualified types. */
if (!CLASS_TYPE_P (type))
type = TYPE_MAIN_VARIANT (type);
expr = build1 (NON_LVALUE_EXPR, type, expr);
}
return expr;
}
static tree
build_cplus_array_type_1 (tree elt_type, tree index_type)
......
......@@ -3768,8 +3768,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
/* Make sure the result is not an lvalue: a unary plus or minus
expression is always a rvalue. */
if (real_lvalue_p (arg))
arg = build1 (NON_LVALUE_EXPR, TREE_TYPE (arg), arg);
arg = rvalue (arg);
}
}
break;
......@@ -4016,9 +4015,9 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
tree type = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
arg = build1 (CONVERT_EXPR, type, arg);
}
else if (lvalue_p (arg))
else
/* Don't let this be an lvalue. */
return non_lvalue (arg);
arg = rvalue (arg);
return arg;
}
......@@ -4666,9 +4665,8 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
If T is a reference type, the result is an lvalue; otherwise,
the result is an rvalue. */
if (TREE_CODE (type) != REFERENCE_TYPE
&& real_lvalue_p (result))
result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
if (TREE_CODE (type) != REFERENCE_TYPE)
result = rvalue (result);
return result;
}
......
2005-09-06 Mark Mitchell <mark@codesourcery.com>
* g++.dg/expr/cast6.C: New test.
PR c++/9782
* g++.dg/init/new15.C: New test.
2005-09-06 Keith Besaw <kbesaw@us.ibm.com>
* gcc.dg/vect/Os-vect-95.c: New test.
void f(int &);
void f(const int &);
int main() {
volatile int x = 2;
f((int)x);
}
// PR c++/9782
extern "C" void printf(char *, ...);
template <int>
struct A {
A() {printf("A::A()\n");}
};
struct B {
B() {printf("B::B()\n");}
};
int main () {
new A<0>[1][1];
new B [1][1];
}
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