diff options
author | Nathan Sidwell <nathan@acm.org> | 1999-02-26 23:37:04 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 1999-02-26 18:37:04 -0500 |
commit | 665431699036e1b9bd2317d452579a6fc6af9482 (patch) | |
tree | 95146880bbae3e437264ebcc433d39108ea8419e /gcc | |
parent | 99f25d8ea84021f7c7887a65085342760abd0c5a (diff) | |
download | gcc-665431699036e1b9bd2317d452579a6fc6af9482.zip gcc-665431699036e1b9bd2317d452579a6fc6af9482.tar.gz gcc-665431699036e1b9bd2317d452579a6fc6af9482.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 43 | ||||
-rw-r--r-- | gcc/cp/call.c | 6 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 7 | ||||
-rw-r--r-- | gcc/cp/decl.c | 42 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 4 | ||||
-rw-r--r-- | gcc/cp/init.c | 4 | ||||
-rw-r--r-- | gcc/cp/method.c | 1 | ||||
-rw-r--r-- | gcc/cp/search.c | 24 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 3 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 156 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 85 |
13 files changed, 272 insertions, 108 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 34e8ef8..8e82f27 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 1e43233..9bf5035 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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))) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 3fc9cf4..c533e3e 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 62ffbf0..59a067e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index b73020f..9f29c65 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -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 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c18eab7..231a598 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index cc38dab..d53dc70 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 847222f..ea424b6 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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; diff --git a/gcc/cp/method.c b/gcc/cp/method.c index f3530dd..8546332 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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; } diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 6c046ed..3b88c40 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -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; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index fd6f3d0..076197a 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 9a99097..463fcd4 100644 --- a/gcc/cp/typeck.c +++ b/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); diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index dc9695e..f002bc0 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -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; - 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; +retry: + /* We must print an error message. Be clever about what it says. */ - case VOID_TYPE: - error ("invalid use of void expression"); - return; + 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 ARRAY_TYPE: - if (TYPE_DOMAIN (type)) - { - type = TREE_TYPE (type); - goto retry; - } - error ("invalid use of array with unspecified bounds"); - return; + case VOID_TYPE: + cp_error ("invalid use of void expression"); + break; - case OFFSET_TYPE: - error ("invalid use of member type (did you forget the `&' ?)"); - return; + case ARRAY_TYPE: + if (TYPE_DOMAIN (type)) + { + type = TREE_TYPE (type); + goto retry; + } + cp_error ("invalid use of array with unspecified bounds"); + break; - case TEMPLATE_TYPE_PARM: - error ("invalid use of template type parameter"); - return; + case OFFSET_TYPE: + bad_member: + cp_error ("invalid use of member (did you forget the `&' ?)"); + break; - default: - my_friendly_abort (108); - } + case TEMPLATE_TYPE_PARM: + cp_error ("invalid use of template type parameter"); + break; - cp_error (errmsg, type); + 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_at ("incomplete `%D' defined here", value); } /* Like error(), but don't call report_error_function(). */ |