aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1994-06-24 00:54:38 +0000
committerMike Stump <mrs@gcc.gnu.org>1994-06-24 00:54:38 +0000
commita32034654e77ec19b8c0245d6dbebb06082f0612 (patch)
treea3da66c1be0dac89fa0edc6c83d4cb0b0798930c /gcc
parentf6ba0600ffc9a3035a121b50fffcf90754a342f5 (diff)
downloadgcc-a32034654e77ec19b8c0245d6dbebb06082f0612.zip
gcc-a32034654e77ec19b8c0245d6dbebb06082f0612.tar.gz
gcc-a32034654e77ec19b8c0245d6dbebb06082f0612.tar.bz2
41st Cygnus<->FSF merge
From-SVN: r7553
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog88
-rw-r--r--gcc/cp/call.c20
-rw-r--r--gcc/cp/class.c4
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/cvt.c76
-rw-r--r--gcc/cp/decl.c285
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/init.c43
-rw-r--r--gcc/cp/pt.c6
-rw-r--r--gcc/cp/tree.c6
-rw-r--r--gcc/cp/typeck.c7
-rw-r--r--gcc/cp/typeck2.c7
12 files changed, 253 insertions, 294 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index cddc168..e894e63 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,91 @@
+Thu Jun 23 00:22:28 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * decl.c (grokdeclarator): Set explicit_int for decls that just
+ specify, say, 'long'.
+
+ * init.c (do_friend): Do overload C functions (or call pushdecl,
+ anyaway).
+
+Wed Jun 22 13:40:49 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * cvt.c (build_up_reference): Don't call readonly_error.
+ (convert_to_reference): Propagate const and volatile from expr to
+ its type.
+
+ * tree.c (lvalue_p): Random CALL_EXPRs are not lvalues.
+
+ * cvt.c (build_up_reference): Break out WITH_CLEANUP_EXPR when
+ creating a temporary.
+ (convert_to_reference): Lose excessive and incorrect trickiness.
+ (cp_convert): Call build_cplus_new with with_cleanup_p set.
+
+ * typeck2.c (build_functional_cast): Ditto.
+
+Tue Jun 21 17:38:38 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * decl.c (grokdeclarator): signed, unsigned, long and short all
+ imply 'int'.
+
+ * decl.c (grokdeclarator): Allow "this is a type" syntax.
+ (grok_reference_init): Simplify and fix.
+
+Sun Jun 19 17:08:48 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * decl.c (grokdeclarator): pedwarn about a typedef that specifies no
+ type.
+
+Sat Jun 18 04:16:50 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * decl.c (start_function): Move TREE_PUBLIC and DECL_EXTERNAL
+ tinkering to after call to pushdecl.
+
+Fri Jun 17 14:48:28 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * call.c (build_method_call): Handle destructors for non-aggregate
+ types properly.
+
+Thu Jun 16 16:48:05 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * call.c (build_method_call): Make sure that the name given for the
+ destructor matches the constructor_name of the instance.
+
+ * pt.c (do_function_instantiation): A non-extern instantiation
+ overrides a later extern one.
+ (do_type_instantiation): Ditto.
+
+Wed Jun 15 19:34:54 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * init.c (expand_aggr_init): Use TYPE_MAIN_VARIANT to get the
+ unqualified array type.
+
+ * cp-tree.h (EMPTY_CONSTRUCTOR_P): Tests whether NODE is a
+ CONSTRUCTOR with no elements.
+
+ * decl.c (various): Lose empty_init_node.
+ (finish_decl): Use EMPTY_CONSTRUCTOR_P, do the empty CONSTRUCTOR
+ thing depending on the value of DECL_COMMON instead of
+ flag_conserve_space, do the empty CONSTRUCTOR thing for types that
+ don't have constructors, don't treat a real empty CONSTRUCTOR
+ specially.
+
+ * typeck2.c (process_init_constructor): Don't treat empty_init_node
+ specially.
+
+Wed Jun 15 19:05:25 1994 Mike Stump (mrs@cygnus.com)
+
+ * class.c (override_one_vtable): Don't forget to merge in an old
+ overrider when we wanted to reuse a vtable, but couldn't.
+
+Wed Jun 15 15:03:16 1994 Jason Merrill (jason@deneb.cygnus.com)
+
+ * decl.c (start_decl): Put statics in common again.
+
+ * decl.c (grokdeclarator): Return NULL_TREE for an error rather than
+ setting the type to error_mark_node.
+
+ * typeck.c (build_modify_expr): Build up a COMPOUND_EXPR for enum
+ bitfield assignments.
+
Tue Jun 14 12:23:38 1994 Jason Merrill (jason@deneb.cygnus.com)
* decl.c (grok_op_properties): Const objects can be passed by value.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 6d2b26c..75c5635 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1603,14 +1603,22 @@ build_method_call (instance, name, parms, basetype_path, flags)
name = TREE_OPERAND (name, 0);
if (parms)
error ("destructors take no parameters");
- basetype = get_type_value (name);
- if (basetype == NULL_TREE)
+ basetype = TREE_TYPE (instance);
+ if (IS_AGGR_TYPE (basetype))
+ {
+ if (name == constructor_name (basetype))
+ goto huzzah;
+ }
+ else
{
- cp_error ("call to destructor for non-type `%D'", name);
- return void_zero_node;
+ if (basetype == get_type_value (name))
+ goto huzzah;
}
- if (basetype != TREE_TYPE(instance))
- basetype = TREE_TYPE(instance);
+ cp_error ("destructor name `~%D' does not match type `%T' of expression",
+ name, basetype);
+ return void_zero_node;
+
+ huzzah:
if (! TYPE_HAS_DESTRUCTOR (basetype))
return void_zero_node;
instance = default_conversion (instance);
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 1d27681..62eff53 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2400,6 +2400,10 @@ override_one_vtable (binfo, old, t)
}
TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
}
+ else if (choose == NEITHER)
+ {
+ TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals);
+ }
}
else
{
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9ba72b0..5a7c353 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1167,6 +1167,9 @@ struct lang_decl
has been duly initialized in its constructor. */
#define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4(NODE))
+#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \
+ && CONSTRUCTOR_ELTS (NODE) == NULL_TREE)
+
/* Indicates that a NON_LVALUE_EXPR came from a C++ reference.
Used to generate more helpful error message in case somebody
tries to take its address. */
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 3750221..0b08f05 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -337,7 +337,20 @@ build_up_reference (type, arg, flags, checkconst)
TREE_READONLY (arg) = 0;
}
+#if 0
+ if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
+ {
+ rval = copy_node (arg);
+ TREE_TYPE (rval) = build_pointer_type (TREE_TYPE (TREE_TYPE (arg)));
+ }
+ else
+ rval = arg;
+
+ rval = convert (build_pointer_type (TREE_TYPE (type)), rval);
+ TREE_TYPE (rval) = type;
+#else
rval = build1 (CONVERT_EXPR, type, arg);
+#endif
TREE_REFERENCE_EXPR (rval) = 1;
/* propagate the const flag on something like:
@@ -372,7 +385,7 @@ build_up_reference (type, arg, flags, checkconst)
}
literal_flag = TREE_CONSTANT (arg);
- goto done_but_maybe_warn;
+ goto done;
/* Get this out of a register if we happened to be in one by accident.
Also, build up references to non-lvalues it we must. */
@@ -409,7 +422,7 @@ build_up_reference (type, arg, flags, checkconst)
TREE_TYPE (rval) = type;
literal_flag = staticp (TREE_OPERAND (targ, 0));
- goto done_but_maybe_warn;
+ goto done;
/* Anything not already handled and not a true memory reference
needs to have a reference built up. Do so silently for
@@ -537,7 +550,12 @@ build_up_reference (type, arg, flags, checkconst)
if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (argtype))
{
temp = build_cplus_new (argtype, targ, 1);
- rval = build1 (ADDR_EXPR, type, temp);
+ if (TREE_CODE (temp) == WITH_CLEANUP_EXPR)
+ rval = build (WITH_CLEANUP_EXPR, type,
+ build1 (ADDR_EXPR, type, TREE_OPERAND (temp, 0)),
+ 0, TREE_OPERAND (temp, 2));
+ else
+ rval = build1 (ADDR_EXPR, type, temp);
goto done;
}
else
@@ -572,10 +590,6 @@ build_up_reference (type, arg, flags, checkconst)
else
rval = build1 (ADDR_EXPR, type, arg);
- done_but_maybe_warn:
- if (checkconst && TREE_READONLY (arg) && ! TYPE_READONLY (target_type))
- readonly_error (arg, "conversion to reference", 1);
-
done:
if (TYPE_USES_COMPLEX_INHERITANCE (argtype))
{
@@ -636,7 +650,11 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
if (form == REFERENCE_TYPE)
ttr = TREE_TYPE (TREE_TYPE (expr));
else
- ttr = TREE_TYPE (expr);
+ {
+ int r = TREE_READONLY (expr);
+ int v = TREE_THIS_VOLATILE (expr);
+ ttr = c_build_type_variant (TREE_TYPE (expr), r, v);
+ }
if (! lvalue_p (expr) &&
(decl == NULL_TREE || ! TYPE_READONLY (ttl)))
@@ -653,46 +671,20 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
{
if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
cp_pedwarn ("conversion from `%T' to `%T' discards const",
- TREE_TYPE (expr), reftype);
+ ttr, reftype);
else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
cp_pedwarn ("conversion from `%T' to `%T' discards volatile",
- TREE_TYPE (expr), reftype);
- }
- }
-
- /* If EXPR is of aggregate type, and is really a CALL_EXPR,
- then we don't need to convert it to reference type if
- it is only being used to initialize DECL which is also
- of the same aggregate type. */
- if (decl != NULL_TREE && decl != error_mark_node
- && IS_AGGR_TYPE (type)
- && TREE_CODE (expr) == CALL_EXPR
- && TYPE_MAIN_VARIANT (type) == intype)
- {
- tree e1 = build (INIT_EXPR, void_type_node, decl, expr);
- tree e2;
-
- TREE_SIDE_EFFECTS (e1) = 1;
- if (form == REFERENCE_TYPE)
- e2 = build1 (NOP_EXPR, reftype, decl);
- else
- {
- e2 = build_unary_op (ADDR_EXPR, decl, 0);
- TREE_TYPE (e2) = reftype;
- TREE_REFERENCE_EXPR (e2) = 1;
+ ttr, reftype);
}
- return build_compound_expr
- (tree_cons (NULL_TREE, e1, build_tree_list (NULL_TREE, e2)));
}
- else if (form == REFERENCE_TYPE)
+ if (form == REFERENCE_TYPE)
{
- rval = build1 (NOP_EXPR,
- build_pointer_type (TREE_TYPE (TREE_TYPE (expr))),
- expr);
+ rval = copy_node (expr);
+ TREE_TYPE (rval) = build_pointer_type (TREE_TYPE (TREE_TYPE (expr)));
rval = cp_convert (build_pointer_type (TREE_TYPE (reftype)), rval,
convtype, flags);
- rval = build1 (NOP_EXPR, reftype, rval);
+ TREE_TYPE (rval) = reftype;
return rval;
}
@@ -1364,7 +1356,7 @@ cp_convert (type, expr, convtype, flags)
return error_mark_node;
}
/* call to constructor successful. */
- rval = build_cplus_new (type, rval, 0);
+ rval = build_cplus_new (type, rval, 1);
return rval;
}
}
@@ -1415,7 +1407,7 @@ cp_convert (type, expr, convtype, flags)
cp_error ("in conversion to type `%T'", type);
return error_mark_node;
}
- rval = build_cplus_new (type, init, 0);
+ rval = build_cplus_new (type, init, 1);
return rval;
}
}
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 4bbfec9..5a20953 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -244,15 +244,6 @@ tree maybe_gc_cleanup;
/* Array type `vtable_entry_type[]' */
tree vtbl_type_node;
-/* Static decls which do not have static initializers have no
- initializers as far as GNU C is concerned. EMPTY_INIT_NODE
- is a static initializer which makes varasm code place the decl
- in data rather than in bss space. Such gymnastics are necessary
- to avoid the problem that the linker will not include a library
- file if all the library appears to contribute are bss variables. */
-
-tree empty_init_node;
-
/* In a destructor, the point at which all derived class destroying
has been done, just before any base class destroying will be done. */
@@ -4376,7 +4367,6 @@ init_decl_processing ()
TREE_TYPE (integer_two_node) = integer_type_node;
integer_three_node = build_int_2 (3, 0);
TREE_TYPE (integer_three_node) = integer_type_node;
- empty_init_node = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE);
bool_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
TREE_SET_CODE (bool_type_node, BOOLEAN_TYPE);
@@ -5385,8 +5375,14 @@ start_decl (declarator, declspecs, initialized, raises)
else
tem = pushdecl (decl);
- /* Tell the back-end to use or not use .common as appropriate. */
- DECL_COMMON (tem) = flag_conserve_space;
+ /* Tell the back-end to use or not use .common as appropriate. If we say
+ -fconserve-space, we want this to save space, at the expense of wrong
+ semantics. If we say -fno-conserve-space, we want this to produce
+ errors about redefs; to do this we force variables into the data
+ segment. Common storage is okay for non-public uninitialized data;
+ the linker can't match it with storage from other files, and we may
+ save some disk space. */
+ DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem);
#if 0
/* We don't do this yet for GNU C++. */
@@ -5556,10 +5552,7 @@ grok_reference_init (decl, type, init, cleanupp)
tree decl, type, init;
tree *cleanupp;
{
- char *errstr = NULL;
- int is_reference;
tree tmp;
- tree this_ptr_type, actual_init = NULL_TREE;
if (init == NULL_TREE)
{
@@ -5585,56 +5578,22 @@ grok_reference_init (decl, type, init, cleanupp)
if (TREE_CODE (init) == TREE_LIST)
init = build_compound_expr (init);
- is_reference = TREE_CODE (TREE_TYPE (init)) == REFERENCE_TYPE;
- tmp = is_reference ? convert_from_reference (init) : init;
if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE)
{
- /* Note: default conversion is only called in very
- special cases. */
+ /* Note: default conversion is only called in very special cases. */
init = default_conversion (init);
}
- /* Can we just enreference this lvalue? */
- if ((is_reference || lvalue_p (init)
- || (actual_init = unary_complex_lvalue (ADDR_EXPR, init)))
- && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
- TYPE_MAIN_VARIANT (TREE_TYPE (tmp)), 0))
- {
- /* This section implements ANSI C++ June 5 1992 WP 8.4.3.5. */
+ tmp = convert_to_reference
+ (type, init, CONV_IMPLICIT, LOOKUP_SPECULATIVELY|LOOKUP_NORMAL, decl);
- /* A reference to a volatile T cannot be initialized with
- a const T, and vice-versa. */
- if (TYPE_VOLATILE (TREE_TYPE (type)) && TREE_READONLY (init))
- errstr = "cannot initialize a reference to a volatile `%T' with a const `%T'";
- else if (TYPE_READONLY (TREE_TYPE (type)) && TREE_THIS_VOLATILE (init))
- errstr = "cannot initialize a reference to a const `%T' with a volatile `%T'";
- /* A reference to a plain T can be initialized only with a plain T. */
- else if (!TYPE_VOLATILE (TREE_TYPE (type))
- && !TYPE_READONLY (TREE_TYPE (type)))
- {
- if (TREE_READONLY (init))
- errstr = "cannot initialize a reference to `%T' with a const `%T'";
- else if (TREE_THIS_VOLATILE (init))
- errstr = "cannot initialize a reference to `%T' with a volatile `%T'";
- }
- if (errstr)
- {
- cp_error (errstr, TREE_TYPE (type), TREE_TYPE (tmp));
- goto fail;
- }
- }
- /* OK, can we generate a reference then? */
- else if ((actual_init = convert_to_reference
- (type, init, CONV_IMPLICIT,
- LOOKUP_SPECULATIVELY|LOOKUP_NORMAL, decl)))
+ if (tmp == error_mark_node)
+ goto fail;
+ else if (tmp != NULL_TREE)
{
- if (actual_init == error_mark_node)
- goto fail;
-
- init = actual_init;
- is_reference = 1;
+ init = tmp;
if (TREE_CODE (init) == WITH_CLEANUP_EXPR)
{
@@ -5643,61 +5602,17 @@ grok_reference_init (decl, type, init, cleanupp)
*cleanupp = TREE_OPERAND (init, 2);
TREE_OPERAND (init, 2) = error_mark_node;
}
- }
- else
- {
- cp_error ("cannot initialize `%T' from `%T'", type, TREE_TYPE (init));
- goto fail;
- }
- /* In the case of initialization, it is permissible
- to assign one reference to another. */
- this_ptr_type = build_pointer_type (TREE_TYPE (type));
-
- if (is_reference)
- {
if (TREE_SIDE_EFFECTS (init))
DECL_INITIAL (decl) = save_expr (init);
else
DECL_INITIAL (decl) = init;
}
- else if (lvalue_p (init))
+ else
{
- tmp = build_unary_op (ADDR_EXPR, init, 0);
- if (TREE_CODE (tmp) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (tmp, 0)) == WITH_CLEANUP_EXPR)
- {
- if (*cleanupp) my_friendly_abort (1);
- *cleanupp = TREE_OPERAND (TREE_OPERAND (tmp, 0), 2);
- TREE_OPERAND (TREE_OPERAND (tmp, 0), 2) = error_mark_node;
- }
- if (IS_AGGR_TYPE (TREE_TYPE (this_ptr_type)))
- DECL_INITIAL (decl) = convert_pointer_to (TREE_TYPE (this_ptr_type),
- tmp);
- else
- DECL_INITIAL (decl) = convert (this_ptr_type, tmp);
-
- DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl));
- if (DECL_INITIAL (decl) == current_class_decl)
- DECL_INITIAL (decl) = copy_node (current_class_decl);
- TREE_TYPE (DECL_INITIAL (decl)) = type;
- }
- /* If actual_init is set here, it is set from the first check above. */
- else if (actual_init)
- {
- /* The initializer for this decl goes into its
- DECL_REFERENCE_SLOT. Make sure that we can handle
- multiple evaluations without ill effect. */
- if (TREE_CODE (actual_init) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (actual_init, 0)) == TARGET_EXPR)
- actual_init = save_expr (actual_init);
- DECL_INITIAL (decl) = convert_pointer_to (TREE_TYPE (this_ptr_type),
- actual_init);
- DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl));
- TREE_TYPE (DECL_INITIAL (decl)) = type;
+ cp_error ("cannot initialize `%T' from `%T'", type, TREE_TYPE (init));
+ goto fail;
}
- else
- my_friendly_abort (1);
/* ?? Can this be optimized in some cases to
hand back the DECL_INITIAL slot?? */
@@ -5892,8 +5807,7 @@ finish_decl (decl, init, asmspec_tree, need_pop)
{
if (TREE_CODE (type) == ARRAY_TYPE)
init = digest_init (type, init, (tree *) 0);
- else if (TREE_CODE (init) == CONSTRUCTOR
- && CONSTRUCTOR_ELTS (init) != NULL_TREE)
+ else if (TREE_CODE (init) == CONSTRUCTOR)
{
if (TYPE_NEEDS_CONSTRUCTING (type))
{
@@ -5951,16 +5865,11 @@ finish_decl (decl, init, asmspec_tree, need_pop)
if (current_binding_level == global_binding_level)
{
tree value;
- if (flag_conserve_space)
- /* If we say -fconserve-space, we want this to save
- space, at the expense of wrong semantics. */
+ if (DECL_COMMON (decl))
/* Should this be a NULL_TREE? */
value = error_mark_node;
else
- /* If we say -fno-conserve-space, we want this to
- produce errors about redefs, to do this we make it
- go in the data space */
- value = digest_init (type, empty_init_node, (tree *) 0);
+ value = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
DECL_INITIAL (decl) = value;
}
else
@@ -5972,10 +5881,17 @@ finish_decl (decl, init, asmspec_tree, need_pop)
if (TREE_CODE (init) != TREE_VEC)
init = store_init_value (decl, init);
+ /* Don't let anyone try to initialize this variable
+ until we are ready to do so. */
if (init)
- /* Don't let anyone try to initialize this variable
- until we are ready to do so. */
- DECL_INITIAL (decl) = error_mark_node;
+ {
+ tree value;
+ if (DECL_COMMON (decl))
+ value = error_mark_node;
+ else
+ value = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
+ DECL_INITIAL (decl) = value;
+ }
}
}
else if (DECL_EXTERNAL (decl))
@@ -6002,27 +5918,19 @@ finish_decl (decl, init, asmspec_tree, need_pop)
cp_error ("uninitialized const `%D'", decl);
/* Initialize variables in need of static initialization with
- `empty_init_node' to keep assemble_variable from putting them in
- the wrong program space. Common storage is okay for non-public
- uninitialized data; the linker can't match it with storage from
- other files, and we may save some disk space. Consts have to go
- into data, though, since the backend would put them in text
- otherwise. */
+ an empty CONSTRUCTOR to keep assemble_variable from putting them in
+ the wrong program space. */
if (flag_pic == 0
&& TREE_STATIC (decl)
- && (TREE_PUBLIC (decl) || was_readonly)
+ && TREE_PUBLIC (decl)
&& ! DECL_EXTERNAL (decl)
&& TREE_CODE (decl) == VAR_DECL
&& TYPE_NEEDS_CONSTRUCTING (type)
&& (DECL_INITIAL (decl) == NULL_TREE
|| DECL_INITIAL (decl) == error_mark_node)
- /* If we say -fconserve-space, we want this to save space,
- at the expense of wrong semantics. */
- && ! flag_conserve_space)
- {
- tree value = digest_init (type, empty_init_node, (tree *) 0);
- DECL_INITIAL (decl) = value;
- }
+ && ! DECL_COMMON (decl))
+ DECL_INITIAL (decl) = build (CONSTRUCTOR, type, NULL_TREE,
+ NULL_TREE);
}
else if (TREE_CODE (decl) == VAR_DECL
&& TREE_CODE (type) != REFERENCE_TYPE
@@ -6182,7 +6090,7 @@ finish_decl (decl, init, asmspec_tree, need_pop)
&& TREE_READONLY (decl)
&& DECL_INITIAL (decl) != NULL_TREE
&& DECL_INITIAL (decl) != error_mark_node
- && DECL_INITIAL (decl) != empty_init_node)
+ && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
{
DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl));
@@ -6889,9 +6797,8 @@ grokvardecl (type, declarator, specbits, initialized)
if (initialized && DECL_INITIAL (decl)
/* Complain about multiply-initialized
member variables, but don't be faked
- out if initializer is faked up from `empty_init_node'. */
- && (TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR
- || CONSTRUCTOR_ELTS (DECL_INITIAL (decl)) != NULL_TREE))
+ out if initializer is empty. */
+ && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
error_with_aggr_type (DECL_CONTEXT (decl),
"multiple initializations of static member `%s::%s'",
IDENTIFIER_POINTER (DECL_NAME (decl)));
@@ -7358,44 +7265,19 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if (TREE_CODE (id) == IDENTIFIER_NODE)
{
- if (id == ridpointers[(int) RID_INT])
- {
- if (type)
- error ("extraneous `int' ignored");
- else
- {
- explicit_int = 1;
- type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
- }
- goto found;
- }
- if (id == ridpointers[(int) RID_CHAR])
- {
- if (type)
- error ("extraneous `char' ignored");
- else
- {
- explicit_char = 1;
- type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
- }
- goto found;
- }
- if (id == ridpointers[(int) RID_BOOL])
- {
- if (type)
- error ("extraneous `bool' ignored");
- else
- {
- type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
- }
- goto found;
- }
- if (id == ridpointers[(int) RID_WCHAR])
+ if (id == ridpointers[(int) RID_INT]
+ || id == ridpointers[(int) RID_CHAR]
+ || id == ridpointers[(int) RID_BOOL]
+ || id == ridpointers[(int) RID_WCHAR])
{
if (type)
- error ("extraneous `__wchar_t' ignored");
+ error ("extraneous `%T' ignored", id);
else
{
+ if (id == ridpointers[(int) RID_INT])
+ explicit_int = 1;
+ else if (id == ridpointers[(int) RID_CHAR])
+ explicit_char = 1;
type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id));
}
goto found;
@@ -7459,6 +7341,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
which case the type defaults to `unknown type' and is
instantiated when assigning to a signature pointer or ref. */
+ if (type == NULL_TREE
+ && (RIDBIT_SETP (RID_SIGNED, specbits)
+ || RIDBIT_SETP (RID_UNSIGNED, specbits)
+ || RIDBIT_SETP (RID_LONG, specbits)
+ || RIDBIT_SETP (RID_SHORT, specbits)))
+ {
+ /* These imply 'int'. */
+ type = integer_type_node;
+ explicit_int = 1;
+ }
+
if (type == NULL_TREE)
{
explicit_int = -1;
@@ -7478,22 +7371,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
opaque_typedef = 1;
type = copy_node (opaque_type_node);
}
+ /* access declaration */
+ else if (decl_context == FIELD && declarator
+ && TREE_CODE (declarator) == SCOPE_REF)
+ type = void_type_node;
else
{
if (funcdef_flag)
{
if (warn_return_type
- && return_type == return_normal
- && ! (RIDBIT_SETP (RID_SIGNED, specbits)
- || RIDBIT_SETP (RID_UNSIGNED, specbits)
- || RIDBIT_SETP (RID_LONG, specbits)
- || RIDBIT_SETP (RID_SHORT, specbits)))
+ && return_type == return_normal)
/* Save warning until we know what is really going on. */
warn_about_return_type = 1;
}
- else if (decl_context == FIELD && declarator
- && TREE_CODE (declarator) == SCOPE_REF)
- /* OK -- access declaration */;
+ else if (RIDBIT_SETP (RID_TYPEDEF, specbits))
+ pedwarn ("ANSI C++ forbids typedef which does not specify a type");
else if (declspecs == NULL_TREE &&
(innermost_code != CALL_EXPR || pedantic))
cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type or storage class",
@@ -7522,6 +7414,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
type = ctor_return_type;
}
+ /* Catch typedefs that only specify a type, like 'typedef int;'. */
+ else if (RIDBIT_SETP (RID_TYPEDEF, specbits) && declarator == NULL_TREE)
+ {
+ /* Template "this is a type" syntax; just ignore for now. */
+ if (processing_template_defn)
+ return void_type_node;
+ }
ctype = NULL_TREE;
@@ -8481,16 +8380,16 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
TREE_TYPE (type), TYPE_ARG_TYPES (type));
else
{
- error ("cannot declare member function `%s::%s' within this class",
- TYPE_NAME_STRING (ctype), name);
+ cp_error ("cannot declare member function `%T::%D' within `%T'",
+ ctype, name, current_class_type);
return void_type_node;
}
}
else if (TYPE_MAIN_VARIANT (ctype) == current_class_type)
{
if (extra_warnings)
- warning ("extra qualification `%s' on member `%s' ignored",
- TYPE_NAME_STRING (ctype), name);
+ cp_warning ("redundant qualification `%T' on member `%D' ignored",
+ ctype, name);
type = build_offset_type (ctype, type);
}
else if (TYPE_SIZE (ctype) != NULL_TREE
@@ -8659,7 +8558,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises)
if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE)
{
cp_error_at ("typedef name may not be class-qualified", decl);
- TREE_TYPE (decl) = error_mark_node;
+ return NULL_TREE;
}
else if (quals)
{
@@ -10773,6 +10672,19 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
(This does not mean `static' in the C sense!) */
TREE_STATIC (decl1) = 1;
+ /* Record the decl so that the function name is defined.
+ If we already have a decl for this name, and it is a FUNCTION_DECL,
+ use the old decl. */
+
+ if (pre_parsed_p == 0)
+ {
+ current_function_decl = decl1 = pushdecl (decl1);
+ DECL_MAIN_VARIANT (decl1) = decl1;
+ fntype = TREE_TYPE (decl1);
+ }
+ else
+ current_function_decl = decl1;
+
/* If this function belongs to an interface, it is public.
If it belongs to someone else's interface, it is also external.
It doesn't matter whether it's inline or not. */
@@ -10800,19 +10712,6 @@ start_function (declspecs, declarator, raises, pre_parsed_p)
#endif
}
- /* Record the decl so that the function name is defined.
- If we already have a decl for this name, and it is a FUNCTION_DECL,
- use the old decl. */
-
- if (pre_parsed_p == 0)
- {
- current_function_decl = decl1 = pushdecl (decl1);
- DECL_MAIN_VARIANT (decl1) = decl1;
- fntype = TREE_TYPE (decl1);
- }
- else
- current_function_decl = decl1;
-
if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1))
{
if (TREE_CODE (fntype) == METHOD_TYPE)
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 964615e..35d408b 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -215,7 +215,7 @@ int warn_extern_inline;
#endif
int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
-/* Nonzero for -no-strict-prototype switch: do not consider empty
+/* Nonzero for -fno-strict-prototype switch: do not consider empty
argument prototype to mean function takes no arguments. */
int strict_prototype = 1;
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 084eebd..5e5d580 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1117,13 +1117,7 @@ expand_aggr_init (exp, init, alias_this)
int was_const_elts = TYPE_READONLY (TREE_TYPE (type));
tree itype = init ? TREE_TYPE (init) : NULL_TREE;
if (was_const_elts)
- {
- tree atype = build_cplus_array_type (TYPE_MAIN_VARIANT (TREE_TYPE (type)),
- TYPE_DOMAIN (type));
- if (init && (TREE_TYPE (exp) == TREE_TYPE (init)))
- TREE_TYPE (init) = atype;
- TREE_TYPE (exp) = atype;
- }
+ TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
if (init && TREE_TYPE (init) == NULL_TREE)
{
/* Handle bad initializers like:
@@ -2613,40 +2607,9 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
enum overload_flags flags;
tree quals;
{
- /* first, lets find out if what we are making a friend needs overloading */
- tree previous_decl;
- int was_c_linkage = 0;
-
/* Every decl that gets here is a friend of something. */
DECL_FRIEND_P (decl) = 1;
- /* If we find something in scope, let see if it has extern "C" linkage. */
- /* This code is pretty general and should be ripped out and reused
- as a separate function. */
- if (DECL_NAME (decl))
- {
- previous_decl = lookup_name (DECL_NAME (decl), 0);
- if (previous_decl && TREE_CODE (previous_decl) == TREE_LIST)
- {
- do
- {
- if (TREE_TYPE (TREE_VALUE (previous_decl)) == TREE_TYPE (decl))
- {
- previous_decl = TREE_VALUE (previous_decl);
- break;
- }
- previous_decl = TREE_CHAIN (previous_decl);
- }
- while (previous_decl);
- }
-
- /* It had extern "C" linkage, so don't overload this. */
- if (previous_decl && TREE_CODE (previous_decl) == FUNCTION_DECL
- && TREE_TYPE (decl) == TREE_TYPE (previous_decl)
- && DECL_LANGUAGE (previous_decl) == lang_c)
- was_c_linkage = 1;
- }
-
if (ctype)
{
tree cname = TYPE_NAME (ctype);
@@ -2711,7 +2674,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
decl = void_type_node;
}
}
- /* never overload C functions */
else if (TREE_CODE (decl) == FUNCTION_DECL
&& ((IDENTIFIER_LENGTH (declarator) == 4
&& IDENTIFIER_POINTER (declarator)[0] == 'm'
@@ -2720,8 +2682,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals)
&& IDENTIFIER_POINTER (declarator)[0] == '_'
&& IDENTIFIER_POINTER (declarator)[1] == '_'
&& strncmp (IDENTIFIER_POINTER (declarator)+2,
- "builtin_", 8) == 0)
- || was_c_linkage))
+ "builtin_", 8) == 0)))
{
/* raw "main", and builtin functions never gets overloaded,
but they can become friends. */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 79d37f7..827ee35 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2377,6 +2377,9 @@ do_function_instantiation (declspecs, declarator, storage)
if (flag_external_templates)
return;
+ if (DECL_EXPLICIT_INSTANTIATION (result) && ! DECL_EXTERNAL (result))
+ return;
+
SET_DECL_EXPLICIT_INSTANTIATION (result);
TREE_PUBLIC (result) = 1;
@@ -2399,6 +2402,9 @@ do_type_instantiation (name, storage)
if (flag_external_templates)
return;
+ if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t))
+ return;
+
if (TYPE_SIZE (t) == NULL_TREE)
{
cp_error ("explicit instantiation of `%#T' before definition of template",
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 5805d36..832d965 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -74,12 +74,6 @@ lvalue_p (ref)
case WITH_CLEANUP_EXPR:
return 1;
- case CALL_EXPR:
- /* unary_complex_lvalue knows how to deal with this case. */
- if (TREE_ADDRESSABLE (TREE_TYPE (ref)))
- return 1;
- break;
-
/* A currently unresolved scope ref. */
case SCOPE_REF:
my_friendly_abort (103);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 746bcd8..840abe6 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5336,6 +5336,7 @@ build_modify_expr (lhs, modifycode, rhs)
tree newrhs = rhs;
tree lhstype = TREE_TYPE (lhs);
tree olhstype = lhstype;
+ tree olhs = lhs;
/* Types that aren't fully specified cannot be used in assignments. */
lhs = require_complete_type (lhs);
@@ -5933,7 +5934,11 @@ build_modify_expr (lhs, modifycode, rhs)
for enum bit fields. */
if (TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE
&& TREE_CODE (olhstype) == ENUMERAL_TYPE)
- return convert_force (olhstype, result);
+ {
+ result = build (COMPOUND_EXPR, olhstype, result, olhs);
+ TREE_NO_UNUSED_WARNING (result) = 1;
+ return result;
+ }
return convert_for_assignment (olhstype, result, "assignment",
NULL_TREE, 0);
}
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 2fe6040..df76845 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -844,7 +844,6 @@ static tree
process_init_constructor (type, init, elts)
tree type, init, *elts;
{
- extern tree empty_init_node;
register tree tail;
/* List of the elements of the result constructor,
in reverse order. */
@@ -917,7 +916,7 @@ process_init_constructor (type, init, elts)
members = tree_cons (NULL_TREE, next1, members);
}
}
- if (TREE_CODE (type) == RECORD_TYPE && init != empty_init_node)
+ if (TREE_CODE (type) == RECORD_TYPE)
{
register tree field;
@@ -1010,7 +1009,7 @@ process_init_constructor (type, init, elts)
}
}
- if (TREE_CODE (type) == UNION_TYPE && init != empty_init_node)
+ if (TREE_CODE (type) == UNION_TYPE)
{
register tree field = TYPE_FIELDS (type);
register tree next1;
@@ -1438,7 +1437,7 @@ build_functional_cast (exp, parms)
return error_mark_node;
if (current_function_decl)
- return build_cplus_new (type, expr_as_ctor, 0);
+ return build_cplus_new (type, expr_as_ctor, 1);
{
register tree parm = TREE_OPERAND (expr_as_ctor, 1);