cp-tree.h (complete_type_or_diagnostic): Changed prototype, renamed from...

* 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.

From-SVN: r53605
This commit is contained in:
Alexandre Oliva 2002-05-19 05:15:12 +00:00 committed by Alexandre Oliva
parent 410b770f63
commit 23b4deba7b
5 changed files with 76 additions and 19 deletions

View File

@ -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> 2002-05-18 Jason Merrill <jason@redhat.com>
* decl2.c (import_export_decl): If we clear * decl2.c (import_export_decl): If we clear

View File

@ -4317,7 +4317,8 @@ extern tree condition_conversion PARAMS ((tree));
extern tree target_type PARAMS ((tree)); extern tree target_type PARAMS ((tree));
extern tree require_complete_type PARAMS ((tree)); extern tree require_complete_type PARAMS ((tree));
extern tree 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 int type_unknown_p PARAMS ((tree));
extern tree commonparms PARAMS ((tree, tree)); extern tree commonparms PARAMS ((tree, tree));
extern tree original_type PARAMS ((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) build_binary_op(code, arg1, arg2, 1)
/* in typeck2.c */ /* 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)); 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 error_not_base_type PARAMS ((tree, tree));
extern tree binfo_or_else PARAMS ((tree, tree)); extern tree binfo_or_else PARAMS ((tree, tree));
extern void readonly_error PARAMS ((tree, const char *, int)); extern void readonly_error PARAMS ((tree, const char *, int));

View File

@ -3112,11 +3112,18 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
if (TREE_CODE (type) == POINTER_TYPE) if (TREE_CODE (type) == POINTER_TYPE)
{ {
type = TYPE_MAIN_VARIANT (TREE_TYPE (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) if (TREE_CODE (type) == ARRAY_TYPE)
goto handle_array; 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. */ /* Call the builtin operator delete. */
return build_builtin_delete_call (addr); return build_builtin_delete_call (addr);

View File

@ -157,13 +157,15 @@ complete_type (type)
} }
/* Like complete_type, but issue an error if the TYPE cannot be /* 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. */ Returns NULL_TREE if the type cannot be made complete. */
tree tree
complete_type_or_else (type, value) complete_type_or_diagnostic (type, value, warn_only)
tree type; tree type;
tree value; tree value;
int warn_only;
{ {
type = complete_type (type); type = complete_type (type);
if (type == error_mark_node) if (type == error_mark_node)
@ -171,7 +173,7 @@ complete_type_or_else (type, value)
return NULL_TREE; return NULL_TREE;
else if (!COMPLETE_TYPE_P (type)) else if (!COMPLETE_TYPE_P (type))
{ {
cxx_incomplete_type_error (value, type); cxx_incomplete_type_diagnostic (value, type, warn_only);
return NULL_TREE; return NULL_TREE;
} }
else else

View File

@ -182,14 +182,29 @@ abstract_virtuals_error (decl, type)
/* Print an error message for invalid use of an incomplete 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) 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 void
cxx_incomplete_type_error (value, type) cxx_incomplete_type_diagnostic (value, type, warn_only)
tree value; tree value;
tree type; tree type;
int warn_only;
{ {
int decl = 0; 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. */ /* Avoid duplicate error message. */
if (TREE_CODE (type) == ERROR_MARK) if (TREE_CODE (type) == ERROR_MARK)
@ -198,7 +213,7 @@ cxx_incomplete_type_error (value, type)
if (value != 0 && (TREE_CODE (value) == VAR_DECL if (value != 0 && (TREE_CODE (value) == VAR_DECL
|| TREE_CODE (value) == PARM_DECL)) || TREE_CODE (value) == PARM_DECL))
{ {
cp_error_at ("`%D' has incomplete type", value); (*p_msg_at) ("`%D' has incomplete type", value);
decl = 1; decl = 1;
} }
retry: retry:
@ -210,12 +225,12 @@ retry:
case UNION_TYPE: case UNION_TYPE:
case ENUMERAL_TYPE: case ENUMERAL_TYPE:
if (!decl) if (!decl)
error ("invalid use of undefined type `%#T'", type); (*p_msg) ("invalid use of undefined type `%#T'", type);
cp_error_at ("forward declaration of `%#T'", type); (*p_msg_at) ("forward declaration of `%#T'", type);
break; break;
case VOID_TYPE: case VOID_TYPE:
error ("invalid use of `%T'", type); (*p_msg) ("invalid use of `%T'", type);
break; break;
case ARRAY_TYPE: case ARRAY_TYPE:
@ -224,27 +239,27 @@ retry:
type = TREE_TYPE (type); type = TREE_TYPE (type);
goto retry; goto retry;
} }
error ("invalid use of array with unspecified bounds"); (*p_msg) ("invalid use of array with unspecified bounds");
break; break;
case OFFSET_TYPE: case OFFSET_TYPE:
bad_member: bad_member:
error ("invalid use of member (did you forget the `&' ?)"); (*p_msg) ("invalid use of member (did you forget the `&' ?)");
break; break;
case TEMPLATE_TYPE_PARM: case TEMPLATE_TYPE_PARM:
error ("invalid use of template type parameter"); (*p_msg) ("invalid use of template type parameter");
break; break;
case UNKNOWN_TYPE: case UNKNOWN_TYPE:
if (value && TREE_CODE (value) == COMPONENT_REF) if (value && TREE_CODE (value) == COMPONENT_REF)
goto bad_member; goto bad_member;
else if (value && TREE_CODE (value) == ADDR_EXPR) 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) 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 else
error ("insufficient contextual information to determine type"); (*p_msg) ("insufficient contextual information to determine type");
break; break;
default: 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, /* Perform appropriate conversions on the initial value of a variable,
store it in the declaration DECL, store it in the declaration DECL,