From: Mike Stump Date: Fri, 24 Jun 1994 00:54:38 +0000 (+0000) Subject: 41st Cygnus<->FSF merge X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a32034654e77ec19b8c0245d6dbebb06082f0612;p=platform%2Fupstream%2Fgcc.git 41st Cygnus<->FSF merge From-SVN: r7553 --- 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);