#include "flags.h"
#include "toplev.h"
#include "output.h"
+#include "diagnostic.h"
static tree process_init_constructor PARAMS ((tree, tree, tree *));
int line;
const char *func;
{
- if (where > 0)
- error ("Internal error #%d.", where);
+ if (errorcount > 0 || sorrycount > 0)
+ /* Say nothing. */;
+ else if (where > 0)
+ {
+ error ("Internal error #%d.", where);
- /* Uncount this error, so finish_abort will do the right thing. */
- --errorcount;
+ /* Uncount this error, so internal_error will do the right thing. */
+ --errorcount;
+ }
fancy_abort (file, line, func);
}
&& TREE_VALUE (init) == error_mark_node))
return error_mark_node;
+ if (TREE_CODE (init) == ERROR_MARK)
+ /* __PRETTY_FUNCTION__'s initializer is a bogus expression inside
+ a template function. This gets substituted during instantiation. */
+ return init;
+
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
if (TREE_CODE (init) == NON_LVALUE_EXPR)
init = TREE_OPERAND (init, 0);
if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
|| code == ENUMERAL_TYPE || code == REFERENCE_TYPE
- || code == BOOLEAN_TYPE || code == COMPLEX_TYPE
+ || code == BOOLEAN_TYPE || code == COMPLEX_TYPE || code == VECTOR_TYPE
|| TYPE_PTRMEMFUNC_P (type))
{
if (raw_constructor)
if (code == ARRAY_TYPE || IS_AGGR_TYPE_CODE (code))
{
- if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type))
+ if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type)
+ && TREE_HAS_CONSTRUCTOR (init))
{
cp_error ("subobject of type `%T' must be initialized by constructor, not by `%E'",
type, init);
next1 = build_functional_cast (TREE_TYPE (field),
NULL_TREE);
else
- next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE,
- NULL_TREE);
+ {
+ next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE,
+ NULL_TREE);
+ if (init)
+ TREE_HAS_CONSTRUCTOR (next1)
+ = TREE_HAS_CONSTRUCTOR (init);
+ }
next1 = digest_init (TREE_TYPE (field), next1, 0);
/* Warn when some struct elements are implicitly initialized. */
- if (extra_warnings)
+ if (extra_warnings
+ && (!init || TREE_HAS_CONSTRUCTOR (init)))
cp_warning ("missing initializer for member `%D'", field);
}
else
/* Warn when some struct elements are implicitly initialized
to zero. */
- if (extra_warnings)
+ if (extra_warnings
+ && (!init || TREE_HAS_CONSTRUCTOR (init)))
cp_warning ("missing initializer for member `%D'", field);
/* The default zero-initialization is fine for us; don't
the A part of the C object named by X. In this case,
DATUM would be x, and BASETYPE would be A.
- Note that this is nonconformant; the standard specifies that first
- we look up ii in A, then convert x to an L& and pull out the ii part.
- But narrowing seems to be standard practice, so let's do it anyway. */
+ I used to think that this was nonconformant, that the standard specified
+ that first we look up ii in A, then convert x to an L& and pull out the
+ ii part. But in fact, it does say that we convert x to an A&; A here
+ is known as the "naming class". (jason 2000-12-19) */
tree
build_scoped_ref (datum, basetype)
tree basetype;
{
tree ref;
- tree type = TREE_TYPE (datum);
if (datum == error_mark_node)
return error_mark_node;
- /* Don't do this if it would cause an error or if we're being pedantic. */
- if (! ACCESSIBLY_UNIQUELY_DERIVED_P (basetype, type)
- || pedantic)
- return datum;
-
ref = build_unary_op (ADDR_EXPR, datum, 0);
ref = convert_pointer_to (basetype, ref);
last_rval = default_conversion (rval);
if (TREE_CODE (TREE_TYPE (last_rval)) == POINTER_TYPE)
- return build_indirect_ref (last_rval, NULL_PTR);
+ return build_indirect_ref (last_rval, NULL);
if (types_memoized)
error ("result of `operator->()' yields non-pointer result");
return build_min_nt (DOTSTAR_EXPR, datum, component);
datum = decay_conversion (datum);
+
+ if (datum == error_mark_node || component == error_mark_node)
+ return error_mark_node;
+
objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (component)));
field_type = type;
}
- else
+ else if (TYPE_PTRMEM_P (TREE_TYPE (component)))
{
type = TREE_TYPE (TREE_TYPE (component));
field_type = TREE_TYPE (type);
}
-
- if (datum == error_mark_node || component == error_mark_node)
- return error_mark_node;
-
- if (TREE_CODE (type) != OFFSET_TYPE && TREE_CODE (type) != METHOD_TYPE)
+ else
{
- cp_error ("`%E' cannot be used as a member pointer, since it is of type `%T'", component, type);
+ cp_error ("`%E' cannot be used as a member pointer, since it is of type `%T'",
+ component, TREE_TYPE (component));
return error_mark_node;
}
ok = is_ptr;
else if (TREE_CODE (core) == TEMPLATE_TYPE_PARM)
ok = 1;
+ else if (processing_template_decl)
+ ok = 1;
else
ok = COMPLETE_TYPE_P (complete_type (core));
-
+
if (ok)
{
tree probe;
incomplete_type_error (NULL_TREE, core);
return list;
}
+
+/* Combine the two exceptions specifier lists LIST and ADD, and return
+ their union. */
+
+tree
+merge_exception_specifiers (list, add)
+ tree list, add;
+{
+ if (!list || !add)
+ return NULL_TREE;
+ else if (!TREE_VALUE (list))
+ return add;
+ else if (!TREE_VALUE (add))
+ return list;
+ else
+ {
+ tree orig_list = list;
+
+ for (; add; add = TREE_CHAIN (add))
+ {
+ tree spec = TREE_VALUE (add);
+ tree probe;
+
+ for (probe = orig_list; probe; probe = TREE_CHAIN (probe))
+ if (same_type_p (TREE_VALUE (probe), spec))
+ break;
+ if (!probe)
+ {
+ spec = build_tree_list (NULL_TREE, spec);
+ TREE_CHAIN (spec) = list;
+ list = spec;
+ }
+ }
+ }
+ return list;
+}