diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 7 | ||||
-rw-r--r-- | gcc/cp/init.c | 13 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 8 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 50 |
5 files changed, 76 insertions, 19 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 16bbf15..56f7663 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,20 @@ +2002-05-19 Alexandre Oliva <aoliva@redhat.com> + + * cp-tree.h (complete_type_or_diagnostic): Changed prototype, + renamed from... + (complete_type_or_else): ... this. Redefined as macro. + (cxx_incomplete_type_diagnostic): Declare. + (cxx_incomplete_type_error): Define as macro. + * init.c (build_delete): Warn about incomplete types other than + void, and use the built-in operator delete for them. + * typeck.c (complete_type_or_diagnostic): Renamed from + complete_type_or_else. Added warn_only argument, passed to... + * typeck2.c (cxx_incomplete_type_diagnostic): ... this. Print + warnings or errors depending on new warn_only argument. Renamed + from... + (cxx_incomplete_type_error): ... this. New implementation in + terms of cxx_incomplete_type_diagnostic. + 2002-05-18 Jason Merrill <jason@redhat.com> * decl2.c (import_export_decl): If we clear diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a1d4ddb..0276309 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4317,7 +4317,8 @@ extern tree condition_conversion PARAMS ((tree)); extern tree target_type PARAMS ((tree)); extern tree require_complete_type PARAMS ((tree)); extern tree complete_type PARAMS ((tree)); -extern tree complete_type_or_else PARAMS ((tree, tree)); +extern tree complete_type_or_diagnostic PARAMS ((tree, tree, int)); +#define complete_type_or_else(T,V) (complete_type_or_diagnostic ((T), (V), 0)) extern int type_unknown_p PARAMS ((tree)); extern tree commonparms PARAMS ((tree, tree)); extern tree original_type PARAMS ((tree)); @@ -4376,7 +4377,11 @@ extern tree check_return_expr PARAMS ((tree)); build_binary_op(code, arg1, arg2, 1) /* in typeck2.c */ +extern void cxx_incomplete_type_diagnostic PARAMS ((tree, tree, int)); +#undef cxx_incomplete_type_error extern void cxx_incomplete_type_error PARAMS ((tree, tree)); +#define cxx_incomplete_type_error(V,T) \ + (cxx_incomplete_type_diagnostic ((V), (T), 0)) extern tree error_not_base_type PARAMS ((tree, tree)); extern tree binfo_or_else PARAMS ((tree, tree)); extern void readonly_error PARAMS ((tree, const char *, int)); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 9827307..3ac91da 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3112,11 +3112,18 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) if (TREE_CODE (type) == POINTER_TYPE) { type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); - if (!VOID_TYPE_P (type) && !complete_type_or_else (type, addr)) - return error_mark_node; if (TREE_CODE (type) == ARRAY_TYPE) goto handle_array; - if (! IS_AGGR_TYPE (type)) + + if (VOID_TYPE_P (type) + /* We don't want to warn about delete of void*, only other + incomplete types. Deleting other incomplete types + invokes undefined behavior, but it is not ill-formed, so + compile to something that would even do The Right Thing + (TM) should the type have a trivial dtor and no delete + operator. */ + || !complete_type_or_diagnostic (type, addr, 1) + || !IS_AGGR_TYPE (type)) { /* Call the builtin operator delete. */ return build_builtin_delete_call (addr); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 3b92a64..5ea8bdb 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -157,13 +157,15 @@ complete_type (type) } /* Like complete_type, but issue an error if the TYPE cannot be - completed. VALUE is used for informative diagnostics. + completed. VALUE is used for informative diagnostics. WARN_ONLY + will cause a warning message to be printed, instead of an error. Returns NULL_TREE if the type cannot be made complete. */ tree -complete_type_or_else (type, value) +complete_type_or_diagnostic (type, value, warn_only) tree type; tree value; + int warn_only; { type = complete_type (type); if (type == error_mark_node) @@ -171,7 +173,7 @@ complete_type_or_else (type, value) return NULL_TREE; else if (!COMPLETE_TYPE_P (type)) { - cxx_incomplete_type_error (value, type); + cxx_incomplete_type_diagnostic (value, type, warn_only); return NULL_TREE; } else diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index b837503..e034d50 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -182,14 +182,29 @@ abstract_virtuals_error (decl, type) /* Print an error message for invalid use of an incomplete type. VALUE is the expression that was used (or 0 if that isn't known) - and TYPE is the type that was invalid. */ + and TYPE is the type that was invalid. If WARN_ONLY is nonzero, a + warning is printed, otherwise an error is printed. */ void -cxx_incomplete_type_error (value, type) +cxx_incomplete_type_diagnostic (value, type, warn_only) tree value; tree type; + int warn_only; { int decl = 0; + void (*p_msg) PARAMS ((const char *, ...)); + void (*p_msg_at) PARAMS ((const char *, ...)); + + if (warn_only) + { + p_msg = warning; + p_msg_at = cp_warning_at; + } + else + { + p_msg = error; + p_msg_at = cp_error_at; + } /* Avoid duplicate error message. */ if (TREE_CODE (type) == ERROR_MARK) @@ -198,7 +213,7 @@ cxx_incomplete_type_error (value, type) if (value != 0 && (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL)) { - cp_error_at ("`%D' has incomplete type", value); + (*p_msg_at) ("`%D' has incomplete type", value); decl = 1; } retry: @@ -210,12 +225,12 @@ retry: case UNION_TYPE: case ENUMERAL_TYPE: if (!decl) - error ("invalid use of undefined type `%#T'", type); - cp_error_at ("forward declaration of `%#T'", type); + (*p_msg) ("invalid use of undefined type `%#T'", type); + (*p_msg_at) ("forward declaration of `%#T'", type); break; case VOID_TYPE: - error ("invalid use of `%T'", type); + (*p_msg) ("invalid use of `%T'", type); break; case ARRAY_TYPE: @@ -224,27 +239,27 @@ retry: type = TREE_TYPE (type); goto retry; } - error ("invalid use of array with unspecified bounds"); + (*p_msg) ("invalid use of array with unspecified bounds"); break; case OFFSET_TYPE: bad_member: - error ("invalid use of member (did you forget the `&' ?)"); + (*p_msg) ("invalid use of member (did you forget the `&' ?)"); break; case TEMPLATE_TYPE_PARM: - error ("invalid use of template type parameter"); + (*p_msg) ("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) - error ("address of overloaded function with no contextual type information"); + (*p_msg) ("address of overloaded function with no contextual type information"); else if (value && TREE_CODE (value) == OVERLOAD) - error ("overloaded function with no contextual type information"); + (*p_msg) ("overloaded function with no contextual type information"); else - error ("insufficient contextual information to determine type"); + (*p_msg) ("insufficient contextual information to determine type"); break; default: @@ -252,6 +267,17 @@ retry: } } +/* Backward-compatibility interface to incomplete_type_diagnostic; + required by ../tree.c. */ +#undef cxx_incomplete_type_error +void +cxx_incomplete_type_error (value, type) + tree value; + tree type; +{ + cxx_incomplete_type_diagnostic (value, type, 0); +} + /* Perform appropriate conversions on the initial value of a variable, store it in the declaration DECL, |