aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog17
-rw-r--r--gcc/cp/cp-tree.h7
-rw-r--r--gcc/cp/init.c13
-rw-r--r--gcc/cp/typeck.c8
-rw-r--r--gcc/cp/typeck2.c50
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,