* init.c (build_new_1, build_delete): Use it.
* typeck.c (require_complete_type): Use complete_type, rather than
expanding it inline.
(complete_type_or_else): New function.
(build_component_ref): Use it.
(pointer_int_sum): Make sure the type pointed to is complete.
(pointer_diff): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@20499
138bc75d-0d04-0410-961f-
82ee72b054a4
+1998-06-13 Mark Mitchell <mark@markmitchell.com>
+
+ * cp-tree.h (complete_type_or_else): Declare.
+ * init.c (build_new_1, build_delete): Use it.
+ * typeck.c (require_complete_type): Use complete_type, rather than
+ expanding it inline.
+ (complete_type_or_else): New function.
+ (build_component_ref): Use it.
+ (pointer_int_sum): Make sure the type pointed to is complete.
+ (pointer_diff): Likewise.
+
+ * pt.c (for_each_template_parm): Traverse the TYPE_CONTEXT for
+ types.
+
+ * search.c (get_matching_virtual): Note that member templates
+ cannot override virtual functions.
+
1998-06-12 Brendan Kehoe <brendan@cygnus.com>
* pt.c (check_explicit_specialization): If DECLARATOR turned into
extern tree truthvalue_conversion PROTO((tree));
extern tree type_for_mode PROTO((enum machine_mode, int));
extern tree type_for_size PROTO((unsigned, int));
+extern int c_get_alias_set PROTO((tree));
/* in decl{2}.c */
extern tree void_list_node;
extern tree target_type PROTO((tree));
extern tree require_complete_type PROTO((tree));
extern tree complete_type PROTO((tree));
+extern tree complete_type_or_else PROTO((tree));
extern int type_unknown_p PROTO((tree));
extern int fntype_p PROTO((tree));
extern tree require_instantiated_type PROTO((tree, tree, tree));
true_type = TREE_TYPE (true_type);
}
- if (TYPE_SIZE (complete_type (true_type)) == 0)
- {
- incomplete_type_error (0, true_type);
- return error_mark_node;
- }
+ if (!complete_type_or_else (true_type))
+ return error_mark_node;
if (has_array)
size = fold (build_binary_op (MULT_EXPR, size_in_bytes (true_type),
if (TREE_CODE (type) == POINTER_TYPE)
{
type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
- if (TYPE_SIZE (complete_type (type)) == 0)
- {
- incomplete_type_error (0, type);
- return error_mark_node;
- }
+ if (!complete_type_or_else (type))
+ return error_mark_node;
if (TREE_CODE (type) == ARRAY_TYPE)
goto handle_array;
if (! IS_AGGR_TYPE (type))
return require_complete_type (value);
}
- if (IS_AGGR_TYPE (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
+ if (TYPE_SIZE (complete_type (type)))
+ return value;
+ else
{
- instantiate_class_template (TYPE_MAIN_VARIANT (type));
- if (TYPE_SIZE (type) != 0)
- return value;
+ incomplete_type_error (value, type);
+ return error_mark_node;
}
-
- incomplete_type_error (value, type);
- return error_mark_node;
}
+/* 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
+ horribly wrong, in which case the error_mark_node is returned. */
+
tree
complete_type (type)
tree type;
return type;
}
+/* Like complete_type, but issue an error if the TYPE cannot be
+ completed. Returns NULL_TREE if the type cannot be made
+ complete. */
+
+tree
+complete_type_or_else (type)
+ tree type;
+{
+ type = complete_type (type);
+ if (type != error_mark_node && !TYPE_SIZE (type))
+ {
+ incomplete_type_error (NULL_TREE, type);
+ return NULL_TREE;
+ }
+ else
+ return type;
+}
+
/* Return truthvalue of whether type of EXP is instantiated. */
int
return error_mark_node;
}
- if (TYPE_SIZE (complete_type (basetype)) == 0)
- {
- incomplete_type_error (0, basetype);
- return error_mark_node;
- }
+ if (!complete_type_or_else (basetype))
+ return error_mark_node;
if (TREE_CODE (component) == BIT_NOT_EXPR)
{
register tree result_type = TREE_TYPE (ptrop);
+ if (!complete_type_or_else (result_type))
+ return error_mark_node;
+
if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
{
if (pedantic || warn_pointer_arith)
tree restype = ptrdiff_type_node;
tree target_type = TREE_TYPE (ptrtype);
+ if (!complete_type_or_else (target_type))
+ return error_mark_node;
+
if (pedantic || warn_pointer_arith)
{
if (TREE_CODE (target_type) == VOID_TYPE)
--- /dev/null
+// Build don't link:
+
+template <class T>
+struct S1
+{
+};
+
+template <class T>
+struct S2
+{
+ typedef T* pointer_t;
+};
+
+int f(S2<S1<int> >::pointer_t p1, S2<S1<int> >::pointer_t p2)
+{
+ return (int) (p1 - p2);
+}