Commit d17811fd by Mark Mitchell Committed by Mark Mitchell

fold-const.c (make_range): Do not access operand 1 for a zero-operand operator.

	* fold-const.c (make_range): Do not access operand 1 for a
	zero-operand operator.

2003-07-08  Mark Mitchell  <mark@codesourcery.com>

	* cp-tree.def (NON_DEPENDENT_EXPR): New node.
	* cp-tree.h (build_call_from_tree): Remove.
	(build_member_call): Likewise.
	(dependent_template_arg_p): Remove.
	(any_dependent_template_arguments_p): New function.
	(dependent_template_id_p): Likewise.
	(any_type_dependent_arguments_p): Likewise.
	(build_non_dependent_expr): Likewise.
	(build_non_dependent_args): Likewise.
	(build_x_compound_expr): Adjust prototype.
	* call.c (build_new_method_call): Handle non-dependent expressions
	correctly.
	* decl2.c (grok_array_decl): Likewise.
	(build_offset_ref_call_from_tree): Likewise.
	(build_call_from_tree): Remove.
	* error.c (dump_decl): Handle NON_DEPENDENT_EXPR.
	(dump_expr): Likewise.
	* init.c (build_member_call): Remove.
	* mangle.c (write_expression): Update handling for template-ids.
	* parser.c (cp_parser_primary_expression): Use
	any_dependent_template_arguments_p.  Update constant-expression
	handling.
	(cp_parser_postfix_expression): Use
	any_type_dependent_arguments_p.  Simplify call processing.
	(cp_parser_unary_expression): Simplify.
	(cp_parser_expression): Adjust for changes to
	build_x_compound_expr.
	(cp_parser_template_argument): Implement standard-conforming
	parsing of non-type template arguments.
	(cp_parser_direct_declarator): Use
	cp_parser_fold_non_dependent_expr.
	(cp_parser_fold_non_dependent_expr): New function.
	(cp_parser_next_token_ends_template_argument_p): Likewise.
	* pt.c (convert_template_argument): Do not call
	maybe_fold_nontype_arg.
	(tsubst_baselink): Likewise.
	(tsubst_copy_and_build): Share common code.  Make sizeof/alignof
	processing work correctly for non-dependent expressions.  Adjust
	handling of COMPOUND_EXPR.  Simplify call processing.
	(value_dependent_expression_p): Deal with functional casts and
	sizeof/alignof correctly.
	(type_dependent_expression_p): Handle overloaded functions.
	(any_type_dependent_arguments_p): New function.
	(any_dependent_template_arguments_p): Likewise.
	(dependent_template_p): Treat SCOPE_REFs as dependent.
	(dependent_template_id_p): Simplify.
	(build_non_dependent_expr): New function.
	(build_non_dependent_args): Likewise.
	* semantics.c (finish_stmt_expr): Don't make dependent
	statement-expresions have void type.
	(finish_call_expr): Handle non-dependent expressions
	correctly.
	* tree.c (lvalue_p_1): Treat NON_DEPENDENT_EXPRs as lvalues.
	* typeck.c (cxx_sizeof_or_alignof_type): Give the expression
	type size_t, even in templates.
	(expr_sizeof): Likewise.
	(finish_class_member_access_expr): Handle non-dependent expressions
	correctly.
	(build_x_indirect_ref): Likewise.
	(build_x_binary_op): Likewise.
	(build_x_unary_op): Likewise.
	(build_x_conditional_expr): Likewise.
	(build_x_compound_expr): Likewise.
	* typeck2.c (build_x_arrow): Likewise.

2003-07-08  Mark Mitchell  <mark@codesourcery.com>

	* g++.dg/abi/mangle17.C: Make sure template expressions are
	dependent.
	* g++.dg/abi/mangle4.C: Mark erroneous casts.
	* g++.dg/debug/debug7.C: Mark erronous new-declarator.
	* g++.dg/opt/stack1.C: Remove erroneous code.
	* g++.dg/parse/template7.C: New test.
	* g++.dg/template/dependent-expr1.C: Mark erroneous code.
	* g++.old-deja/g++.pt/crash4.C: Likewise.

2003-07-09  Mark Mitchell  <mark@codesourcery.com>

	* gcj/array.h (JvPrimClass): Don't parenthesize the output.

From-SVN: r69130
parent 844c00ed
2003-07-08 Mark Mitchell <mark@codesourcery.com>
* fold-const.c (make_range): Do not access operand 1 for a
zero-operand operator.
2003-07-09 Neil Booth <neil@daikokuya.co.uk>
* toplev.c (warn_dummy, W_options): Die.
......
2003-07-08 Mark Mitchell <mark@codesourcery.com>
* cp-tree.def (NON_DEPENDENT_EXPR): New node.
* cp-tree.h (build_call_from_tree): Remove.
(build_member_call): Likewise.
(dependent_template_arg_p): Remove.
(any_dependent_template_arguments_p): New function.
(dependent_template_id_p): Likewise.
(any_type_dependent_arguments_p): Likewise.
(build_non_dependent_expr): Likewise.
(build_non_dependent_args): Likewise.
(build_x_compound_expr): Adjust prototype.
* call.c (build_new_method_call): Handle non-dependent expressions
correctly.
* decl2.c (grok_array_decl): Likewise.
(build_offset_ref_call_from_tree): Likewise.
(build_call_from_tree): Remove.
* error.c (dump_decl): Handle NON_DEPENDENT_EXPR.
(dump_expr): Likewise.
* init.c (build_member_call): Remove.
* mangle.c (write_expression): Update handling for template-ids.
* parser.c (cp_parser_primary_expression): Use
any_dependent_template_arguments_p. Update constant-expression
handling.
(cp_parser_postfix_expression): Use
any_type_dependent_arguments_p. Simplify call processing.
(cp_parser_unary_expression): Simplify.
(cp_parser_expression): Adjust for changes to
build_x_compound_expr.
(cp_parser_template_argument): Implement standard-conforming
parsing of non-type template arguments.
(cp_parser_direct_declarator): Use
cp_parser_fold_non_dependent_expr.
(cp_parser_fold_non_dependent_expr): New function.
(cp_parser_next_token_ends_template_argument_p): Likewise.
* pt.c (convert_template_argument): Do not call
maybe_fold_nontype_arg.
(tsubst_baselink): Likewise.
(tsubst_copy_and_build): Share common code. Make sizeof/alignof
processing work correctly for non-dependent expressions. Adjust
handling of COMPOUND_EXPR. Simplify call processing.
(value_dependent_expression_p): Deal with functional casts and
sizeof/alignof correctly.
(type_dependent_expression_p): Handle overloaded functions.
(any_type_dependent_arguments_p): New function.
(any_dependent_template_arguments_p): Likewise.
(dependent_template_p): Treat SCOPE_REFs as dependent.
(dependent_template_id_p): Simplify.
(build_non_dependent_expr): New function.
(build_non_dependent_args): Likewise.
* semantics.c (finish_stmt_expr): Don't make dependent
statement-expresions have void type.
(finish_call_expr): Handle non-dependent expressions
correctly.
* tree.c (lvalue_p_1): Treat NON_DEPENDENT_EXPRs as lvalues.
* typeck.c (cxx_sizeof_or_alignof_type): Give the expression
type size_t, even in templates.
(expr_sizeof): Likewise.
(finish_class_member_access_expr): Handle non-dependent expressions
correctly.
(build_x_indirect_ref): Likewise.
(build_x_binary_op): Likewise.
(build_x_unary_op): Likewise.
(build_x_conditional_expr): Likewise.
(build_x_compound_expr): Likewise.
* typeck2.c (build_x_arrow): Likewise.
Wed Jul 9 02:28:39 CEST 2003 Jan Hubicka <jh@suse.cz>
* cp-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): New.
......@@ -210,13 +277,13 @@ Wed Jul 9 02:28:39 CEST 2003 Jan Hubicka <jh@suse.cz>
(build_conditional_expr): Likewise.
(build_new_method_call): Likewise.
* cp-tree.def (OFFSET_REF): Update documentation.
(cp_convert_to_pointer): Update handling of conversions from
* cvt.c (cp_convert_to_pointer): Update handling of conversions from
pointers to members to pointers.
(ocp_convert): Do not call resolve_offset_ref.
(convert_to_void): Likewise.
(build_expr_type_conversion): Likewise.
(delete_sanity): Likewise.
(resolve_offset_ref): Simplify greatly.
* decl2.c (delete_sanity): Likewise.
* init.c (resolve_offset_ref): Simplify greatly.
(build_vec_delete): Do not call resolve_offset_ref.
* parser.c (cp_parser_postfix_expression): Call resolve_offset_ref
if appropriate.
......
......@@ -325,8 +325,7 @@ build_call (tree function, tree parms)
BASETYPE_PATH, if non-NULL, contains a chain from the type of INSTANCE
down to the real instance type to use for access checking. We need this
information to get protected accesses correct. This parameter is used
by build_member_call.
information to get protected accesses correct.
FLAGS is the logical disjunction of zero or more LOOKUP_
flags. See cp-tree.h for more info.
......@@ -4883,6 +4882,9 @@ build_new_method_call (tree instance, tree fns, tree args,
tree class_type;
int template_only = 0;
bool any_viable_p;
tree orig_instance;
tree orig_fns;
tree orig_args;
my_friendly_assert (instance != NULL_TREE, 20020729);
......@@ -4891,6 +4893,20 @@ build_new_method_call (tree instance, tree fns, tree args,
|| args == error_mark_node)
return error_mark_node;
orig_instance = instance;
orig_fns = fns;
orig_args = args;
if (processing_template_decl)
{
instance = build_non_dependent_expr (instance);
if (!BASELINK_P (fns)
&& TREE_CODE (fns) != PSEUDO_DTOR_EXPR
&& TREE_TYPE (fns) != unknown_type_node)
fns = build_non_dependent_expr (fns);
args = build_non_dependent_args (orig_args);
}
/* Process the argument list. */
user_args = args;
args = resolve_args (args);
......@@ -5068,6 +5084,13 @@ build_new_method_call (tree instance, tree fns, tree args,
call = build (COMPOUND_EXPR, TREE_TYPE (call), instance, call);
}
if (processing_template_decl && call != error_mark_node)
return build_min (CALL_EXPR,
TREE_TYPE (call),
build_min_nt (COMPONENT_REF,
orig_instance,
orig_fns),
orig_args);
return call;
}
......
......@@ -238,6 +238,16 @@ DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", 'e', 2)
DEFTREECODE (TYPEID_EXPR, "typeid_expr", 'e', 1)
DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", 'e', 3)
/* A placeholder for an expression that is not type-dependent, but
does occur in a template. When an expression that is not
type-dependent appears in a larger expression, we must compute the
type of that larger expression. That computation would normally
modify the original expression, which would change the mangling of
that expression if it appeared in a template argument list. In
that situation, we create a NON_DEPENDENT_EXPR to take the place of
the original expression. */
DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", 'e', 0)
/* CTOR_INITIALIZER is a placeholder in template code for a call to
setup_vtbl_pointer (and appears in all functions, not just ctors). */
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 1)
......
......@@ -215,6 +215,7 @@ struct diagnostic_context;
#define abi_version_at_least(N) \
(flag_abi_version == 0 || flag_abi_version >= (N))
/* Language-dependent contents of an identifier. */
......@@ -3775,7 +3776,6 @@ extern void import_export_tinfo (tree, tree, bool);
extern void finish_file (void);
extern tree build_cleanup (tree);
extern tree build_offset_ref_call_from_tree (tree, tree);
extern tree build_call_from_tree (tree, tree, bool);
extern void set_decl_namespace (tree, tree, bool);
extern tree current_decl_namespace (void);
extern void push_decl_namespace (tree);
......@@ -3853,7 +3853,6 @@ extern int is_aggr_type (tree, int);
extern tree get_aggr_from_typedef (tree, int);
extern tree get_type_value (tree);
extern tree build_zero_init (tree, tree, bool);
extern tree build_member_call (tree, tree, tree);
extern tree build_offset_ref (tree, tree);
extern tree resolve_offset_ref (tree);
extern tree build_new (tree, tree, tree, int);
......@@ -3974,12 +3973,16 @@ extern tree current_instantiation (void);
extern tree maybe_get_template_decl_from_type_decl (tree);
extern int processing_template_parmlist;
extern bool dependent_type_p (tree);
extern bool dependent_template_arg_p (tree);
extern bool any_dependent_template_arguments_p (tree);
extern bool dependent_template_p (tree);
extern bool dependent_template_id_p (tree, tree);
extern bool type_dependent_expression_p (tree);
extern bool any_type_dependent_arguments_p (tree);
extern bool value_dependent_expression_p (tree);
extern tree resolve_typename_type (tree, bool);
extern tree template_for_substitution (tree);
extern tree build_non_dependent_expr (tree);
extern tree build_non_dependent_args (tree);
/* in repo.c */
extern void repo_template_used (tree);
......@@ -4267,7 +4270,7 @@ extern tree build_x_binary_op (enum tree_code, tree, tree);
extern tree build_x_unary_op (enum tree_code, tree);
extern tree unary_complex_lvalue (enum tree_code, tree);
extern tree build_x_conditional_expr (tree, tree, tree);
extern tree build_x_compound_expr (tree);
extern tree build_x_compound_expr (tree, tree);
extern tree build_compound_expr (tree);
extern tree build_static_cast (tree, tree);
extern tree build_reinterpret_cast (tree, tree);
......
......@@ -398,59 +398,77 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags, tree quals)
tree
grok_array_decl (tree array_expr, tree index_exp)
{
tree type = TREE_TYPE (array_expr);
tree p1, p2, i1, i2;
tree type;
tree expr;
tree orig_array_expr = array_expr;
tree orig_index_exp = index_exp;
if (type == error_mark_node || index_exp == error_mark_node)
if (error_operand_p (array_expr) || error_operand_p (index_exp))
return error_mark_node;
if (processing_template_decl)
return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE,
array_expr, index_exp);
{
if (type_dependent_expression_p (array_expr)
|| type_dependent_expression_p (index_exp))
return build_min_nt (ARRAY_REF, array_expr, index_exp);
array_expr = build_non_dependent_expr (array_expr);
index_exp = build_non_dependent_expr (index_exp);
}
type = TREE_TYPE (array_expr);
my_friendly_assert (type, 20030626);
type = non_reference (type);
/* If they have an `operator[]', use that. */
if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp)))
return build_new_op (ARRAY_REF, LOOKUP_NORMAL,
expr = build_new_op (ARRAY_REF, LOOKUP_NORMAL,
array_expr, index_exp, NULL_TREE);
/* Otherwise, create an ARRAY_REF for a pointer or array type. It
is a little-known fact that, if `a' is an array and `i' is an
int, you can write `i[a]', which means the same thing as `a[i]'. */
if (TREE_CODE (type) == ARRAY_TYPE)
p1 = array_expr;
else
p1 = build_expr_type_conversion (WANT_POINTER, array_expr, false);
{
tree p1, p2, i1, i2;
/* Otherwise, create an ARRAY_REF for a pointer or array type.
It is a little-known fact that, if `a' is an array and `i' is
an int, you can write `i[a]', which means the same thing as
`a[i]'. */
if (TREE_CODE (type) == ARRAY_TYPE)
p1 = array_expr;
else
p1 = build_expr_type_conversion (WANT_POINTER, array_expr, false);
if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE)
p2 = index_exp;
else
p2 = build_expr_type_conversion (WANT_POINTER, index_exp, false);
if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE)
p2 = index_exp;
else
p2 = build_expr_type_conversion (WANT_POINTER, index_exp, false);
i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr, false);
i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp, false);
i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr,
false);
i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp,
false);
if ((p1 && i2) && (i1 && p2))
error ("ambiguous conversion for array subscript");
if ((p1 && i2) && (i1 && p2))
error ("ambiguous conversion for array subscript");
if (p1 && i2)
array_expr = p1, index_exp = i2;
else if (i1 && p2)
array_expr = p2, index_exp = i1;
else
{
error ("invalid types `%T[%T]' for array subscript",
type, TREE_TYPE (index_exp));
return error_mark_node;
}
if (p1 && i2)
array_expr = p1, index_exp = i2;
else if (i1 && p2)
array_expr = p2, index_exp = i1;
else
{
error ("invalid types `%T[%T]' for array subscript",
type, TREE_TYPE (index_exp));
return error_mark_node;
}
if (array_expr == error_mark_node || index_exp == error_mark_node)
error ("ambiguous conversion for array subscript");
if (array_expr == error_mark_node || index_exp == error_mark_node)
error ("ambiguous conversion for array subscript");
return build_array_ref (array_expr, index_exp);
expr = build_array_ref (array_expr, index_exp);
}
if (processing_template_decl && expr != error_mark_node)
return build_min (ARRAY_REF, TREE_TYPE (expr), orig_array_expr,
orig_index_exp);
return expr;
}
/* Given the cast expression EXP, checking out its validity. Either return
......@@ -2949,8 +2967,37 @@ tree
build_offset_ref_call_from_tree (tree fn, tree args)
{
tree object_addr;
tree orig_fn;
tree orig_args;
tree expr;
orig_fn = fn;
orig_args = args;
my_friendly_assert (TREE_CODE (fn) == OFFSET_REF, 20020725);
if (processing_template_decl)
{
tree object;
tree object_type;
my_friendly_assert (TREE_CODE (fn) == DOTSTAR_EXPR
|| TREE_CODE (fn) == MEMBER_REF,
20030708);
if (type_dependent_expression_p (fn)
|| any_type_dependent_arguments_p (args))
return build_min_nt (CALL_EXPR, fn, args);
/* Transform the arguments and add the implicit "this"
parameter. That must be done before the FN is transformed
because we depend on the form of FN. */
args = build_non_dependent_args (args);
object_type = TREE_TYPE (TREE_OPERAND (fn, 0));
if (TREE_CODE (fn) == DOTSTAR_EXPR)
object_type = build_pointer_type (non_reference (object_type));
object = build (NON_DEPENDENT_EXPR, object_type);
args = tree_cons (NULL_TREE, object, args);
/* Now that the arguments are done, transform FN. */
fn = build_non_dependent_expr (fn);
}
/* A qualified name corresponding to a bound pointer-to-member is
represented as an OFFSET_REF:
......@@ -2958,79 +3005,18 @@ build_offset_ref_call_from_tree (tree fn, tree args)
struct B { void g(); };
void (B::*p)();
void B::g() { (this->*p)(); } */
if (TREE_CODE (TREE_OPERAND (fn, 1)) == FIELD_DECL)
/* This case should now be handled elsewhere. */
abort ();
else
if (TREE_CODE (fn) == OFFSET_REF)
{
object_addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (fn, 0), 0);
fn = TREE_OPERAND (fn, 1);
fn = get_member_function_from_ptrfunc (&object_addr, fn);
args = tree_cons (NULL_TREE, object_addr, args);
}
return build_function_call (fn, args);
}
/* FN indicates the function to call. Name resolution has been
performed on FN. ARGS are the arguments to the function. They
have already been semantically analyzed. DISALLOW_VIRTUAL is true
if the function call should be determined at compile time, even if
FN is virtual. */
tree
build_call_from_tree (tree fn, tree args, bool disallow_virtual)
{
tree template_args;
tree template_id;
tree f;
/* Check to see that name lookup has already been performed. */
my_friendly_assert (TREE_CODE (fn) != OFFSET_REF, 20020725);
my_friendly_assert (TREE_CODE (fn) != SCOPE_REF, 20020725);
/* In the future all of this should be eliminated. Instead,
name-lookup for a member function should simply return a
baselink, instead of a FUNCTION_DECL, TEMPLATE_DECL, or
TEMPLATE_ID_EXPR. */
if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
{
template_id = fn;
template_args = TREE_OPERAND (fn, 1);
fn = TREE_OPERAND (fn, 0);
}
else
{
template_id = NULL_TREE;
template_args = NULL_TREE;
}
f = (TREE_CODE (fn) == OVERLOAD) ? get_first_fn (fn) : fn;
/* Make sure we have a baselink (rather than simply a
FUNCTION_DECL) for a member function. */
if (current_class_type
&& ((TREE_CODE (f) == FUNCTION_DECL
&& DECL_FUNCTION_MEMBER_P (f))
|| (DECL_FUNCTION_TEMPLATE_P (f)
&& DECL_FUNCTION_MEMBER_P (f))))
{
f = lookup_member (current_class_type, DECL_NAME (f),
/*protect=*/1, /*want_type=*/false);
if (f)
fn = f;
}
if (template_id)
{
if (BASELINK_P (fn))
BASELINK_FUNCTIONS (fn) = build_nt (TEMPLATE_ID_EXPR,
BASELINK_FUNCTIONS (fn),
template_args);
else
fn = template_id;
}
return finish_call_expr (fn, args, disallow_virtual);
expr = build_function_call (fn, args);
if (processing_template_decl && expr != error_mark_node)
return build_min (CALL_EXPR, TREE_TYPE (expr), orig_fn, orig_args);
return expr;
}
/* Returns true if ROOT (a namespace, class, or function) encloses
......
......@@ -988,6 +988,10 @@ dump_decl (tree t, int flags)
dump_decl (BASELINK_FUNCTIONS (t), flags);
break;
case NON_DEPENDENT_EXPR:
dump_expr (t, flags);
break;
default:
sorry_for_unsupported_tree (t);
/* Fallthrough to error. */
......@@ -2028,7 +2032,11 @@ dump_expr (tree t, int flags)
dump_expr (get_first_fn (t), flags & ~TFF_EXPR_IN_PARENS);
break;
/* else fall through */
case NON_DEPENDENT_EXPR:
output_add_string (scratch_buffer, "<expression of type ");
dump_type (TREE_TYPE (t), flags);
output_add_character (scratch_buffer, '>');
break;
/* This list is incomplete, but should suffice for now.
It is very important that `sorry' does not call
......
......@@ -1337,157 +1337,6 @@ get_type_value (tree name)
return NULL_TREE;
}
/* This code could just as well go in `class.c', but is placed here for
modularity. */
/* For an expression of the form TYPE :: NAME (PARMLIST), build
the appropriate function call. */
tree
build_member_call (tree type, tree name, tree parmlist)
{
tree t;
tree method_name;
tree fns;
int dtor = 0;
tree basetype_path, decl;
if (TREE_CODE (name) == TEMPLATE_ID_EXPR
&& TREE_CODE (type) == NAMESPACE_DECL)
{
/* 'name' already refers to the decls from the namespace, since we
hit do_identifier for template_ids. */
method_name = TREE_OPERAND (name, 0);
/* FIXME: Since we don't do independent names right yet, the
name might also be a LOOKUP_EXPR. Once we resolve this to a
real decl earlier, this can go. This may happen during
tsubst'ing. */
if (TREE_CODE (method_name) == LOOKUP_EXPR)
{
method_name = lookup_namespace_name
(type, TREE_OPERAND (method_name, 0));
TREE_OPERAND (name, 0) = method_name;
}
my_friendly_assert (is_overloaded_fn (method_name), 980519);
return finish_call_expr (name, parmlist, /*disallow_virtual=*/true);
}
if (DECL_P (name))
name = DECL_NAME (name);
if (TREE_CODE (type) == NAMESPACE_DECL)
return finish_call_expr (lookup_namespace_name (type, name),
parmlist,
/*disallow_virtual=*/true);
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
{
method_name = TREE_OPERAND (name, 0);
if (TREE_CODE (method_name) == COMPONENT_REF)
method_name = TREE_OPERAND (method_name, 1);
if (is_overloaded_fn (method_name))
method_name = DECL_NAME (OVL_CURRENT (method_name));
TREE_OPERAND (name, 0) = method_name;
}
else
method_name = name;
if (TREE_CODE (method_name) == BIT_NOT_EXPR)
{
method_name = TREE_OPERAND (method_name, 0);
dtor = 1;
}
/* This shouldn't be here, and build_member_call shouldn't appear in
parse.y! (mrs) */
if (type && TREE_CODE (type) == IDENTIFIER_NODE
&& get_aggr_from_typedef (type, 0) == 0)
{
tree ns = lookup_name (type, 0);
if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
return finish_call_expr (lookup_namespace_name (ns, name),
parmlist,
/*disallow_virtual=*/true);
}
if (type == NULL_TREE || ! is_aggr_type (type, 1))
return error_mark_node;
/* An operator we did not like. */
if (name == NULL_TREE)
return error_mark_node;
if (dtor)
{
error ("cannot call destructor `%T::~%T' without object", type,
method_name);
return error_mark_node;
}
decl = maybe_dummy_object (type, &basetype_path);
fns = lookup_fnfields (basetype_path, method_name, 0);
if (fns)
{
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
BASELINK_FUNCTIONS (fns) = build_nt (TEMPLATE_ID_EXPR,
BASELINK_FUNCTIONS (fns),
TREE_OPERAND (name, 1));
return build_new_method_call (decl, fns, parmlist,
/*conversion_path=*/NULL_TREE,
LOOKUP_NORMAL|LOOKUP_NONVIRTUAL);
}
/* Convert 'this' to the specified type to disambiguate conversion
to the function's context. */
if (decl == current_class_ref
/* ??? this is wrong, but if this conversion is invalid we need to
defer it until we know whether we are calling a static or
non-static member function. Be conservative for now. */
&& ACCESSIBLY_UNIQUELY_DERIVED_P (type, current_class_type))
{
basetype_path = NULL_TREE;
decl = build_scoped_ref (decl, type, &basetype_path);
if (decl == error_mark_node)
return error_mark_node;
}
if (constructor_name_p (method_name, type))
return build_functional_cast (type, parmlist);
if (TREE_CODE (name) == IDENTIFIER_NODE
&& ((t = lookup_field (TYPE_BINFO (type), name, 1, false))))
{
if (t == error_mark_node)
return error_mark_node;
if (TREE_CODE (t) == FIELD_DECL)
{
if (is_dummy_object (decl))
{
error ("invalid use of non-static field `%D'", t);
return error_mark_node;
}
decl = build (COMPONENT_REF, TREE_TYPE (t), decl, t);
}
else if (TREE_CODE (t) == VAR_DECL)
decl = t;
else
{
error ("invalid use of member `%D'", t);
return error_mark_node;
}
if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl)))
return build_new_op (CALL_EXPR, LOOKUP_NORMAL, decl,
parmlist, NULL_TREE);
return build_function_call (decl, parmlist);
}
else
{
error ("no method `%T::%D'", type, name);
return error_mark_node;
}
}
/* Build a reference to a member of an aggregate. This is not a
C++ `&', but really something which can have its address taken,
and then act as a pointer to member, for example TYPE :: FIELD
......
......@@ -2019,6 +2019,19 @@ write_expression (tree expr)
write_type (TREE_OPERAND (expr, 0));
if (TREE_CODE (TREE_OPERAND (expr, 1)) == IDENTIFIER_NODE)
write_source_name (TREE_OPERAND (expr, 1));
else if (TREE_CODE (TREE_OPERAND (expr, 1)) == TEMPLATE_ID_EXPR)
{
tree template_id;
tree name;
template_id = TREE_OPERAND (expr, 1);
name = TREE_OPERAND (template_id, 0);
/* FIXME: What about operators? */
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE,
20030707);
write_source_name (TREE_OPERAND (template_id, 0));
write_template_args (TREE_OPERAND (template_id, 1));
}
else
{
/* G++ 3.2 incorrectly put out both the "sr" code and
......
......@@ -1449,8 +1449,12 @@ finish_stmt_expr (tree rtl_expr)
tree result;
/* If the last thing in the statement-expression was not an
expression-statement, then it has type `void'. */
if (!last_expr_type)
expression-statement, then it has type `void'. In a template, we
cannot distinguish the case where the last expression-statement
had a dependent type from the case where the last statement was
not an expression-statement. Therefore, we (incorrectly) treat
the STMT_EXPR as dependent in that case. */
if (!last_expr_type && !processing_template_decl)
last_expr_type = void_type_node;
result = build_min (STMT_EXPR, last_expr_type, last_tree);
TREE_SIDE_EFFECTS (result) = 1;
......@@ -1482,16 +1486,32 @@ finish_stmt_expr (tree rtl_expr)
tree
finish_call_expr (tree fn, tree args, bool disallow_virtual)
{
tree result;
tree orig_fn;
tree orig_args;
if (fn == error_mark_node || args == error_mark_node)
return error_mark_node;
if (processing_template_decl)
return build_nt (CALL_EXPR, fn, args, NULL_TREE);
/* ARGS should be a list of arguments. */
my_friendly_assert (!args || TREE_CODE (args) == TREE_LIST,
20020712);
orig_fn = fn;
orig_args = args;
if (processing_template_decl)
{
if (type_dependent_expression_p (fn)
|| any_type_dependent_arguments_p (args))
return build_nt (CALL_EXPR, fn, args);
if (!BASELINK_P (fn)
&& TREE_CODE (fn) != PSEUDO_DTOR_EXPR
&& TREE_TYPE (fn) != unknown_type_node)
fn = build_non_dependent_expr (fn);
args = build_non_dependent_args (orig_args);
}
/* A reference to a member function will appear as an overloaded
function (rather than a BASELINK) if an unqualified name was used
to refer to it. */
......@@ -1512,6 +1532,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
}
}
result = NULL_TREE;
if (BASELINK_P (fn))
{
tree object;
......@@ -1551,17 +1572,22 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
object = build_dummy_object (DECL_CONTEXT (representative_fn));
}
return build_new_method_call (object, fn, args, NULL_TREE,
(disallow_virtual
? LOOKUP_NONVIRTUAL : 0));
if (processing_template_decl)
{
if (type_dependent_expression_p (object))
return build_nt (CALL_EXPR, orig_fn, orig_args);
object = build_non_dependent_expr (object);
}
result = build_new_method_call (object, fn, args, NULL_TREE,
(disallow_virtual
? LOOKUP_NONVIRTUAL : 0));
}
else if (is_overloaded_fn (fn))
/* A call to a namespace-scope function. */
return build_new_function_call (fn, args);
result = build_new_function_call (fn, args);
else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
{
tree result;
if (args)
error ("arguments to destructor are not allowed");
/* Mark the pseudo-destructor call as having side-effects so
......@@ -1570,20 +1596,18 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
void_type_node,
TREE_OPERAND (fn, 0));
TREE_SIDE_EFFECTS (result) = 1;
return result;
}
else if (CLASS_TYPE_P (TREE_TYPE (fn)))
{
/* If the "function" is really an object of class type, it might
have an overloaded `operator ()'. */
tree result;
result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE);
if (result)
return result;
}
/* If the "function" is really an object of class type, it might
have an overloaded `operator ()'. */
result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE);
if (!result)
/* A call where the function is unknown. */
result = build_function_call (fn, args);
/* A call where the function is unknown. */
return build_function_call (fn, args);
if (processing_template_decl)
return build (CALL_EXPR, TREE_TYPE (result), orig_fn, orig_args);
return result;
}
/* Finish a call to a postfix increment or decrement or EXPR. (Which
......
......@@ -174,6 +174,14 @@ lvalue_p_1 (tree ref,
return (DECL_NONSTATIC_MEMBER_FUNCTION_P (ref)
? clk_none : clk_ordinary);
case NON_DEPENDENT_EXPR:
/* We must consider NON_DEPENDENT_EXPRs to be lvalues so that
things like "&E" where "E" is an expression with a
non-dependent type work. It is safe to be lenient because an
error will be issued when the template is instantiated if "E"
is not an lvalue. */
return clk_ordinary;
default:
break;
}
......
......@@ -980,44 +980,48 @@ build_scoped_ref (tree datum, tree basetype, tree* binfo_p)
delegation is detected. */
tree
build_x_arrow (tree datum)
build_x_arrow (tree expr)
{
tree orig_expr = expr;
tree types_memoized = NULL_TREE;
register tree rval = datum;
tree type = TREE_TYPE (rval);
tree type = TREE_TYPE (expr);
tree last_rval = NULL_TREE;
if (type == error_mark_node)
return error_mark_node;
if (processing_template_decl)
return build_min_nt (ARROW_EXPR, rval);
{
if (type_dependent_expression_p (expr))
return build_min_nt (ARROW_EXPR, expr);
expr = build_non_dependent_expr (expr);
}
if (TREE_CODE (type) == REFERENCE_TYPE)
{
rval = convert_from_reference (rval);
type = TREE_TYPE (rval);
expr = convert_from_reference (expr);
type = TREE_TYPE (expr);
}
if (IS_AGGR_TYPE (type))
{
while ((rval = build_new_op (COMPONENT_REF, LOOKUP_NORMAL, rval,
while ((expr = build_new_op (COMPONENT_REF, LOOKUP_NORMAL, expr,
NULL_TREE, NULL_TREE)))
{
if (rval == error_mark_node)
if (expr == error_mark_node)
return error_mark_node;
if (value_member (TREE_TYPE (rval), types_memoized))
if (value_member (TREE_TYPE (expr), types_memoized))
{
error ("circular pointer delegation detected");
return error_mark_node;
}
else
{
types_memoized = tree_cons (NULL_TREE, TREE_TYPE (rval),
types_memoized = tree_cons (NULL_TREE, TREE_TYPE (expr),
types_memoized);
}
last_rval = rval;
last_rval = expr;
}
if (last_rval == NULL_TREE)
......@@ -1030,10 +1034,17 @@ build_x_arrow (tree datum)
last_rval = convert_from_reference (last_rval);
}
else
last_rval = decay_conversion (rval);
last_rval = decay_conversion (expr);
if (TREE_CODE (TREE_TYPE (last_rval)) == POINTER_TYPE)
return build_indirect_ref (last_rval, NULL);
{
if (processing_template_decl)
return build_min (ARROW_EXPR,
TREE_TYPE (TREE_TYPE (last_rval)),
orig_expr);
return build_indirect_ref (last_rval, NULL);
}
if (types_memoized)
error ("result of `operator->()' yields non-pointer result");
......
......@@ -2908,7 +2908,8 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
{
arg0 = TREE_OPERAND (exp, 0);
if (first_rtl_op (code) > 0)
arg0 = TREE_OPERAND (exp, 0);
if (TREE_CODE_CLASS (code) == '<'
|| TREE_CODE_CLASS (code) == '1'
|| TREE_CODE_CLASS (code) == '2')
......
2003-07-08 Mark Mitchell <mark@codesourcery.com>
* g++.dg/abi/mangle17.C: Make sure template expressions are
dependent.
* g++.dg/abi/mangle4.C: Mark erroneous casts.
* g++.dg/debug/debug7.C: Mark erronous new-declarator.
* g++.dg/opt/stack1.C: Remove erroneous code.
* g++.dg/parse/template7.C: New test.
* g++.dg/template/dependent-expr1.C: Mark erroneous code.
* g++.old-deja/g++.pt/crash4.C: Likewise.
2003-07-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* gcc.dg/const-elim-1.c (dg-final): Change regexp to match labels
......
......@@ -4,8 +4,8 @@ enum E { e = 3 };
template <int I> struct S {};
template <int I> void f (S<e + int (3.7)>) {}
template void f<7>(S<e + int (3.7)>); // { dg-warning "mangle" }
template <int I> void f (S<I + e + int (3.7)>) {}
template void f<7>(S<7 + e + int (3.7)>); // { dg-warning "mangle" }
template <int I> void g (S<e + int (3.7)>) {}
template void g<7>(S<e + int (3.7)>); // { dg-warning "mangle" }
template <int I> void g (S<I + e + int (3.7)>) {}
template void g<7>(S<7 + e + int (3.7)>); // { dg-warning "mangle" }
......@@ -8,19 +8,17 @@ template<const A* a> class C {};
template<const B* b> class D {};
template<B* b> class E {};
template<const B* b> void f(D<b> &, C<static_cast<const A*>(b)> &) {}
template<const B* b> void g(D<b> &, E<const_cast<B*>(b)> &) {}
template<const B* b> void f(D<b> &, C<static_cast<const A*>(b)> &) {} // { dg-error "" }
template<const B* b> void g(D<b> &, E<const_cast<B*>(b)> &) {} // { dg-error "" }
B b;
int main()
{
C<static_cast<const A*>(&b)> c;
C<static_cast<const A*>(&b)> c; // { dg-error "" }
D<&b> d;
E<const_cast<B*>(&b)> e;
f(d, c);
g(d, e);
E<const_cast<B*>(&b)> e; // { dg-error "" }
f(d, c); // { dg-error "" }
g(d, e); // { dg-error "" }
}
// { dg-final { scan-assembler "\n_?_Z1fIXadL_Z1bEEEvR1DIXT_EER1CIXcvPK1AT_EE\[: \t\n\]" } }
// { dg-final { scan-assembler "\n_?_Z1gIXadL_Z1bEEEvR1DIXT_EER1EIXcvP1BT_EE\[: \t\n\]" } }
......@@ -7,7 +7,7 @@ main() {
int a = 4;
int b = 5;
int (*x)[b] = new int[a][b];
int (*x)[b] = new int[a][b]; // { dg-error "" }
x[2][1] = 7;
......
......@@ -68,7 +68,7 @@ template<typename=void>
struct adaptor {
adaptor (matrix<> &m) : m(&m), upper_ (1) {}
int size1 () const { return m->size1 (); }
int size1 () const;
int size2 () const { return 3; }
int lower () const { return 1; }
int upper () const { return upper_; }
......
template <int I>
void f();
void g() { f<(3, 2)>(); } // { dg-error "" }
......@@ -21,9 +21,9 @@ namespace std
Foo (__alignof__ (x));
Foo (x->~I ());
// Foo (typeid (I));
Foo (delete x);
Foo (delete[] x);
Foo (throw x);
Foo (delete x); // { dg-error "" }
Foo (delete[] x); // { dg-error "" }
Foo (throw x); // { dg-error "" }
}
}
// { dg-do assemble }
// { dg-do compile }
// Origin: Mark Mitchell <mark@codesourcery.com>
template <int> struct S1{};
......@@ -7,5 +7,5 @@ struct S2 { int i; };
template <class T>
void f(S2 s2) {
S1<s2.i> s1;
S1<s2.i> s1; // { dg-error "" }
}
2003-07-09 Mark Mitchell <mark@codesourcery.com>
* gcj/array.h (JvPrimClass): Don't parenthesize the output.
2003-07-09 Michael Koch <konqueror@gmx.de>
* gnu/java/awt/peer/gtk/GtkComponentPeer.java,
......
......@@ -71,7 +71,9 @@ typedef JArray<jstring> *jstringArray;
extern java::lang::Class _Jv_byteClass, _Jv_shortClass, _Jv_intClass,
_Jv_longClass, _Jv_booleanClass, _Jv_charClass, _Jv_floatClass,
_Jv_doubleClass, _Jv_voidClass;
#define JvPrimClass(TYPE) (& _Jv_##TYPE##Class)
/* The definition of this macro cannot be enclosed in parentheses
because "JvPrimClass(x)" is used as a template argument. */
#define JvPrimClass(TYPE) & _Jv_##TYPE##Class
extern "C" jobjectArray _Jv_NewObjectArray(jsize length, jclass, jobject init);
extern "C" jobject _Jv_NewPrimArray (jclass eltype, jint count);
......
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