Commit a7a64a77 by Mark Mitchell Committed by Mark Mitchell

cp-tree.h (CP_INTEGRAL_TYPE_P): New macro.

	* cp-tree.h (CP_INTEGRAL_TYPE_P): New macro.
	(ARITHMETIC_TYPE_P): Adjust definition for standard conformance.
	(strip_top_quals): Declare.
	(ncp_convert): Likewise.
	(type_after_usual_arithmetic_converions): Likewise.
	(composite_pointer_type): Likewise.
	* call.c (strip_top_quals): Don't make it static.
	(promoted_arithmetic_type_p): New function.
	(conditional_conversion): Likewise.
	(null_ptr_cst_p): Allow `false' as a NULL pointer constant.
	(standard_conversion): Use same_type_p.  Don't build BASE_CONVs
	for converting a type to itself.
	(reference_binding): Honor LOOKUP_NO_TEMP_BIND.
	(implicit_conversion): Make sure the from and to types are
	complete.
	(add_builtin_candidate): Correct handling of ?: operator.
	(add_builtin_candidates): Improve documentation.
	(build_conditional_expr): New function.
	(can_convert): Implement in terms of can_convert_arg.
	(ncp_convert): New function.
	* typeck.c (type_after_usual_arithmetic_conversions): New
	function, split out from common_type.
	(composite_pointer_type): New function, split out from
	build_conditional_expr.
	(common_type): Use type_after_usual_arithmetic_conversions.
	Remove redundant attribute merging.
	(comptypes): Tidy.  Handle COMPLEX_TYPE.
	(build_binary_op_nodefault): Use null_ptr_cst_p.
	(build_conditional_expr): Remove.
	(convert_for_assignment): Use new conversion functions.

	* cp-tree.h (abstract_virtuals_error): Change declaration.
	* typeck2.c (abstract_virtuals_error): Check to see if an error
	ocurred, and return a boolean value accordingly.
	(build_functional_cast): Adjust accordingly.
	* class.c (finish_struct_1): Likewise.
	* cvt.c (ocp_convert): Likewise.
	* decl.c (cp_finish_decl): Likewise.
	(grokparams): Likewise.
	(grok_op_properties): Likewise.
	(start_function): Likewise.
	* init.c (build_new_1): Likewise.

	* pt.c (unify): Don't get confused by pointers-to-member functions.

	* search.c (build_cplus_new): Robustify.

From-SVN: r28262
parent 5cabd6f5
1999-07-26 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (CP_INTEGRAL_TYPE_P): New macro.
(ARITHMETIC_TYPE_P): Adjust definition for standard conformance.
(strip_top_quals): Declare.
(ncp_convert): Likewise.
(type_after_usual_arithmetic_converions): Likewise.
(composite_pointer_type): Likewise.
* call.c (strip_top_quals): Don't make it static.
(promoted_arithmetic_type_p): New function.
(conditional_conversion): Likewise.
(null_ptr_cst_p): Allow `false' as a NULL pointer constant.
(standard_conversion): Use same_type_p. Don't build BASE_CONVs
for converting a type to itself.
(reference_binding): Honor LOOKUP_NO_TEMP_BIND.
(implicit_conversion): Make sure the from and to types are
complete.
(add_builtin_candidate): Correct handling of ?: operator.
(add_builtin_candidates): Improve documentation.
(build_conditional_expr): New function.
(can_convert): Implement in terms of can_convert_arg.
(ncp_convert): New function.
* typeck.c (type_after_usual_arithmetic_conversions): New
function, split out from common_type.
(composite_pointer_type): New function, split out from
build_conditional_expr.
(common_type): Use type_after_usual_arithmetic_conversions.
Remove redundant attribute merging.
(comptypes): Tidy. Handle COMPLEX_TYPE.
(build_binary_op_nodefault): Use null_ptr_cst_p.
(build_conditional_expr): Remove.
(convert_for_assignment): Use new conversion functions.
* cp-tree.h (abstract_virtuals_error): Change declaration.
* typeck2.c (abstract_virtuals_error): Check to see if an error
ocurred, and return a boolean value accordingly.
(build_functional_cast): Adjust accordingly.
* class.c (finish_struct_1): Likewise.
* cvt.c (ocp_convert): Likewise.
* decl.c (cp_finish_decl): Likewise.
(grokparams): Likewise.
(grok_op_properties): Likewise.
(start_function): Likewise.
* init.c (build_new_1): Likewise.
* pt.c (unify): Don't get confused by pointers-to-member functions.
* search.c (build_cplus_new): Robustify.
1999-07-24 Richard Henderson <rth@cygnus.com>
* decl.c (ptr_type_node, va_list_type_node): New.
......
......@@ -3619,8 +3619,7 @@ finish_struct_1 (t)
{
/* Never let anything with uninheritable virtuals
make it through without complaint. */
if (CLASSTYPE_ABSTRACT_VIRTUALS (type))
abstract_virtuals_error (x, type);
abstract_virtuals_error (x, type);
/* Don't let signatures make it through either. */
if (IS_SIGNATURE (type))
......
......@@ -1660,7 +1660,24 @@ extern int flag_new_for_scope;
#define INTEGRAL_CODE_P(CODE) \
(CODE == INTEGER_TYPE || CODE == ENUMERAL_TYPE || CODE == BOOLEAN_TYPE)
#define ARITHMETIC_TYPE_P(TYPE) (INTEGRAL_TYPE_P (TYPE) || FLOAT_TYPE_P (TYPE))
/* [basic.fundamental]
Types bool, char, wchar_t, and the signed and unsigned integer types
are collectively called integral types.
Note that INTEGRAL_TYPE_P, as defined in tree.h, allows enumeration
types as well, which is incorrect in C++. */
#define CP_INTEGRAL_TYPE_P(TYPE) \
(TREE_CODE ((TYPE)) == BOOLEAN_TYPE \
|| TREE_CODE ((TYPE)) == INTEGER_TYPE)
/* [basic.fundamental]
Integral and floating types are collectively called arithmetic
types. */
#define ARITHMETIC_TYPE_P(TYPE) \
(CP_INTEGRAL_TYPE_P (TYPE) || TREE_CODE (TYPE) == REAL_TYPE)
/* Mark which labels are explicitly declared.
These may be shadowed, and may be referenced from nested functions. */
......@@ -2767,6 +2784,8 @@ extern tree convert_default_arg PROTO((tree, tree, tree));
extern tree convert_arg_to_ellipsis PROTO((tree));
extern int is_properly_derived_from PROTO((tree, tree));
extern tree initialize_reference PROTO((tree, tree));
extern tree strip_top_quals PROTO((tree));
extern tree ncp_convert PROTO((tree, tree));
/* in class.c */
extern tree build_vbase_path PROTO((enum tree_code, tree, tree, tree, int));
......@@ -3534,12 +3553,14 @@ extern tree build_ptrmemfunc1 PROTO((tree, tree, tree, tree, t
extern void expand_ptrmemfunc_cst PROTO((tree, tree *, tree *, tree *, tree *));
extern tree delta2_from_ptrmemfunc PROTO((tree));
extern tree pfn_from_ptrmemfunc PROTO((tree));
extern tree type_after_usual_arithmetic_conversions PROTO((tree, tree));
extern tree composite_pointer_type PROTO((tree, tree, tree, tree, char*));
/* in typeck2.c */
extern tree error_not_base_type PROTO((tree, tree));
extern tree binfo_or_else PROTO((tree, tree));
extern void readonly_error PROTO((tree, const char *, int));
extern void abstract_virtuals_error PROTO((tree, tree));
extern int abstract_virtuals_error PROTO((tree, tree));
extern void signature_error PROTO((tree, tree));
extern void incomplete_type_error PROTO((tree, tree));
extern void my_friendly_abort PROTO((int))
......
......@@ -826,11 +826,8 @@ ocp_convert (type, expr, convtype, flags)
ctor = e;
if (IS_AGGR_TYPE (type) && CLASSTYPE_ABSTRACT_VIRTUALS (type))
{
abstract_virtuals_error (NULL_TREE, type);
return error_mark_node;
}
if (abstract_virtuals_error (NULL_TREE, type))
return error_mark_node;
if ((flags & LOOKUP_ONLYCONVERTING)
&& ! (IS_AGGR_TYPE (dtype) && DERIVED_FROM_P (type, dtype)))
......
......@@ -7857,14 +7857,9 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
if (was_temp)
resume_temporary_allocation ();
if (type != error_mark_node
&& TYPE_LANG_SPECIFIC (core_type)
&& CLASSTYPE_ABSTRACT_VIRTUALS (core_type))
abstract_virtuals_error (decl, core_type);
else if ((TREE_CODE (type) == FUNCTION_TYPE
|| TREE_CODE (type) == METHOD_TYPE)
&& TYPE_LANG_SPECIFIC (TREE_TYPE (type))
&& CLASSTYPE_ABSTRACT_VIRTUALS (TREE_TYPE (type)))
if (!abstract_virtuals_error (decl, core_type)
&& (TREE_CODE (type) == FUNCTION_TYPE
|| TREE_CODE (type) == METHOD_TYPE))
abstract_virtuals_error (decl, TREE_TYPE (type));
if (TYPE_LANG_SPECIFIC (core_type) && IS_SIGNATURE (core_type))
......@@ -11614,13 +11609,8 @@ grokparms (first_parm, funcdef_flag)
type = build_pointer_type (type);
TREE_TYPE (decl) = type;
}
else if (TREE_CODE (type) == RECORD_TYPE
&& TYPE_LANG_SPECIFIC (type)
&& CLASSTYPE_ABSTRACT_VIRTUALS (type))
{
abstract_virtuals_error (decl, type);
any_error = 1; /* Seems like a good idea. */
}
else if (abstract_virtuals_error (decl, type))
any_error = 1; /* Seems like a good idea. */
else if (TREE_CODE (type) == RECORD_TYPE
&& TYPE_LANG_SPECIFIC (type)
&& IS_SIGNATURE (type))
......@@ -12033,9 +12023,7 @@ grok_op_properties (decl, virtualp, friendp)
else if (name == ansi_opname[(int) COND_EXPR])
{
/* 13.4.0.3 */
pedwarn ("ANSI C++ prohibits overloading operator ?:");
if (list_length (argtypes) != 4)
cp_error ("`%D' must take exactly three arguments", decl);
cp_error ("ANSI C++ prohibits overloading operator ?:");
}
else if (ambi_op_p (name))
{
......@@ -13113,9 +13101,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
= CP_TYPE_VOLATILE_P (TREE_TYPE (fntype));
}
if (TYPE_LANG_SPECIFIC (TREE_TYPE (fntype))
&& CLASSTYPE_ABSTRACT_VIRTUALS (TREE_TYPE (fntype)))
abstract_virtuals_error (decl1, TREE_TYPE (fntype));
abstract_virtuals_error (decl1, TREE_TYPE (fntype));
}
/* Effective C++ rule 15. See also c_expand_return. */
......
......@@ -2206,12 +2206,8 @@ build_new_1 (exp)
return error_mark_node;
}
if (TYPE_LANG_SPECIFIC (true_type)
&& CLASSTYPE_ABSTRACT_VIRTUALS (true_type))
{
abstract_virtuals_error (NULL_TREE, true_type);
return error_mark_node;
}
if (abstract_virtuals_error (NULL_TREE, true_type))
return error_mark_node;
if (TYPE_LANG_SPECIFIC (true_type) && IS_SIGNATURE (true_type))
{
......
......@@ -8338,10 +8338,6 @@ unify (tparms, targs, parm, arg, strict)
{
int sub_strict;
if (TREE_CODE (arg) == RECORD_TYPE && TYPE_PTRMEMFUNC_FLAG (arg))
return (unify (tparms, targs, parm,
TYPE_PTRMEMFUNC_FN_TYPE (arg), strict));
if (TREE_CODE (arg) != POINTER_TYPE)
return 1;
......@@ -8361,14 +8357,13 @@ unify (tparms, targs, parm, arg, strict)
this is probably OK. */
sub_strict = strict;
if (TREE_CODE (TREE_TYPE (arg)) != RECORD_TYPE
|| TYPE_PTRMEMFUNC_FLAG (TREE_TYPE (arg)))
if (TREE_CODE (TREE_TYPE (arg)) != RECORD_TYPE)
/* The derived-to-base conversion only persists through one
level of pointers. */
sub_strict &= ~UNIFY_ALLOW_DERIVED;
return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE
(arg), sub_strict);
return unify (tparms, targs, TREE_TYPE (parm),
TREE_TYPE (arg), sub_strict);
}
case REFERENCE_TYPE:
......@@ -8448,13 +8443,20 @@ unify (tparms, targs, parm, arg, strict)
case RECORD_TYPE:
case UNION_TYPE:
if (TYPE_PTRMEMFUNC_FLAG (parm))
return unify (tparms, targs, TYPE_PTRMEMFUNC_FN_TYPE (parm),
arg, strict);
if (TREE_CODE (arg) != TREE_CODE (parm))
return 1;
if (TYPE_PTRMEMFUNC_P (parm))
{
if (!TYPE_PTRMEMFUNC_P (arg))
return 1;
return unify (tparms, targs,
TYPE_PTRMEMFUNC_FN_TYPE (parm),
TYPE_PTRMEMFUNC_FN_TYPE (arg),
strict);
}
if (CLASSTYPE_TEMPLATE_INFO (parm))
{
tree t = NULL_TREE;
......
......@@ -3130,6 +3130,10 @@ add_conversions (binfo, data)
tree method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
tree *conversions = (tree *) data;
/* Some builtin types have no method vector, not even an empty one. */
if (!method_vec)
return NULL_TREE;
for (i = 2; i < TREE_VEC_LENGTH (method_vec); ++i)
{
tree tmp = TREE_VEC_ELT (method_vec, i);
......
......@@ -125,21 +125,27 @@ readonly_error (arg, string, soft)
(*fn) ("%s of read-only location", string);
}
/* Print an error message for invalid use of a type which declares
virtual functions which are not inheritable. */
/* If TYPE has abstract virtual functions, issue an error about trying
to create an object of that type. DECL is the object declared, or
NULL_TREE if the declaration is unavailable. Returns 1 if an error
occurred; zero if all was well. */
void
int
abstract_virtuals_error (decl, type)
tree decl;
tree type;
{
tree u = CLASSTYPE_ABSTRACT_VIRTUALS (type);
tree u;
tree tu;
if (!CLASS_TYPE_P (type) || !CLASSTYPE_ABSTRACT_VIRTUALS (type))
return 0;
u = CLASSTYPE_ABSTRACT_VIRTUALS (type);
if (decl)
{
if (TREE_CODE (decl) == RESULT_DECL)
return;
return 0;
if (TREE_CODE (decl) == VAR_DECL)
cp_error ("cannot declare variable `%D' to be of type `%T'",
......@@ -170,6 +176,8 @@ abstract_virtuals_error (decl, type)
}
else
cp_error (" since type `%T' has abstract virtual functions", type);
return 1;
}
/* Print an error message for invalid use of a signature type.
......@@ -1486,11 +1494,8 @@ build_functional_cast (exp, parms)
cp_error ("type `%T' is not yet defined", type);
return error_mark_node;
}
if (IS_AGGR_TYPE (type) && CLASSTYPE_ABSTRACT_VIRTUALS (type))
{
abstract_virtuals_error (NULL_TREE, type);
return error_mark_node;
}
if (abstract_virtuals_error (NULL_TREE, type))
return error_mark_node;
if (parms && TREE_CHAIN (parms) == NULL_TREE)
return build_c_cast (type, TREE_VALUE (parms));
......
......@@ -1168,8 +1168,8 @@ class dict : public object {
DISPLAYER displayer, STRINGER str_f)
{// ERROR - candidate for bad call
if (799 >= 800 ) cout << "Creating new dictionary..." << '\n'; ;
if (cmp == __null ) cmp = &default_compare;
if (displayer == __null ) displayer = &default_displayer;
if (cmp == __null ) cmp = (COMPARE) &default_compare;
if (displayer == __null ) displayer = (DISPLAYER) &default_displayer;
if (str_f == __null ) str_f = &default_stringer;
compare_f = cmp;
display_f = displayer;
......@@ -1417,7 +1417,7 @@ class queue : public object {
DISPLAYER displayer, STRINGER str_f)
{// ERROR - candidate for bad call
if (799 >= 800 ) cout << "Creating new queue..." << '\n'; ;
if (displayer == __null ) displayer = &default_displayer;
if (displayer == __null ) displayer = (DISPLAYER) &default_displayer;
if (str_f == __null ) str_f = &default_stringer;
display_f = displayer;
destroy_f = destroyer;
......
......@@ -2,8 +2,9 @@
// Bug: g++ misinterprets typedefs of function type in class scope.
// Build don't link:
typedef int (*F1) ();
struct A {
typedef int F();
F *fp;
void* g() { return fp; } // gets bogus error - typing
F1 g() { return fp; } // gets bogus error - typing
};
......@@ -11,11 +11,11 @@ public:
void f1b() { ok += 5; }
void f2a() { ok += 7; } // gets bogus error XFAIL *-*-*
void f2b() { }
const static void (*table[2][2])();
static void (*table[2][2])();
void main();
} a;
const void (*A::table[2][2])()
void (*A::table[2][2])()
= { { PMF2PF(&A::f1a), PMF2PF(&A::f1b) },
{ PMF2PF(&A::f2a), PMF2PF(&A::f1b) },
};
......
// Build don't run:
// Origin: Mark Mitchell <mark@codesourcery.com>
template <class T>
void f (T&) ;
template <>
void f (void (&)())
{
}
void g ()
{
}
void h ()
{
}
bool b;
int main ()
{
f (b ? g : h);
}
......@@ -5,4 +5,4 @@
// Special g++ Options:
int foo();
const int (*bar)() = foo; // ERROR - adding const - XFAIL *-*-*
const int (*bar)() = foo; // ERROR - adding const
// Build don't link:
// Origin: Jason Merrill <jason@cygnus.com>
const char *pc;
enum A { x } a;
int i;
int main()
{
return i ? *pc : a;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment