typeck.c (complete_type_or_else): Add VALUE arg, for helpful diagnostics.
* typeck.c (complete_type_or_else): Add VALUE arg, for helpful diagnostics. cp-tree.h (complete_type_or_else): Added VALUE parameter. * init.c (build_new_1): Extra arg to complete_type_or_else. (build_delete): Likewise. * typeck.c (require_complete_type): Likewise. (pointer_int_sum): Likewise. (pointer_diff): Likewise. (build_component_ref): Likewise. * typeck2.c (incomplete_type_error): Always use cp_error. Show declaration of undefined type, if appropriate. Deal with UNKNOWN_TYPE nodes. * typeck.c (require_complete_type): Use TYPE_SIZE as size_zero_node to mean incomplete type. (require_complete_type_in_void): New function. (build_compound_expr): Call complete_type_in_void for LHS. (build_c_cast): Call complete_type_in_void for void cast. * cvt.c (ocp_convert): Call complete_type_in_void for void cast. * decl.c (cplus_expand_expr_stmt): Void expression checks moved to require_complete_type_in_void. Call it. * cp-tree.h (require_complete_type_in_void): Prototype new function. * typeck.c (convert_arguments): Use alternative format for function decls. Don't require_complete_type here. Simplify diagnostic printing. (convert_for_initialization): Don't require_complete_type on RHS yet. * call.c (convert_arg_to_ellipsis): Call require_complete_type. * call.c (build_over_call): Cope with qualified void return type. * semantics.c (finish_call_expr): Likewise * typeck.c (build_function_call_real): Likewise (c_expand_return): Likewise * decl2.c (reparse_absdcl_as_expr): Cope with qualified void type. * call.c (print_z_candidates): Use alternate print format, to be consistant with (pt.c) print_candidates. method.c (hack_identifier): List candidate members. search.c (lookup_field): Build ambiguous list, and show it, if ambiguous. From-SVN: r25474
This commit is contained in:
parent
99f25d8ea8
commit
6654316990
13 changed files with 277 additions and 113 deletions
|
@ -1,3 +1,46 @@
|
|||
1999-02-26 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* typeck.c (complete_type_or_else): Add VALUE arg, for helpful
|
||||
diagnostics.
|
||||
cp-tree.h (complete_type_or_else): Added VALUE parameter.
|
||||
* init.c (build_new_1): Extra arg to complete_type_or_else.
|
||||
(build_delete): Likewise.
|
||||
* typeck.c (require_complete_type): Likewise.
|
||||
(pointer_int_sum): Likewise.
|
||||
(pointer_diff): Likewise.
|
||||
(build_component_ref): Likewise.
|
||||
|
||||
* typeck2.c (incomplete_type_error): Always use cp_error.
|
||||
Show declaration of undefined type, if appropriate.
|
||||
Deal with UNKNOWN_TYPE nodes.
|
||||
|
||||
* typeck.c (require_complete_type): Use TYPE_SIZE as
|
||||
size_zero_node to mean incomplete type.
|
||||
(require_complete_type_in_void): New function.
|
||||
(build_compound_expr): Call complete_type_in_void for LHS.
|
||||
(build_c_cast): Call complete_type_in_void for void cast.
|
||||
* cvt.c (ocp_convert): Call complete_type_in_void for void cast.
|
||||
* decl.c (cplus_expand_expr_stmt): Void expression checks moved to
|
||||
require_complete_type_in_void. Call it.
|
||||
* cp-tree.h (require_complete_type_in_void): Prototype new function.
|
||||
|
||||
* typeck.c (convert_arguments): Use alternative format for function
|
||||
decls. Don't require_complete_type here. Simplify diagnostic printing.
|
||||
(convert_for_initialization): Don't require_complete_type on RHS yet.
|
||||
* call.c (convert_arg_to_ellipsis): Call require_complete_type.
|
||||
|
||||
* call.c (build_over_call): Cope with qualified void return type.
|
||||
* semantics.c (finish_call_expr): Likewise
|
||||
* typeck.c (build_function_call_real): Likewise
|
||||
(c_expand_return): Likewise
|
||||
* decl2.c (reparse_absdcl_as_expr): Cope with qualified void type.
|
||||
|
||||
* call.c (print_z_candidates): Use alternate print format, to be
|
||||
consistant with (pt.c) print_candidates.
|
||||
method.c (hack_identifier): List candidate members.
|
||||
search.c (lookup_field): Build ambiguous list, and show it, if
|
||||
ambiguous.
|
||||
|
||||
1999-02-26 Mark Mitchell <mark@markmitchell.com>
|
||||
|
||||
* typeck.c (decay_conversion): Don't confuse constant array
|
||||
|
|
|
@ -2078,7 +2078,7 @@ print_z_candidates (candidates)
|
|||
else if (TYPE_P (candidates->fn))
|
||||
cp_error ("%s %T <conversion>", str, candidates->fn);
|
||||
else
|
||||
cp_error_at ("%s %+D%s", str, candidates->fn,
|
||||
cp_error_at ("%s %+#D%s", str, candidates->fn,
|
||||
candidates->viable == -1 ? " <near match>" : "");
|
||||
str = " ";
|
||||
}
|
||||
|
@ -3175,6 +3175,8 @@ convert_arg_to_ellipsis (arg)
|
|||
/* Convert `short' and `char' to full-size `int'. */
|
||||
arg = default_conversion (arg);
|
||||
|
||||
arg = require_complete_type (arg);
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
|
@ -3515,7 +3517,7 @@ build_over_call (cand, args, flags)
|
|||
}
|
||||
|
||||
fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args);
|
||||
if (TREE_TYPE (fn) == void_type_node)
|
||||
if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE)
|
||||
return fn;
|
||||
fn = require_complete_type (fn);
|
||||
if (IS_AGGR_TYPE (TREE_TYPE (fn)))
|
||||
|
|
|
@ -4888,8 +4888,6 @@ push_nested_class (type, modify)
|
|||
{
|
||||
tree context;
|
||||
|
||||
my_friendly_assert (!type || TREE_CODE (type) != NAMESPACE_DECL, 980711);
|
||||
|
||||
/* A namespace might be passed in error cases, like A::B:C. */
|
||||
if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type)
|
||||
|| TREE_CODE (type) == NAMESPACE_DECL
|
||||
|
|
|
@ -3324,8 +3324,9 @@ extern int string_conv_p PROTO((tree, tree, int));
|
|||
extern tree condition_conversion PROTO((tree));
|
||||
extern tree target_type PROTO((tree));
|
||||
extern tree require_complete_type PROTO((tree));
|
||||
extern tree require_complete_type_in_void PROTO((tree));
|
||||
extern tree complete_type PROTO((tree));
|
||||
extern tree complete_type_or_else PROTO((tree));
|
||||
extern tree complete_type_or_else PROTO((tree, tree));
|
||||
extern int type_unknown_p PROTO((tree));
|
||||
extern int fntype_p PROTO((tree));
|
||||
extern tree commonparms PROTO((tree, tree));
|
||||
|
|
|
@ -687,10 +687,11 @@ ocp_convert (type, expr, convtype, flags)
|
|||
|
||||
if (code == VOID_TYPE && (convtype & CONV_STATIC))
|
||||
{
|
||||
if (type_unknown_p (e))
|
||||
error ("address of overloaded function with no contextual type information");
|
||||
e = require_complete_type_in_void (e);
|
||||
if (e != error_mark_node)
|
||||
e = build1 (CONVERT_EXPR, void_type_node, e);
|
||||
|
||||
return build1 (CONVERT_EXPR, type, e);
|
||||
return e;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -14380,38 +14380,30 @@ cplus_expand_expr_stmt (exp)
|
|||
/* Arrange for all temps to disappear. */
|
||||
expand_start_target_temps ();
|
||||
|
||||
if (TREE_TYPE (exp) == unknown_type_node)
|
||||
exp = require_complete_type_in_void (exp);
|
||||
|
||||
if (TREE_CODE (exp) == FUNCTION_DECL)
|
||||
{
|
||||
if (TREE_CODE (exp) == COMPONENT_REF)
|
||||
error ("invalid reference to a member function name, did you forget the ()?");
|
||||
else
|
||||
error ("address of overloaded function with no contextual type information");
|
||||
cp_warning ("reference, not call, to function `%D'", exp);
|
||||
warning ("at this point in file");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TREE_CODE (exp) == FUNCTION_DECL)
|
||||
{
|
||||
cp_warning ("reference, not call, to function `%D'", exp);
|
||||
warning ("at this point in file");
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* We should do this eventually, but right now this causes regex.o from
|
||||
libg++ to miscompile, and tString to core dump. */
|
||||
exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
|
||||
/* We should do this eventually, but right now this causes regex.o from
|
||||
libg++ to miscompile, and tString to core dump. */
|
||||
exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp);
|
||||
#endif
|
||||
|
||||
/* Strip unused implicit INDIRECT_REFs of references. */
|
||||
if (TREE_CODE (exp) == INDIRECT_REF
|
||||
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE)
|
||||
exp = TREE_OPERAND (exp, 0);
|
||||
/* Strip unused implicit INDIRECT_REFs of references. */
|
||||
if (TREE_CODE (exp) == INDIRECT_REF
|
||||
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE)
|
||||
exp = TREE_OPERAND (exp, 0);
|
||||
|
||||
/* If we don't do this, we end up down inside expand_expr
|
||||
trying to do TYPE_MODE on the ERROR_MARK, and really
|
||||
go outside the bounds of the type. */
|
||||
if (exp != error_mark_node)
|
||||
expand_expr_stmt (break_out_cleanups (exp));
|
||||
}
|
||||
/* If we don't do this, we end up down inside expand_expr
|
||||
trying to do TYPE_MODE on the ERROR_MARK, and really
|
||||
go outside the bounds of the type. */
|
||||
if (exp != error_mark_node)
|
||||
expand_expr_stmt (break_out_cleanups (exp));
|
||||
|
||||
/* Clean up any pending cleanups. This happens when a function call
|
||||
returns a cleanup-needing value that nobody uses. */
|
||||
|
|
|
@ -3506,7 +3506,9 @@ reparse_absdcl_as_expr (type, decl)
|
|||
|
||||
decl = build_x_function_call (decl, NULL_TREE, current_class_ref);
|
||||
|
||||
if (TREE_CODE (decl) == CALL_EXPR && TREE_TYPE (decl) != void_type_node)
|
||||
if (TREE_CODE (decl) == CALL_EXPR
|
||||
&& (! TREE_TYPE (decl)
|
||||
|| TREE_CODE (TREE_TYPE (decl)) != VOID_TYPE))
|
||||
decl = require_complete_type (decl);
|
||||
|
||||
return decl;
|
||||
|
|
|
@ -2163,7 +2163,7 @@ build_new_1 (exp)
|
|||
true_type = TREE_TYPE (true_type);
|
||||
}
|
||||
|
||||
if (!complete_type_or_else (true_type))
|
||||
if (!complete_type_or_else (true_type, exp))
|
||||
return error_mark_node;
|
||||
|
||||
if (has_array)
|
||||
|
@ -3014,7 +3014,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
|
|||
if (TREE_CODE (type) == POINTER_TYPE)
|
||||
{
|
||||
type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
|
||||
if (!complete_type_or_else (type))
|
||||
if (type != void_type_node && !complete_type_or_else (type, addr))
|
||||
return error_mark_node;
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
goto handle_array;
|
||||
|
|
|
@ -2023,6 +2023,7 @@ hack_identifier (value, name)
|
|||
{
|
||||
error ("request for member `%s' is ambiguous in multiple inheritance lattice",
|
||||
IDENTIFIER_POINTER (name));
|
||||
print_candidates (value);
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
|
|
|
@ -870,6 +870,7 @@ lookup_field (xbasetype, name, protect, want_type)
|
|||
tree entry, binfo, binfo_h;
|
||||
tree own_access = access_default_node;
|
||||
int vbase_name_p = VBASE_NAME_P (name);
|
||||
tree ambiguous = NULL_TREE;
|
||||
|
||||
/* rval_binfo is the binfo associated with the found member, note,
|
||||
this can be set with useful information, even when rval is not
|
||||
|
@ -986,6 +987,7 @@ lookup_field (xbasetype, name, protect, want_type)
|
|||
tree binfos = BINFO_BASETYPES (binfo);
|
||||
int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
|
||||
tree nval;
|
||||
int idx = -1;
|
||||
|
||||
/* Process and/or queue base types. */
|
||||
for (i = 0; i < n_baselinks; i++)
|
||||
|
@ -1040,7 +1042,7 @@ lookup_field (xbasetype, name, protect, want_type)
|
|||
|
||||
nval = lookup_field_1 (type, name);
|
||||
|
||||
if (nval || lookup_fnfields_here (type, name)>=0)
|
||||
if (nval || (idx = lookup_fnfields_here (type, name)) >= 0)
|
||||
{
|
||||
if (nval && nval == rval && SHARED_MEMBER_P (nval))
|
||||
{
|
||||
|
@ -1074,10 +1076,20 @@ lookup_field (xbasetype, name, protect, want_type)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* This is ambiguous. */
|
||||
errstr = "request for member `%D' is ambiguous";
|
||||
protect += 2;
|
||||
break;
|
||||
/* This is ambiguous. Remember it. */
|
||||
if (! ambiguous)
|
||||
{
|
||||
errstr = "request for member `%D' is ambiguous";
|
||||
protect += 2;
|
||||
if (rval)
|
||||
ambiguous = scratch_tree_cons (NULL_TREE, rval, ambiguous);
|
||||
}
|
||||
if (! nval)
|
||||
{
|
||||
nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
|
||||
nval = OVL_CURRENT (nval);
|
||||
}
|
||||
ambiguous = scratch_tree_cons (NULL_TREE, nval, ambiguous);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1176,6 +1188,8 @@ lookup_field (xbasetype, name, protect, want_type)
|
|||
if (errstr && protect)
|
||||
{
|
||||
cp_error (errstr, name, type);
|
||||
if (ambiguous)
|
||||
print_candidates (ambiguous);
|
||||
rval = error_mark_node;
|
||||
}
|
||||
|
||||
|
|
|
@ -855,7 +855,8 @@ finish_call_expr (fn, args, koenig)
|
|||
result = build_x_function_call (fn, args, current_class_ref);
|
||||
|
||||
if (TREE_CODE (result) == CALL_EXPR
|
||||
&& TREE_TYPE (result) != void_type_node)
|
||||
&& (! TREE_TYPE (result)
|
||||
|| TREE_CODE (TREE_TYPE (result)) != VOID_TYPE))
|
||||
result = require_complete_type (result);
|
||||
|
||||
return result;
|
||||
|
|
156
gcc/cp/typeck.c
156
gcc/cp/typeck.c
|
@ -90,7 +90,7 @@ require_complete_type (value)
|
|||
{
|
||||
tree type;
|
||||
|
||||
if (processing_template_decl)
|
||||
if (processing_template_decl || value == error_mark_node)
|
||||
return value;
|
||||
|
||||
if (TREE_CODE (value) == OVERLOAD)
|
||||
|
@ -100,7 +100,7 @@ require_complete_type (value)
|
|||
|
||||
/* First, detect a valid value with a complete type. */
|
||||
if (TYPE_SIZE (type) != 0
|
||||
&& type != void_type_node
|
||||
&& TYPE_SIZE (type) != size_zero_node
|
||||
&& ! (TYPE_LANG_SPECIFIC (type)
|
||||
&& (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))
|
||||
&& TYPE_SIZE (SIGNATURE_TYPE (type)) == 0))
|
||||
|
@ -122,12 +122,105 @@ require_complete_type (value)
|
|||
return require_complete_type (value);
|
||||
}
|
||||
|
||||
if (complete_type_or_else (type))
|
||||
if (complete_type_or_else (type, value))
|
||||
return value;
|
||||
else
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Makes sure EXPR is a complete type when used in a void context, like a
|
||||
whole expression, or lhs of a comma operator. Issue a diagnostic and
|
||||
return error_mark_node on failure. This is a little tricky, because some
|
||||
valid void types look stunningly similar to invalid void types. We err on
|
||||
the side of caution */
|
||||
|
||||
tree
|
||||
require_complete_type_in_void (expr)
|
||||
tree expr;
|
||||
{
|
||||
switch (TREE_CODE (expr))
|
||||
{
|
||||
case COND_EXPR:
|
||||
{
|
||||
tree op;
|
||||
|
||||
op = TREE_OPERAND (expr,2);
|
||||
op = require_complete_type_in_void (op);
|
||||
TREE_OPERAND (expr,2) = op;
|
||||
if (op == error_mark_node)
|
||||
{
|
||||
expr = op;
|
||||
break;
|
||||
}
|
||||
|
||||
/* fallthrough */
|
||||
}
|
||||
|
||||
case COMPOUND_EXPR:
|
||||
{
|
||||
tree op;
|
||||
|
||||
op = TREE_OPERAND (expr,1);
|
||||
op = require_complete_type_in_void (op);
|
||||
TREE_OPERAND (expr,1) = op;
|
||||
if (op == error_mark_node)
|
||||
{
|
||||
expr = op;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case NON_LVALUE_EXPR:
|
||||
case NOP_EXPR:
|
||||
{
|
||||
tree op;
|
||||
|
||||
op = TREE_OPERAND (expr,0);
|
||||
op = require_complete_type_in_void (op);
|
||||
TREE_OPERAND (expr,0) = op;
|
||||
if (op == error_mark_node)
|
||||
{
|
||||
expr = op;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CALL_EXPR: /* function call return can be ignored */
|
||||
case RTL_EXPR: /* RTL nodes have no value */
|
||||
case DELETE_EXPR: /* delete expressions have no type */
|
||||
case VEC_DELETE_EXPR:
|
||||
case INTEGER_CST: /* used for null pointer */
|
||||
case EXIT_EXPR: /* have no return */
|
||||
case LOOP_EXPR: /* have no return */
|
||||
case BIND_EXPR: /* have no return */
|
||||
case THROW_EXPR: /* have no return */
|
||||
case MODIFY_EXPR: /* sometimes this has a void type, but that's ok */
|
||||
case CONVERT_EXPR: /* sometimes has a void type */
|
||||
break;
|
||||
|
||||
case INDIRECT_REF:
|
||||
{
|
||||
tree op = TREE_OPERAND (expr,0);
|
||||
|
||||
/* Calling a function returning a reference has an implicit
|
||||
dereference applied. We don't want to make that an error. */
|
||||
if (TREE_CODE (op) == CALL_EXPR
|
||||
&& TREE_CODE (TREE_TYPE (op)) == REFERENCE_TYPE)
|
||||
break;
|
||||
/* else fallthrough */
|
||||
}
|
||||
|
||||
default:
|
||||
expr = require_complete_type (expr);
|
||||
break;
|
||||
}
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
/* Try to complete TYPE, if it is incomplete. For example, if TYPE is
|
||||
a template instantiation, do the instantiation. Returns TYPE,
|
||||
whether or not it could be completed, unless something goes
|
||||
|
@ -161,20 +254,21 @@ complete_type (type)
|
|||
}
|
||||
|
||||
/* Like complete_type, but issue an error if the TYPE cannot be
|
||||
completed. Returns NULL_TREE if the type cannot be made
|
||||
complete. */
|
||||
completed. VALUE is used for informative diagnostics.
|
||||
Returns NULL_TREE if the type cannot be made complete. */
|
||||
|
||||
tree
|
||||
complete_type_or_else (type)
|
||||
complete_type_or_else (type, value)
|
||||
tree type;
|
||||
tree value;
|
||||
{
|
||||
type = complete_type (type);
|
||||
if (type == error_mark_node)
|
||||
/* We already issued an error. */
|
||||
return NULL_TREE;
|
||||
else if (!TYPE_SIZE (type))
|
||||
else if (!TYPE_SIZE (type) || TYPE_SIZE (type) == size_zero_node)
|
||||
{
|
||||
incomplete_type_error (NULL_TREE, type);
|
||||
incomplete_type_error (value, type);
|
||||
return NULL_TREE;
|
||||
}
|
||||
else
|
||||
|
@ -1997,7 +2091,7 @@ build_component_ref (datum, component, basetype_path, protect)
|
|||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (!complete_type_or_else (basetype))
|
||||
if (!complete_type_or_else (basetype, datum))
|
||||
return error_mark_node;
|
||||
|
||||
if (TREE_CODE (component) == BIT_NOT_EXPR)
|
||||
|
@ -2928,7 +3022,7 @@ build_function_call_real (function, params, require_complete, flags)
|
|||
|
||||
if (require_complete)
|
||||
{
|
||||
if (value_type == void_type_node)
|
||||
if (TREE_CODE (value_type) == VOID_TYPE)
|
||||
return result;
|
||||
result = require_complete_type (result);
|
||||
}
|
||||
|
@ -3003,7 +3097,7 @@ convert_arguments (typelist, values, fndecl, flags)
|
|||
{
|
||||
if (fndecl)
|
||||
{
|
||||
cp_error_at ("too many arguments to %s `%+D'", called_thing,
|
||||
cp_error_at ("too many arguments to %s `%+#D'", called_thing,
|
||||
fndecl);
|
||||
error ("at this point in file");
|
||||
}
|
||||
|
@ -3032,8 +3126,6 @@ convert_arguments (typelist, values, fndecl, flags)
|
|||
|| TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE)
|
||||
val = default_conversion (val);
|
||||
|
||||
val = require_complete_type (val);
|
||||
}
|
||||
|
||||
if (val == error_mark_node)
|
||||
|
@ -3108,9 +3200,8 @@ convert_arguments (typelist, values, fndecl, flags)
|
|||
{
|
||||
if (fndecl)
|
||||
{
|
||||
char *buf = (char *)alloca (32 + strlen (called_thing));
|
||||
sprintf (buf, "too few arguments to %s `%%#D'", called_thing);
|
||||
cp_error_at (buf, fndecl);
|
||||
cp_error_at ("too few arguments to %s `%+#D'",
|
||||
called_thing, fndecl);
|
||||
error ("at this point in file");
|
||||
}
|
||||
else
|
||||
|
@ -3990,7 +4081,7 @@ pointer_int_sum (resultcode, ptrop, intop)
|
|||
|
||||
register tree result_type = TREE_TYPE (ptrop);
|
||||
|
||||
if (!complete_type_or_else (result_type))
|
||||
if (!complete_type_or_else (result_type, ptrop))
|
||||
return error_mark_node;
|
||||
|
||||
if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
|
||||
|
@ -4082,7 +4173,7 @@ pointer_diff (op0, op1, ptrtype)
|
|||
tree restype = ptrdiff_type_node;
|
||||
tree target_type = TREE_TYPE (ptrtype);
|
||||
|
||||
if (!complete_type_or_else (target_type))
|
||||
if (!complete_type_or_else (target_type, NULL_TREE))
|
||||
return error_mark_node;
|
||||
|
||||
if (pedantic || warn_pointer_arith)
|
||||
|
@ -5272,6 +5363,7 @@ build_compound_expr (list)
|
|||
tree list;
|
||||
{
|
||||
register tree rest;
|
||||
tree first;
|
||||
|
||||
if (TREE_READONLY_DECL_P (TREE_VALUE (list)))
|
||||
TREE_VALUE (list) = decl_constant_value (TREE_VALUE (list));
|
||||
|
@ -5291,14 +5383,21 @@ build_compound_expr (list)
|
|||
return TREE_VALUE (list);
|
||||
}
|
||||
|
||||
first = TREE_VALUE (list);
|
||||
first = require_complete_type_in_void (first);
|
||||
if (first == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
rest = build_compound_expr (TREE_CHAIN (list));
|
||||
if (rest == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
/* When pedantic, a compound expression cannot be a constant expression. */
|
||||
if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)) && ! pedantic)
|
||||
if (! TREE_SIDE_EFFECTS (first) && ! pedantic)
|
||||
return rest;
|
||||
|
||||
return build (COMPOUND_EXPR, TREE_TYPE (rest),
|
||||
break_out_cleanups (TREE_VALUE (list)), rest);
|
||||
break_out_cleanups (first), rest);
|
||||
}
|
||||
|
||||
tree
|
||||
|
@ -5670,7 +5769,13 @@ build_c_cast (type, expr)
|
|||
warning ("cast to pointer from integer of different size");
|
||||
#endif
|
||||
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
if (TREE_CODE (type) == VOID_TYPE)
|
||||
{
|
||||
value = require_complete_type_in_void (value);
|
||||
if (value != error_mark_node)
|
||||
value = build1 (CONVERT_EXPR, void_type_node, value);
|
||||
}
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
value = (convert_from_reference
|
||||
(convert_to_reference (type, value, CONV_C_CAST,
|
||||
LOOKUP_COMPLAIN, NULL_TREE)));
|
||||
|
@ -6954,11 +7059,8 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
|
|||
return rhs;
|
||||
}
|
||||
|
||||
rhs = require_complete_type (rhs);
|
||||
if (rhs == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (exp != 0) exp = require_complete_type (exp);
|
||||
if (exp != 0)
|
||||
exp = require_complete_type (exp);
|
||||
if (exp == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
@ -7158,7 +7260,7 @@ c_expand_return (retval)
|
|||
if (retval == result
|
||||
|| DECL_CONSTRUCTOR_P (current_function_decl))
|
||||
/* It's already done for us. */;
|
||||
else if (TREE_TYPE (retval) == void_type_node)
|
||||
else if (TREE_CODE (TREE_TYPE (retval)) == VOID_TYPE)
|
||||
{
|
||||
pedwarn ("return of void value in function returning non-void");
|
||||
expand_expr_stmt (retval);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Report error messages, build initializers, and perform
|
||||
some front-end optimizations for C++ compiler.
|
||||
Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
|
||||
Hacked by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
@ -213,55 +213,62 @@ incomplete_type_error (value, type)
|
|||
tree value;
|
||||
tree type;
|
||||
{
|
||||
char *errmsg = 0;
|
||||
|
||||
/* Avoid duplicate error message. */
|
||||
if (TREE_CODE (type) == ERROR_MARK)
|
||||
return;
|
||||
|
||||
retry:
|
||||
/* We must print an error message. Be clever about what it says. */
|
||||
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case RECORD_TYPE:
|
||||
case UNION_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
cp_error ("invalid use of undefined type `%#T'", type);
|
||||
cp_error_at ("forward declaration of `%#T'", type);
|
||||
break;
|
||||
|
||||
case VOID_TYPE:
|
||||
cp_error ("invalid use of void expression");
|
||||
break;
|
||||
|
||||
case ARRAY_TYPE:
|
||||
if (TYPE_DOMAIN (type))
|
||||
{
|
||||
type = TREE_TYPE (type);
|
||||
goto retry;
|
||||
}
|
||||
cp_error ("invalid use of array with unspecified bounds");
|
||||
break;
|
||||
|
||||
case OFFSET_TYPE:
|
||||
bad_member:
|
||||
cp_error ("invalid use of member (did you forget the `&' ?)");
|
||||
break;
|
||||
|
||||
case TEMPLATE_TYPE_PARM:
|
||||
cp_error ("invalid use of template type parameter");
|
||||
break;
|
||||
|
||||
case UNKNOWN_TYPE:
|
||||
if (value && TREE_CODE (value) == COMPONENT_REF)
|
||||
goto bad_member;
|
||||
else if (value && TREE_CODE (value) == ADDR_EXPR)
|
||||
cp_error ("address of overloaded function with no contextual type information");
|
||||
else if (value && TREE_CODE (value) == OVERLOAD)
|
||||
cp_error ("overloaded function with no contextual type information");
|
||||
else
|
||||
cp_error ("insufficient contextual information to determine type");
|
||||
break;
|
||||
|
||||
default:
|
||||
my_friendly_abort (108);
|
||||
}
|
||||
|
||||
if (value != 0 && (TREE_CODE (value) == VAR_DECL
|
||||
|| TREE_CODE (value) == PARM_DECL))
|
||||
cp_error ("`%D' has incomplete type", value);
|
||||
else
|
||||
{
|
||||
retry:
|
||||
/* We must print an error message. Be clever about what it says. */
|
||||
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case RECORD_TYPE:
|
||||
case UNION_TYPE:
|
||||
case ENUMERAL_TYPE:
|
||||
errmsg = "invalid use of undefined type `%#T'";
|
||||
break;
|
||||
|
||||
case VOID_TYPE:
|
||||
error ("invalid use of void expression");
|
||||
return;
|
||||
|
||||
case ARRAY_TYPE:
|
||||
if (TYPE_DOMAIN (type))
|
||||
{
|
||||
type = TREE_TYPE (type);
|
||||
goto retry;
|
||||
}
|
||||
error ("invalid use of array with unspecified bounds");
|
||||
return;
|
||||
|
||||
case OFFSET_TYPE:
|
||||
error ("invalid use of member type (did you forget the `&' ?)");
|
||||
return;
|
||||
|
||||
case TEMPLATE_TYPE_PARM:
|
||||
error ("invalid use of template type parameter");
|
||||
return;
|
||||
|
||||
default:
|
||||
my_friendly_abort (108);
|
||||
}
|
||||
|
||||
cp_error (errmsg, type);
|
||||
}
|
||||
cp_error_at ("incomplete `%D' defined here", value);
|
||||
}
|
||||
|
||||
/* Like error(), but don't call report_error_function(). */
|
||||
|
|
Loading…
Add table
Reference in a new issue