diff options
author | obrien <obrien@FreeBSD.org> | 2002-12-04 15:42:16 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-12-04 15:42:16 +0000 |
commit | 7a1080fa5c329ea8a9505e51ce151719955bcfa2 (patch) | |
tree | 78b77287e56e2a87be73638176124be85a8fc6c7 /contrib/gcc/cp | |
parent | ef3bb1318428b8cfb1c8287f61b9b1f23f9bf0b5 (diff) | |
download | FreeBSD-src-7a1080fa5c329ea8a9505e51ce151719955bcfa2.zip FreeBSD-src-7a1080fa5c329ea8a9505e51ce151719955bcfa2.tar.gz |
Gcc 3.2.1 release virgin vendor import. (19-Nov-2002)
Diffstat (limited to 'contrib/gcc/cp')
-rw-r--r-- | contrib/gcc/cp/ChangeLog | 188 | ||||
-rw-r--r-- | contrib/gcc/cp/cfns.h | 9 | ||||
-rw-r--r-- | contrib/gcc/cp/class.c | 48 | ||||
-rw-r--r-- | contrib/gcc/cp/cp-lang.c | 21 | ||||
-rw-r--r-- | contrib/gcc/cp/cp-tree.h | 29 | ||||
-rw-r--r-- | contrib/gcc/cp/cvt.c | 10 | ||||
-rw-r--r-- | contrib/gcc/cp/decl.c | 64 | ||||
-rw-r--r-- | contrib/gcc/cp/decl2.c | 14 | ||||
-rw-r--r-- | contrib/gcc/cp/init.c | 2 | ||||
-rw-r--r-- | contrib/gcc/cp/lex.c | 17 | ||||
-rw-r--r-- | contrib/gcc/cp/mangle.c | 73 | ||||
-rw-r--r-- | contrib/gcc/cp/method.c | 2 | ||||
-rw-r--r-- | contrib/gcc/cp/parse.y | 30 | ||||
-rw-r--r-- | contrib/gcc/cp/pt.c | 10 | ||||
-rw-r--r-- | contrib/gcc/cp/rtti.c | 8 | ||||
-rw-r--r-- | contrib/gcc/cp/semantics.c | 2 | ||||
-rw-r--r-- | contrib/gcc/cp/spew.c | 93 | ||||
-rw-r--r-- | contrib/gcc/cp/tree.c | 20 | ||||
-rw-r--r-- | contrib/gcc/cp/typeck.c | 19 | ||||
-rw-r--r-- | contrib/gcc/cp/typeck2.c | 5 |
20 files changed, 540 insertions, 124 deletions
diff --git a/contrib/gcc/cp/ChangeLog b/contrib/gcc/cp/ChangeLog index cc84a03..5a611ae 100644 --- a/contrib/gcc/cp/ChangeLog +++ b/contrib/gcc/cp/ChangeLog @@ -1,3 +1,191 @@ +2002-11-19 Release Manager + + * GCC 3.2.1 Released. + +2002-11-19 Release Manager + + * GCC 3.2.1 Released. + +2002-11-18 Release Manager + + * GCC 3.2.1 Released. + +2002-11-11 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/7788 + * rtti.c (unemitted_tinfo_decl_p): Check it has a field. + +2002-11-02 Zack Weinberg <zack@codesourcery.com> + + PR c/7353 redux + * decl2.c (grokfield): Reject TYPE_DECLs with initializers. + +2002-11-01 Gabriel Dos Reis <gdr@integrable-solutions.net> + + PR C++/2521 + * typeck.c (build_x_unary_op): Handle pointer-to-member. + +2002-10-30 Mark Mitchell <mark@codesourcery.com> + + PR c++/8160 + * typeck2.c (process_init_constructor): Call complete_array_type. + + PR c++/8149 + * decl.c (make_typename_type): Issue errors about invalid results. + +2002-10-29 Mark Mitchell <mark@codesourcery.com> + + PR c++/8287 + * decl.c (finish_destructor_body): Create the label to jump to + when returning from a destructor here. + (finish_function_body): Rather than here. + + * semantics.c (finish_alignof): Call complete_type before calling + c_alignof. + * decl2.c (build_expr_from_tree): Use + finish_sizeof/finish_alignof. + +2002-10-10 Jim Wilson <wilson@redhat.com> + + * decl.c (duplicate_decls): Don't call decl_attributes. + +2002-10-25 Zack Weinberg <zack@codesourcery.com> + + PR middle-end/6994 + * cp-lang.c (cp_var_mod_type_p): New: C++ hook for + variably_modified_type_p. + * cp-tree.h: Remove prototype of variably_modified_type_p. + * tree.c (variably_modified_type_p): Remove; now implemented + in language-independent code. + + PR c++/7266 + * decl.c (grokdeclarator): Check that TREE_OPERAND 0 of a + SCOPE_REF is not null before dereferencing it. + +2002-10-24 David Edelsohn <edelsohn@gnu.org> + + PR c++/7228 + * cp-tree.h (CLASSTYPE_READONLY_FIELDS_NEED_INIT): Check that + lang_type structure exists before accessing field. + (SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT): New macro. + (CLASSTYPE_REF_FIELDS_NEED_INIT): Similar. + (SET_CLASSTYPE_REF_FIELDS_NEED_INIT): New macro. + * class.c (check_field_decls): Use new macros. + * typeck2.c (process_init_constructor): Remove redundant check for + existence of lang_type structure. + +2002-10-23 Mark Mitchell <mark@codesourcery.com> + + PR c++/8067 + * decl.c (maybe_inject_for_scope_var): Ignore __FUNCTION__ and + related variables. + +2002-10-23 Mark Mitchell <mark@codesourcery.com> + + PR c++/7679 + * spew.c (next_token): Do not return an endless stream of + END_OF_SAVED_INPUT tokens. + (snarf_method): Add three END_OF_SAVED_INPUT tokens to the end of + the cached token stream. + (snarf_defarg): Likewise. + +2002-10-22 Mark Mitchell <mark@codesourcery.com> + + PR c++/6579 + * spew.c (snarf_parenthesized_expression): New function. + (snarf_block): Use it. + +2002-10-21 Matthias Klose <doko@debian.org> + + * Backport, without whitespace change: + 2002-06-19 Akim Demaille <akim@epita.fr> + * parse.y (TYPENAME): Rename as tTYPENAME to avoid the clash with + decl.h's TYPENAME. + * spew.c, lex.c: Adjust. + * parse.y (explicit_instantiation): Add empty action to override + the default $$ = $1 where it introduces a type clash. + +2002-10-21 Mark Mitchell <mark@codesourcery.com> + + PR c++/8218 + * cp-tree.h (lang_type_class): Add contains_empty_class_p. + (CLASSTYPE_CONTAINS_EMPTY_CLASS_P): New macro. + * class.c (check_bases): Update CLASSTYPE_CONTAINS_EMPTY_CLASS_P. + (check_field_decls): Likewise. + (layout_class_type): Likewise. + (finish_struct_1): Initialize it. + (walk_subobject_offsets): Use it to prune searches. + +2002-10-18 Zack Weinberg <zack@codesourcery.com> + + * decl.c (start_decl): Point users of the old initialized- + typedef extension at __typeof__. + +2002-10-18 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/7676 + * class.c (add_method): Compare template parms too. + +2002-10-17 Mark Mitchell <mark@codesourcery.com> + + * mangle.c (globals): Add entity and need_abi_warning. + (write_prefix): Likewise. + (write_template_prefix): Likewise. + (start_mangling): Add entity parameter. + (finish_mangling): Warn about names whose mangling will change. + (mangle_decl_string): Adjust. + (mangle_type_string): Likewise. + (mangle_special_for_type): Likewise. + (mangle_ctor_vtbl_for_type): Likewise. + (mangle_thunk): Likewise. + (mangle_guard_variable): Likewise. + (mangle_ref_init_variable): Likewise. + + PR c++/7584 + * class.c (handle_using_decl): Allow the declaration used to be + from an ambiguous base. + +2002-10-16 Mark Mitchell <mark@codesourcery.com> + + PR c++/7478 + * cvt.c (convert_to_reference): Allow references as the incoming + type. + + PR c++/8134 + * tree.c (zero_init_p): Always return 1. + + PR c++/7524 + * method.c (do_build_assign_ref): Use cp_build_qualified_type, not + build_qualified_type. + +2002-10-14 Mark Mitchell <mark@codesourcery.com> + + PR c++/7176 + * lex.c (do_identifier): Add another option for the parsing + parameter. + * parse.y (do_id): Use it. + +2002-10-11 Mark Mitchell <mark@codesourcery.com> + + PR c++/5661 + * cp-tree.h (variably_modified_type_p): New function. + (grokdeclarator) Tighten check for variably modified types as + fields. + * pt.c (convert_template_argument): Do not allow variably modified + types as template arguments. + * tree.c (variably_modified_type_p): New function. + +2002-10-11 Jason Molenda <jmolenda@apple.com> + + * init.c (build_field_list): Provide uses_unions_p with a default + value. + +2002-10-10 Gabriel Dos Reis <gdr@integrable-solutions.net> + + PRs C++/6803, C++/7721 and C++/7803 + * decl.c (grokdeclarator): Gracefully handle template-name as + decl-specifier. + 2002-10-09 Zack Weinberg <zack@codesourcery.com> PR c/7353 diff --git a/contrib/gcc/cp/cfns.h b/contrib/gcc/cp/cfns.h index a139160..c7e6a9d 100644 --- a/contrib/gcc/cp/cfns.h +++ b/contrib/gcc/cp/cfns.h @@ -1,6 +1,5 @@ -/* C code produced by gperf version 2.7.2 */ -/* Command-line: gperf -o -C -E -k '1-6,$' -j1 -D -N libc_name_p /FBSD/src/gnu/usr.bin/cc/cc1plus/../../../../contrib/gcc/cp/cfns.gperf */ -/* $FreeBSD$ */ +/* C code produced by gperf version 2.7 */ +/* Command-line: gperf -o -C -E -k 1-6,$ -j1 -D -N libc_name_p ../../../egcs-CVS20000404/gcc/cp/cfns.gperf */ #ifdef __GNUC__ __inline #endif @@ -13,10 +12,6 @@ const char * libc_name_p PARAMS ((const char *, unsigned int)); #ifdef __GNUC__ __inline -#else -#ifdef __cplusplus -inline -#endif #endif static unsigned int hash (str, len) diff --git a/contrib/gcc/cp/class.c b/contrib/gcc/cp/class.c index 2395d79..2ac4e30 100644 --- a/contrib/gcc/cp/class.c +++ b/contrib/gcc/cp/class.c @@ -945,6 +945,13 @@ add_method (type, method, error_p) && (TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms1))) != TYPE_QUALS (TREE_TYPE (TREE_VALUE (parms2))))) same = 0; + + /* For templates, the template parms must be identical. */ + if (TREE_CODE (fn) == TEMPLATE_DECL + && !comp_template_parms (DECL_TEMPLATE_PARMS (fn), + DECL_TEMPLATE_PARMS (method))) + same = 0; + if (! DECL_STATIC_FUNCTION_P (fn)) parms1 = TREE_CHAIN (parms1); if (! DECL_STATIC_FUNCTION_P (method)) @@ -1150,9 +1157,12 @@ handle_using_decl (using_decl, t) tree flist = NULL_TREE; tree old_value; - binfo = binfo_or_else (ctype, t); + binfo = lookup_base (t, ctype, ba_any, NULL); if (! binfo) - return; + { + error_not_base_type (t, ctype); + return; + } if (name == constructor_name (ctype) || name == constructor_name_full (ctype)) @@ -1338,6 +1348,8 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p, TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype); TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype); TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype); + CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) + |= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype); } } @@ -3237,10 +3249,18 @@ check_field_decls (t, access_decls, empty_p, ; else { + tree element_type; + /* The class is non-empty. */ *empty_p = 0; /* The class is not even nearly empty. */ CLASSTYPE_NEARLY_EMPTY_P (t) = 0; + /* If one of the data members contains an empty class, + so does T. */ + element_type = strip_array_types (type); + if (CLASS_TYPE_P (element_type) + && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type)) + CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1; } } @@ -3322,7 +3342,7 @@ check_field_decls (t, access_decls, empty_p, { CLASSTYPE_NON_POD_P (t) = 1; if (DECL_INITIAL (x) == NULL_TREE) - CLASSTYPE_REF_FIELDS_NEED_INIT (t) = 1; + SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1); /* ARM $12.6.2: [A member initializer list] (or, for an aggregate, initialization by a brace-enclosed list) is the @@ -3356,7 +3376,7 @@ check_field_decls (t, access_decls, empty_p, { C_TYPE_FIELDS_READONLY (t) = 1; if (DECL_INITIAL (x) == NULL_TREE) - CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) = 1; + SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1); /* ARM $12.6.2: [A member initializer list] (or, for an aggregate, initialization by a brace-enclosed list) is the @@ -3372,8 +3392,9 @@ check_field_decls (t, access_decls, empty_p, else if (IS_AGGR_TYPE (type)) { C_TYPE_FIELDS_READONLY (t) |= C_TYPE_FIELDS_READONLY (type); - CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) - |= CLASSTYPE_READONLY_FIELDS_NEED_INIT (type); + SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, + CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) + | CLASSTYPE_READONLY_FIELDS_NEED_INIT (type)); } /* Core issue 80: A nonstatic data member is required to have a @@ -3507,6 +3528,10 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p) tree field; int i; + /* Avoid recursing into objects that are not interesting. */ + if (!CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type)) + return 0; + /* Record the location of TYPE. */ r = (*f) (type, offset, offsets); if (r) @@ -3552,9 +3577,15 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p) } else if (TREE_CODE (type) == ARRAY_TYPE) { + tree element_type = strip_array_types (type); tree domain = TYPE_DOMAIN (type); tree index; + /* Avoid recursing into objects that are not interesting. */ + if (!CLASS_TYPE_P (element_type) + || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type)) + return 0; + /* Step through each of the elements in the array. */ for (index = size_zero_node; INT_CST_LT (index, TYPE_MAX_VALUE (domain)); @@ -4267,6 +4298,7 @@ check_bases_and_members (t, empty_p) /* Assume that the class is nearly empty; we'll clear this flag if it turns out not to be nearly empty. */ CLASSTYPE_NEARLY_EMPTY_P (t) = 1; + CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 0; /* Check all the base-classes. */ check_bases (t, &cant_have_default_ctor, &cant_have_const_ctor, @@ -4974,6 +5006,10 @@ layout_class_type (t, empty_p, vfuns_p, virtuals_p) CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t); CLASSTYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (t); + /* Every empty class contains an empty class. */ + if (*empty_p) + CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1; + /* Set the TYPE_DECL for this type to contain the right value for DECL_OFFSET, so that we can use it as part of a COMPONENT_REF for multiple inheritance. */ diff --git a/contrib/gcc/cp/cp-lang.c b/contrib/gcc/cp/cp-lang.c index b573cce..1464ef6 100644 --- a/contrib/gcc/cp/cp-lang.c +++ b/contrib/gcc/cp/cp-lang.c @@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */ static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree)); static tree cp_expr_size PARAMS ((tree)); +static bool cp_var_mod_type_p PARAMS ((tree)); #undef LANG_HOOKS_NAME #define LANG_HOOKS_NAME "GNU C++" @@ -84,6 +85,8 @@ static tree cp_expr_size PARAMS ((tree)); cp_copy_res_decl_for_inlining #undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P #define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P anon_aggr_type_p +#undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P +#define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P cp_var_mod_type_p #undef LANG_HOOKS_TREE_INLINING_START_INLINING #define LANG_HOOKS_TREE_INLINING_START_INLINING cp_start_inlining #undef LANG_HOOKS_TREE_INLINING_END_INLINING @@ -130,3 +133,21 @@ cp_expr_size (exp) /* Use the default code. */ return lhd_expr_size (exp); } + +/* Returns true if T is a variably modified type, in the sense of C99. + This routine needs only check cases that cannot be handled by the + language-independent logic in tree-inline.c. */ + +static bool +cp_var_mod_type_p (tree type) +{ + /* If TYPE is a pointer-to-member, it is variably modified if either + the class or the member are variably modified. */ + if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type)) + return (variably_modified_type_p (TYPE_PTRMEM_CLASS_TYPE (type)) + || variably_modified_type_p (TYPE_PTRMEM_POINTED_TO_TYPE (type))); + + /* All other types are not variably modified. */ + return false; +} + diff --git a/contrib/gcc/cp/cp-tree.h b/contrib/gcc/cp/cp-tree.h index 4bd0879..9e8199f 100644 --- a/contrib/gcc/cp/cp-tree.h +++ b/contrib/gcc/cp/cp-tree.h @@ -1251,6 +1251,7 @@ struct lang_type unsigned java_interface : 1; unsigned non_zero_init : 1; + unsigned contains_empty_class_p : 1; /* When adding a flag here, consider whether or not it ought to apply to a template instance if it applies to the template. If @@ -1259,7 +1260,7 @@ struct lang_type /* There are some bits left to fill out a 32-bit word. Keep track of this by updating the size of this bitfield whenever you add or remove a flag. */ - unsigned dummy : 7; + unsigned dummy : 6; int vsize; @@ -1520,6 +1521,10 @@ struct lang_type #define CLASSTYPE_NEARLY_EMPTY_P(NODE) \ (TYPE_LANG_SPECIFIC (NODE)->nearly_empty_p) +/* Nonzero if this class contains an empty subobject. */ +#define CLASSTYPE_CONTAINS_EMPTY_CLASS_P(NODE) \ + (TYPE_LANG_SPECIFIC (NODE)->contains_empty_class_p) + /* A list of class types of which this type is a friend. The TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the case of a template friend. */ @@ -1534,13 +1539,21 @@ struct lang_type #define CLASSTYPE_DECLARED_CLASS(NODE) \ (TYPE_LANG_SPECIFIC (NODE)->declared_class) -/* Nonzero if this class has const members which have no specified initialization. */ -#define CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE) \ - (TYPE_LANG_SPECIFIC (NODE)->const_needs_init) - -/* Nonzero if this class has ref members which have no specified initialization. */ -#define CLASSTYPE_REF_FIELDS_NEED_INIT(NODE) \ - (TYPE_LANG_SPECIFIC (NODE)->ref_needs_init) +/* Nonzero if this class has const members + which have no specified initialization. */ +#define CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE) \ + (TYPE_LANG_SPECIFIC (NODE) \ + ? TYPE_LANG_SPECIFIC (NODE)->const_needs_init : 0) +#define SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE, VALUE) \ + (TYPE_LANG_SPECIFIC (NODE)->const_needs_init = (VALUE)) + +/* Nonzero if this class has ref members + which have no specified initialization. */ +#define CLASSTYPE_REF_FIELDS_NEED_INIT(NODE) \ + (TYPE_LANG_SPECIFIC (NODE) \ + ? TYPE_LANG_SPECIFIC (NODE)->ref_needs_init : 0) +#define SET_CLASSTYPE_REF_FIELDS_NEED_INIT(NODE, VALUE) \ + (TYPE_LANG_SPECIFIC (NODE)->ref_needs_init = (VALUE)) /* Nonzero if this class is included from a header file which employs `#pragma interface', and it is not included in its implementation file. */ diff --git a/contrib/gcc/cp/cvt.c b/contrib/gcc/cp/cvt.c index 9b4f68f..5e6c92c 100644 --- a/contrib/gcc/cp/cvt.c +++ b/contrib/gcc/cp/cvt.c @@ -464,12 +464,13 @@ convert_to_reference (reftype, expr, convtype, flags, decl) tree decl; { register tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype)); - register tree intype = TREE_TYPE (expr); + register tree intype; tree rval = NULL_TREE; tree rval_as_conversion = NULL_TREE; int i; - if (TREE_CODE (type) == FUNCTION_TYPE && intype == unknown_type_node) + if (TREE_CODE (type) == FUNCTION_TYPE + && TREE_TYPE (expr) == unknown_type_node) { expr = instantiate_type (type, expr, (flags & LOOKUP_COMPLAIN) @@ -479,6 +480,11 @@ convert_to_reference (reftype, expr, convtype, flags, decl) intype = TREE_TYPE (expr); } + else + { + expr = convert_from_reference (expr); + intype = TREE_TYPE (expr); + } my_friendly_assert (TREE_CODE (intype) != REFERENCE_TYPE, 364); diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c index 26484d7..06b081c 100644 --- a/contrib/gcc/cp/decl.c +++ b/contrib/gcc/cp/decl.c @@ -3500,7 +3500,6 @@ duplicate_decls (newdecl, olddecl) except for any that we copy here from the old type. */ DECL_ATTRIBUTES (newdecl) = (*targetm.merge_decl_attributes) (olddecl, newdecl); - decl_attributes (&newdecl, DECL_ATTRIBUTES (newdecl), 0); if (TREE_CODE (newdecl) == TEMPLATE_DECL) { @@ -5760,6 +5759,12 @@ make_typename_type (context, name, complain) t = lookup_field (context, name, 0, 1); if (t) { + if (TREE_CODE (t) != TYPE_DECL) + { + if (complain & tf_error) + error ("no type named `%#T' in `%#T'", name, context); + return error_mark_node; + } if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl)) t = TREE_TYPE (t); if (IMPLICIT_TYPENAME_P (t)) @@ -7328,7 +7333,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) switch (TREE_CODE (decl)) { case TYPE_DECL: - error ("typedef `%D' is initialized", decl); + error ("typedef `%D' is initialized (use __typeof__ instead)", decl); initialized = 0; break; @@ -8026,6 +8031,12 @@ maybe_inject_for_scope_var (decl) { if (!DECL_NAME (decl)) return; + + /* Declarations of __FUNCTION__ and its ilk appear magically when + the variable is first used. If that happens to be inside a + for-loop, we don't want to do anything special. */ + if (DECL_PRETTY_FUNCTION_P (decl)) + return; if (current_binding_level->is_for_scope) { @@ -10060,6 +10071,16 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) next = 0; break; + case TEMPLATE_DECL: + /* Sometimes, we see a template-name used as part of a + decl-specifier like in + std::allocator alloc; + Handle that gracefully. */ + error ("invalid use of template-name '%E' in a declarator", + decl); + return error_mark_node; + break; + default: internal_error ("`%D' as declarator", decl); } @@ -10700,19 +10721,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) type = create_array_type_for_decl (dname, type, size); - /* VLAs never work as fields. */ - if (decl_context == FIELD && !processing_template_decl - && TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) != NULL_TREE - && !TREE_CONSTANT (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))) - { - error ("size of member `%D' is not constant", dname); - /* Proceed with arbitrary constant size, so that offset - computations don't get confused. */ - type = create_array_type_for_decl (dname, TREE_TYPE (type), - integer_one_node); - } - ctype = NULL_TREE; } break; @@ -11019,8 +11027,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) pop_decl_namespace (); else if (friendp && (TREE_COMPLEXITY (declarator) < 2)) /* Don't fall out into global scope. Hides real bug? --eichin */ ; - else if (! IS_AGGR_TYPE_CODE - (TREE_CODE (TREE_OPERAND (declarator, 0)))) + else if (!TREE_OPERAND (declarator, 0) + || !IS_AGGR_TYPE_CODE + (TREE_CODE (TREE_OPERAND (declarator, 0)))) ; else if (TREE_COMPLEXITY (declarator) == current_class_depth) { @@ -11200,6 +11209,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) type = error_mark_node; } + if (decl_context == FIELD + && !processing_template_decl + && variably_modified_type_p (type)) + { + error ("data member may not have variably modified type `%T'", type); + type = error_mark_node; + } + if (explicitp == 1 || (explicitp && friendp)) { /* [dcl.fct.spec] The explicit specifier shall only be used in @@ -14101,6 +14118,10 @@ finish_destructor_body () { tree exprstmt; + /* Any return from a destructor will end up here; that way all base + and member cleanups will be run when the function returns. */ + add_stmt (build_stmt (LABEL_STMT, dtor_label)); + /* And perform cleanups for our bases and members. */ perform_base_cleanups (); @@ -14176,14 +14197,7 @@ void finish_function_body (compstmt) tree compstmt; { - if (processing_template_decl) - /* Do nothing now. */; - else if (DECL_DESTRUCTOR_P (current_function_decl)) - /* Any return from a destructor will end up here. Put it before the - cleanups so that an explicit return doesn't duplicate them. */ - add_stmt (build_stmt (LABEL_STMT, dtor_label)); - - /* Close the block; in a destructor, run the member cleanups. */ + /* Close the block. */ finish_compound_stmt (0, compstmt); if (processing_template_decl) diff --git a/contrib/gcc/cp/decl2.c b/contrib/gcc/cp/decl2.c index 4334963..730bbfb 100644 --- a/contrib/gcc/cp/decl2.c +++ b/contrib/gcc/cp/decl2.c @@ -1519,7 +1519,13 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist) /* friend or constructor went bad. */ return value; if (TREE_TYPE (value) == error_mark_node) - return error_mark_node; + return error_mark_node; + + if (TREE_CODE (value) == TYPE_DECL && init) + { + error ("typedef `%D' is initialized (use __typeof__ instead)", value); + init = NULL_TREE; + } /* Pass friendly classes back. */ if (TREE_CODE (value) == VOID_TYPE) @@ -3795,10 +3801,8 @@ build_expr_from_tree (t) case ALIGNOF_EXPR: { tree r = build_expr_from_tree (TREE_OPERAND (t, 0)); - if (!TYPE_P (r)) - return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r); - else - return TREE_CODE (t) == SIZEOF_EXPR ? c_sizeof (r) : c_alignof (r); + return (TREE_CODE (t) == SIZEOF_EXPR + ? finish_sizeof (r) : finish_alignof (r)); } case MODOP_EXPR: diff --git a/contrib/gcc/cp/init.c b/contrib/gcc/cp/init.c index a46d853..df63e67 100644 --- a/contrib/gcc/cp/init.c +++ b/contrib/gcc/cp/init.c @@ -348,6 +348,8 @@ build_field_list (t, list, uses_unions_p) { tree fields; + *uses_unions_p = 0; + /* Note whether or not T is a union. */ if (TREE_CODE (t) == UNION_TYPE) *uses_unions_p = 1; diff --git a/contrib/gcc/cp/lex.c b/contrib/gcc/cp/lex.c index d68957a..c40469c 100644 --- a/contrib/gcc/cp/lex.c +++ b/contrib/gcc/cp/lex.c @@ -90,10 +90,11 @@ extern YYSTYPE yylval; /* the semantic value of the */ int warn_traditional = 0; int flag_digraphs = 1; -/* the declaration found for the last IDENTIFIER token read in. - yylex must look this up to detect typedefs, which get token type TYPENAME, - so it is left around in case the identifier is not a typedef but is - used in a context which makes it a reference to a variable. */ +/* the declaration found for the last IDENTIFIER token read in. yylex + must look this up to detect typedefs, which get token type + tTYPENAME, so it is left around in case the identifier is not a + typedef but is used in a context which makes it a reference to a + variable. */ tree lastiddecl; /* Array for holding counts of the numbers of tokens seen. */ @@ -739,7 +740,7 @@ yyprint (file, yychar, yylval) switch (yychar) { case IDENTIFIER: - case TYPENAME: + case tTYPENAME: case TYPESPEC: case PTYPENAME: case PFUNCNAME: @@ -977,7 +978,7 @@ check_for_missing_semicolon (type) if ((yychar > 255 && yychar != SCSPEC && yychar != IDENTIFIER - && yychar != TYPENAME + && yychar != tTYPENAME && yychar != CV_QUALIFIER && yychar != SELFNAME) || yychar == 0 /* EOF */) @@ -1194,7 +1195,7 @@ do_identifier (token, parsing, args) tree args; { register tree id; - int lexing = (parsing == 1); + int lexing = (parsing == 1 || parsing == 3); if (! lexing) id = lookup_name (token, 0); @@ -1216,7 +1217,7 @@ do_identifier (token, parsing, args) /* Remember that this name has been used in the class definition, as per [class.scope0] */ - if (id && parsing) + if (id && parsing && parsing != 3) maybe_note_name_used_in_class (token, id); if (id == error_mark_node) diff --git a/contrib/gcc/cp/mangle.c b/contrib/gcc/cp/mangle.c index ba312b7..10f2b62 100644 --- a/contrib/gcc/cp/mangle.c +++ b/contrib/gcc/cp/mangle.c @@ -93,6 +93,13 @@ static struct globals /* An array of the current substitution candidates, in the order we've seen them. */ varray_type substitutions; + + /* The entity that is being mangled. */ + tree entity; + + /* True if the mangling will be different in a future version of the + ABI. */ + bool need_abi_warning; } G; /* Indices into subst_identifiers. These are identifiers used in @@ -186,8 +193,8 @@ static const char *mangle_decl_string PARAMS ((tree)); /* Control functions. */ -static inline void start_mangling PARAMS ((void)); -static inline const char *finish_mangling PARAMS ((void)); +static inline void start_mangling PARAMS ((tree)); +static inline const char *finish_mangling PARAMS ((bool)); static tree mangle_special_for_type PARAMS ((tree, const char *)); /* Foreign language functions. */ @@ -884,6 +891,10 @@ write_prefix (node) template_info = CLASSTYPE_TEMPLATE_INFO (node); } + /* In G++ 3.2, the name of the template parameter was used. */ + if (TREE_CODE (node) == TEMPLATE_TYPE_PARM) + G.need_abi_warning = true; + if (template_info != NULL) /* Templated. */ { @@ -955,6 +966,10 @@ write_template_prefix (node) if (find_substitution (substitution)) return; + /* In G++ 3.2, the name of the template template parameter was used. */ + if (TREE_CODE (TREE_TYPE (template)) == TEMPLATE_TEMPLATE_PARM) + G.need_abi_warning = true; + write_prefix (context); write_unqualified_name (decl); @@ -1823,6 +1838,10 @@ write_expression (expr) write_template_arg_literal (expr); else if (DECL_P (expr)) { + /* G++ 3.2 incorrectly mangled non-type template arguments of + enumeration type using their names. */ + if (code == CONST_DECL) + G.need_abi_warning = 1; write_char ('L'); write_mangled_name (expr); write_char ('E'); @@ -1878,7 +1897,12 @@ write_expression (expr) if (TREE_CODE (TREE_OPERAND (expr, 1)) == IDENTIFIER_NODE) write_source_name (TREE_OPERAND (expr, 1)); else - write_encoding (TREE_OPERAND (expr, 1)); + { + /* G++ 3.2 incorrectly put out both the "sr" code and + the nested name of the qualified name. */ + G.need_abi_warning = 1; + write_encoding (TREE_OPERAND (expr, 1)); + } break; default: @@ -1983,6 +2007,10 @@ write_template_arg (node) write_template_template_arg (node); else if (DECL_P (node)) { + /* G++ 3.2 incorrectly mangled non-type template arguments of + enumeration type using their names. */ + if (code == CONST_DECL) + G.need_abi_warning = 1; write_char ('L'); write_char ('Z'); write_encoding (node); @@ -2152,16 +2180,23 @@ write_substitution (seq_id) /* Start mangling a new name or type. */ static inline void -start_mangling () +start_mangling (tree entity) { + G.entity = entity; + G.need_abi_warning = false; obstack_free (&G.name_obstack, obstack_base (&G.name_obstack)); } /* Done with mangling. Return the generated mangled name. */ static inline const char * -finish_mangling () +finish_mangling (bool warn) { + if (warn_abi && warn && G.need_abi_warning) + warning ("the mangled name of `%D' will change in a future " + "version of GCC", + G.entity); + /* Clear all the substitutions. */ VARRAY_POP_ALL (G.substitutions); @@ -2197,7 +2232,7 @@ mangle_decl_string (decl) { const char *result; - start_mangling (); + start_mangling (decl); if (TREE_CODE (decl) == TYPE_DECL) write_type (TREE_TYPE (decl)); @@ -2224,7 +2259,7 @@ mangle_decl_string (decl) write_string (" *INTERNAL* "); } - result = finish_mangling (); + result = finish_mangling (/*warn=*/true); if (DEBUG_MANGLE) fprintf (stderr, "mangle_decl_string = '%s'\n\n", result); return result; @@ -2249,9 +2284,9 @@ mangle_type_string (type) { const char *result; - start_mangling (); + start_mangling (type); write_type (type); - result = finish_mangling (); + result = finish_mangling (/*warn=*/false); if (DEBUG_MANGLE) fprintf (stderr, "mangle_type_string = '%s'\n\n", result); return result; @@ -2279,7 +2314,7 @@ mangle_special_for_type (type, code) /* We don't have an actual decl here for the special component, so we can't just process the <encoded-name>. Instead, fake it. */ - start_mangling (); + start_mangling (type); /* Start the mangling. */ write_string ("_Z"); @@ -2287,7 +2322,7 @@ mangle_special_for_type (type, code) /* Add the type. */ write_type (type); - result = finish_mangling (); + result = finish_mangling (/*warn=*/false); if (DEBUG_MANGLE) fprintf (stderr, "mangle_special_for_type = %s\n\n", result); @@ -2354,7 +2389,7 @@ mangle_ctor_vtbl_for_type (type, binfo) { const char *result; - start_mangling (); + start_mangling (type); write_string ("_Z"); write_string ("TC"); @@ -2363,7 +2398,7 @@ mangle_ctor_vtbl_for_type (type, binfo) write_char ('_'); write_type (BINFO_TYPE (binfo)); - result = finish_mangling (); + result = finish_mangling (/*warn=*/false); if (DEBUG_MANGLE) fprintf (stderr, "mangle_ctor_vtbl_for_type = %s\n\n", result); return get_identifier (result); @@ -2387,7 +2422,7 @@ mangle_thunk (fn_decl, offset, vcall_offset) { const char *result; - start_mangling (); + start_mangling (fn_decl); write_string ("_Z"); /* The <special-name> for virtual thunks is Tv, for non-virtual @@ -2413,7 +2448,7 @@ mangle_thunk (fn_decl, offset, vcall_offset) /* Scoped name. */ write_encoding (fn_decl); - result = finish_mangling (); + result = finish_mangling (/*warn=*/false); if (DEBUG_MANGLE) fprintf (stderr, "mangle_thunk = %s\n\n", result); return get_identifier (result); @@ -2454,7 +2489,7 @@ tree mangle_guard_variable (variable) tree variable; { - start_mangling (); + start_mangling (variable); write_string ("_ZGV"); if (strncmp (IDENTIFIER_POINTER (DECL_NAME (variable)), "_ZGR", 4) == 0) /* The name of a guard variable for a reference temporary should refer @@ -2462,7 +2497,7 @@ mangle_guard_variable (variable) write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4); else write_name (variable, /*ignore_local_scope=*/0); - return get_identifier (finish_mangling ()); + return get_identifier (finish_mangling (/*warn=*/false)); } /* Return an identifier for the name of a temporary variable used to @@ -2473,10 +2508,10 @@ tree mangle_ref_init_variable (variable) tree variable; { - start_mangling (); + start_mangling (variable); write_string ("_ZGR"); write_name (variable, /*ignore_local_scope=*/0); - return get_identifier (finish_mangling ()); + return get_identifier (finish_mangling (/*warn=*/false)); } diff --git a/contrib/gcc/cp/method.c b/contrib/gcc/cp/method.c index e4af0ab..5bb555d 100644 --- a/contrib/gcc/cp/method.c +++ b/contrib/gcc/cp/method.c @@ -688,7 +688,7 @@ do_build_assign_ref (fndecl) comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field); init = build (COMPONENT_REF, - build_qualified_type (TREE_TYPE (field), cvquals), + cp_build_qualified_type (TREE_TYPE (field), cvquals), init, field); if (DECL_NAME (field)) diff --git a/contrib/gcc/cp/parse.y b/contrib/gcc/cp/parse.y index 6782621..5328ed3 100644 --- a/contrib/gcc/cp/parse.y +++ b/contrib/gcc/cp/parse.y @@ -253,7 +253,7 @@ cp_parse_init () /* All identifiers that are declared typedefs in the current block. In some contexts, they are treated just like IDENTIFIER, but they can also serve as typespecs in declarations. */ -%token TYPENAME +%token tTYPENAME %token SELFNAME /* A template function. */ @@ -315,7 +315,7 @@ cp_parse_init () %nonassoc IF %nonassoc ELSE -%left IDENTIFIER PFUNCNAME TYPENAME SELFNAME PTYPENAME SCSPEC TYPESPEC CV_QUALIFIER ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD ATTRIBUTE +%left IDENTIFIER PFUNCNAME tTYPENAME SELFNAME PTYPENAME SCSPEC TYPESPEC CV_QUALIFIER ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD ATTRIBUTE %left '{' ',' ';' @@ -345,7 +345,7 @@ cp_parse_init () %type <code> unop -%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist +%type <ttype> identifier IDENTIFIER tTYPENAME CONSTANT expr nonnull_exprlist %type <ttype> PFUNCNAME maybe_identifier %type <ttype> paren_expr_or_null nontrivial_exprlist SELFNAME %type <ttype> expr_no_commas expr_no_comma_rangle @@ -994,7 +994,7 @@ member_init: identifier: IDENTIFIER - | TYPENAME + | tTYPENAME | SELFNAME | PTYPENAME | NSNAME @@ -1031,17 +1031,21 @@ explicit_instantiation: { do_type_instantiation ($4.t, $1, 1); yyungetc (';', 1); } end_explicit_instantiation + {} | SCSPEC TEMPLATE begin_explicit_instantiation typed_declspecs declarator { tree specs = strip_attrs ($4.t); do_decl_instantiation (specs, $5, $1); } end_explicit_instantiation + {} | SCSPEC TEMPLATE begin_explicit_instantiation notype_declarator { do_decl_instantiation (NULL_TREE, $4, $1); } end_explicit_instantiation + {} | SCSPEC TEMPLATE begin_explicit_instantiation constructor_declarator { do_decl_instantiation (NULL_TREE, $4, $1); } end_explicit_instantiation + {} ; begin_explicit_instantiation: @@ -1060,7 +1064,7 @@ template_type: PTYPENAME '<' template_arg_list_opt template_close_bracket .finish_template_type { $$ = $5; } - | TYPENAME '<' template_arg_list_opt template_close_bracket + | tTYPENAME '<' template_arg_list_opt template_close_bracket .finish_template_type { $$ = $5; } | self_template_type @@ -1507,7 +1511,7 @@ do_id: don't do_identifier; we only do that for unqualified identifiers. */ if (!lastiddecl || TREE_CODE (lastiddecl) != TREE_LIST) - $$ = do_identifier ($<ttype>-1, 1, NULL_TREE); + $$ = do_identifier ($<ttype>-1, 3, NULL_TREE); else $$ = $<ttype>-1; } @@ -1532,7 +1536,7 @@ object_template_id: unqualified_id: notype_unqualified_id - | TYPENAME + | tTYPENAME | SELFNAME ; @@ -2767,7 +2771,7 @@ after_type_component_declarator0: after_type_declarator maybeasm maybe_attribute maybe_init { $$ = parse_field0 ($1, $<ftype>0.t, $<ftype>0.lookups, $3, $2, $4); } - | TYPENAME ':' expr_no_commas maybe_attribute + | tTYPENAME ':' expr_no_commas maybe_attribute { $$ = parse_bitfield0 ($1, $<ftype>0.t, $<ftype>0.lookups, $4, $3); } ; @@ -2790,7 +2794,7 @@ notype_component_declarator0: after_type_component_declarator: after_type_declarator maybeasm maybe_attribute maybe_init { $$ = parse_field ($1, $3, $2, $4); } - | TYPENAME ':' expr_no_commas maybe_attribute + | tTYPENAME ':' expr_no_commas maybe_attribute { $$ = parse_bitfield ($1, $4, $3); } ; @@ -3062,7 +3066,7 @@ functional_cast: ; type_name: - TYPENAME + tTYPENAME | SELFNAME | template_type %prec EMPTY ; @@ -3086,7 +3090,7 @@ nested_name_specifier: /* Why the @#$%^& do type_name and notype_identifier need to be expanded inline here?!? (jason) */ nested_name_specifier_1: - TYPENAME SCOPE + tTYPENAME SCOPE { if (TREE_CODE ($1) == IDENTIFIER_NODE) { @@ -3172,7 +3176,7 @@ typename_sub1: /* This needs to return a TYPE_DECL for simple names so that we don't forget what name was used. */ typename_sub2: - TYPENAME SCOPE + tTYPENAME SCOPE { if (TREE_CODE ($1) != TYPE_DECL) $$ = lastiddecl; @@ -3610,7 +3614,7 @@ label_colon: { finish_label_stmt ($1); } | PTYPENAME ':' { finish_label_stmt ($1); } - | TYPENAME ':' + | tTYPENAME ':' { finish_label_stmt ($1); } | SELFNAME ':' { finish_label_stmt ($1); } diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c index 8fc9f74..b8e9545 100644 --- a/contrib/gcc/cp/pt.c +++ b/contrib/gcc/cp/pt.c @@ -3430,6 +3430,16 @@ convert_template_argument (parm, arg, args, complain, i, in_decl) val, t); return error_mark_node; } + + /* In order to avoid all sorts of complications, we do + not allow variably-modified types as template + arguments. */ + if (variably_modified_type_p (val)) + { + error ("template-argument `%T' is a variably modified type", + val); + return error_mark_node; + } } } } diff --git a/contrib/gcc/cp/rtti.c b/contrib/gcc/cp/rtti.c index ae23234..39cb1c6 100644 --- a/contrib/gcc/cp/rtti.c +++ b/contrib/gcc/cp/rtti.c @@ -1413,11 +1413,13 @@ unemitted_tinfo_decl_p (t, data) TREE_CODE (t) == VAR_DECL /* whos name points back to itself */ && IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == t - /* whos name's type is non-null */ + /* whose name's type is non-null */ && TREE_TYPE (DECL_NAME (t)) - /* and whos type is a struct */ + /* and whose type is a struct */ && TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE - /* with a first field of our pseudo type info */ + /* with a field */ + && TYPE_FIELDS (TREE_TYPE (t)) + /* which is our pseudo type info */ && TREE_TYPE (TYPE_FIELDS (TREE_TYPE (t))) == ti_desc_type_node) return 1; return 0; diff --git a/contrib/gcc/cp/semantics.c b/contrib/gcc/cp/semantics.c index 43d3074..a484203 100644 --- a/contrib/gcc/cp/semantics.c +++ b/contrib/gcc/cp/semantics.c @@ -2117,7 +2117,7 @@ finish_alignof (t) if (processing_template_decl) return build_min_nt (ALIGNOF_EXPR, t); - return TYPE_P (t) ? c_alignof (t) : c_alignof_expr (t); + return TYPE_P (t) ? c_alignof (complete_type (t)) : c_alignof_expr (t); } /* Generate RTL for the statement T, and its substatements, and any diff --git a/contrib/gcc/cp/spew.c b/contrib/gcc/cp/spew.c index 212dada..278a99a 100644 --- a/contrib/gcc/cp/spew.c +++ b/contrib/gcc/cp/spew.c @@ -115,6 +115,7 @@ static SPEW_INLINE int read_process_identifier PARAMS ((YYSTYPE *)); static SPEW_INLINE void feed_input PARAMS ((struct unparsed_text *)); static SPEW_INLINE void snarf_block PARAMS ((const char *, int)); static tree snarf_defarg PARAMS ((void)); +static void snarf_parenthesized_expression PARAMS ((const char *, int)); static int frob_id PARAMS ((int, int, tree *)); /* The list of inline functions being held off until we reach the end of @@ -141,10 +142,11 @@ static enum cpp_ttype last_token; static tree last_token_id; /* From lex.c: */ -/* the declaration found for the last IDENTIFIER token read in. - yylex must look this up to detect typedefs, which get token type TYPENAME, - so it is left around in case the identifier is not a typedef but is - used in a context which makes it a reference to a variable. */ +/* the declaration found for the last IDENTIFIER token read in. yylex + must look this up to detect typedefs, which get token type + tTYPENAME, so it is left around in case the identifier is not a + typedef but is used in a context which makes it a reference to a + variable. */ extern tree lastiddecl; /* let our brains leak out here too */ extern int yychar; /* the lookahead symbol */ extern YYSTYPE yylval; /* the semantic value of the */ @@ -483,9 +485,8 @@ add_token (t) memcpy (t, feed->input->pos, sizeof (struct token)); return (feed->input->pos++)->yychar; } - - memcpy (t, &Teosi, sizeof (struct token)); - return END_OF_SAVED_INPUT; + + return 0; } /* Shift the next token onto the fifo. */ @@ -628,11 +629,11 @@ identifier_type (decl) if (t && t == decl) return SELFNAME; - return TYPENAME; + return tTYPENAME; } /* token[0] == AGGR (struct/union/enum) - Thus, token[1] is either a TYPENAME or a TYPENAME_DEFN. + Thus, token[1] is either a tTYPENAME or a TYPENAME_DEFN. If token[2] == '{' or ':' then it's TYPENAME_DEFN. It's also a definition if it's a forward declaration (as in 'struct Foo;') which we can tell if token[2] == ';' *and* token[-1] != FRIEND or NEW. */ @@ -644,7 +645,7 @@ do_aggr () scan_tokens (2); yc1 = nth_token (1)->yychar; - if (yc1 != TYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME) + if (yc1 != tTYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME) return; yc2 = nth_token (2)->yychar; if (yc2 == ';') @@ -659,7 +660,7 @@ do_aggr () switch (yc1) { - case TYPENAME: + case tTYPENAME: nth_token (1)->yychar = TYPENAME_DEFN; break; case PTYPENAME: @@ -757,7 +758,7 @@ yylex () break; } case IDENTIFIER_DEFN: - case TYPENAME: + case tTYPENAME: case TYPENAME_DEFN: case PTYPENAME: case PTYPENAME_DEFN: @@ -897,7 +898,7 @@ frob_id (yyc, peek, idp) yyc = identifier_type (trrr); switch(yyc) { - case TYPENAME: + case tTYPENAME: case SELFNAME: case NSNAME: case PTYPENAME: @@ -1031,6 +1032,38 @@ process_next_inline (i) } +/* Accumulate the tokens that make up a parenthesized expression in T, + having already read the opening parenthesis. */ + +static void +snarf_parenthesized_expression (starting_file, starting_line) + const char *starting_file; + int starting_line; +{ + int yyc; + int level = 1; + + while (1) + { + size_t point; + + point = obstack_object_size (&inline_text_obstack); + obstack_blank (&inline_text_obstack, sizeof (struct token)); + yyc = add_token ((struct token *) + (obstack_base (&inline_text_obstack) + point)); + if (yyc == '(') + ++level; + else if (yyc == ')' && --level == 0) + break; + else if (yyc == 0) + { + error_with_file_and_line (starting_file, starting_line, + "end of file read inside definition"); + break; + } + } +} + /* Subroutine of snarf_method, deals with actual absorption of the block. */ static SPEW_INLINE void @@ -1113,6 +1146,8 @@ snarf_block (starting_file, starting_line) else if (look_for_semicolon && blev == 0) break; } + else if (yyc == '(' && blev == 0) + snarf_parenthesized_expression (starting_file, starting_line); else if (yyc == 0) { error_with_file_and_line (starting_file, starting_line, @@ -1131,12 +1166,27 @@ snarf_method (decl) int starting_lineno = lineno; const char *starting_filename = input_filename; size_t len; + int i; struct unparsed_text *meth; /* Leave room for the header, then absorb the block. */ obstack_blank (&inline_text_obstack, sizeof (struct unparsed_text)); snarf_block (starting_filename, starting_lineno); + /* Add three END_OF_SAVED_INPUT tokens. We used to provide an + infinite stream of END_OF_SAVED_INPUT tokens -- but that can + cause the compiler to get stuck in an infinite loop when + encountering invalid code. We need more than one because the + parser sometimes peeks ahead several tokens. */ + for (i = 0; i < 3; ++i) + { + size_t point = obstack_object_size (&inline_text_obstack); + obstack_blank (&inline_text_obstack, sizeof (struct token)); + memcpy ((struct token *) + (obstack_base (&inline_text_obstack) + point), + &Teosi, + sizeof (struct token)); + } len = obstack_object_size (&inline_text_obstack); meth = (struct unparsed_text *) obstack_finish (&inline_text_obstack); @@ -1187,6 +1237,7 @@ snarf_defarg () size_t point; size_t len; struct unparsed_text *buf; + int i; tree arg; obstack_blank (&inline_text_obstack, sizeof (struct unparsed_text)); @@ -1216,6 +1267,20 @@ snarf_defarg () push_token ((struct token *) (obstack_base (&inline_text_obstack) + point)); /* This is the documented way to shrink a growing obstack block. */ obstack_blank (&inline_text_obstack, - (int) sizeof (struct token)); + /* Add three END_OF_SAVED_INPUT tokens. We used to provide an + infinite stream of END_OF_SAVED_INPUT tokens -- but that can + cause the compiler to get stuck in an infinite loop when + encountering invalid code. We need more than one because the + parser sometimes peeks ahead several tokens. */ + for (i = 0; i < 3; ++i) + { + point = obstack_object_size (&inline_text_obstack); + obstack_blank (&inline_text_obstack, sizeof (struct token)); + memcpy ((struct token *) + (obstack_base (&inline_text_obstack) + point), + &Teosi, + sizeof (struct token)); + } done: len = obstack_object_size (&inline_text_obstack); @@ -1448,7 +1513,7 @@ debug_yychar (yy) { if (yy<256) fprintf (stderr, "->%d < %c >\n", lineno, yy); - else if (yy == IDENTIFIER || yy == TYPENAME) + else if (yy == IDENTIFIER || yy == tTYPENAME) { const char *id; if (TREE_CODE (yylval.ttype) == IDENTIFIER_NODE) diff --git a/contrib/gcc/cp/tree.c b/contrib/gcc/cp/tree.c index 748ab9a..65dca00 100644 --- a/contrib/gcc/cp/tree.c +++ b/contrib/gcc/cp/tree.c @@ -1903,19 +1903,19 @@ pod_type_p (t) int zero_init_p (t) - tree t; + tree t ATTRIBUTE_UNUSED; { - t = strip_array_types (t); - - /* NULL pointers to data members are initialized with -1. */ - if (TYPE_PTRMEM_P (t)) - return 0; + /* This is not a correct implementation of this function. As a + result, pointers-to-members will not be correctly + zero-initialized. - /* Classes that contain types that can't be zero-initialized, cannot - be zero-initialized themselves. */ - if (CLASS_TYPE_P (t) && CLASSTYPE_NON_ZERO_INIT_P (t)) - return 0; + However, using a correct implementation of this function results + in many other failures. Correcting these other failures required + a major infrastructure improvement, which was undertaken in the + GCC 3.3 source base. + In order to reduce risk, these changes were not ported to the GCC + 3.2 source base. */ return 1; } diff --git a/contrib/gcc/cp/typeck.c b/contrib/gcc/cp/typeck.c index d326969..b019d0a 100644 --- a/contrib/gcc/cp/typeck.c +++ b/contrib/gcc/cp/typeck.c @@ -4167,6 +4167,25 @@ build_x_unary_op (code, xarg) } if (code == ADDR_EXPR) { + /* A pointer to member-function can be formed only by saying + &X::mf. */ + if (!flag_ms_extensions && TREE_CODE (TREE_TYPE (xarg)) == METHOD_TYPE + && (TREE_CODE (xarg) != OFFSET_REF || !PTRMEM_OK_P (xarg))) + { + if (TREE_CODE (xarg) != OFFSET_REF) + { + error ("invalid use of '%E' to form a pointer-to-member-function. Use a qualified-id.", + xarg); + return error_mark_node; + } + else + { + error ("parenthesis around '%E' cannot be used to form a pointer-to-member-function", + xarg); + PTRMEM_OK_P (xarg) = 1; + } + } + if (TREE_CODE (xarg) == OFFSET_REF) { ptrmem = PTRMEM_OK_P (xarg); diff --git a/contrib/gcc/cp/typeck2.c b/contrib/gcc/cp/typeck2.c index d3febeb..f8e612b 100644 --- a/contrib/gcc/cp/typeck2.c +++ b/contrib/gcc/cp/typeck2.c @@ -863,8 +863,7 @@ process_init_constructor (type, init, elts) { if (TREE_READONLY (field)) error ("uninitialized const member `%D'", field); - else if (TYPE_LANG_SPECIFIC (TREE_TYPE (field)) - && CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field))) + else if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field))) error ("member `%D' with uninitialized const fields", field); else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE) @@ -976,6 +975,8 @@ process_init_constructor (type, init, elts) return error_mark_node; result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (members)); + if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE) + complete_array_type (type, result, /*do_default=*/0); if (init) TREE_HAS_CONSTRUCTOR (result) = TREE_HAS_CONSTRUCTOR (init); if (allconstant) TREE_CONSTANT (result) = 1; |