* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103947
138bc75d-0d04-0410-961f-
82ee72b054a4
+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.
/* 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;
}
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);
}
}
+ 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;
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");
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;
}
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;
}
}
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;
+}
+
\f
static tree
build_cplus_array_type_1 (tree elt_type, tree index_type)
/* 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;
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;
}
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.
--- /dev/null
+void f(int &);
+void f(const int &);
+int main() {
+ volatile int x = 2;
+ f((int)x);
+}
--- /dev/null
+// 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];
+}