diff options
author | kan <kan@FreeBSD.org> | 2003-08-22 02:56:07 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2003-08-22 02:56:07 +0000 |
commit | 61e519ea39ae3e7da7754ac55be8c0443ae420e2 (patch) | |
tree | d9ba6250139a4332cf27a501e45674c8157f1642 /contrib/gcc/cp | |
parent | 6ff48acf086d689c2d10a6aecf71e05a04658ff5 (diff) | |
parent | 08db0e4d745472adc9c30de407304713c78e950e (diff) | |
download | FreeBSD-src-61e519ea39ae3e7da7754ac55be8c0443ae420e2.zip FreeBSD-src-61e519ea39ae3e7da7754ac55be8c0443ae420e2.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r119256,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib/gcc/cp')
-rw-r--r-- | contrib/gcc/cp/ChangeLog | 102 | ||||
-rw-r--r-- | contrib/gcc/cp/call.c | 31 | ||||
-rw-r--r-- | contrib/gcc/cp/class.c | 28 | ||||
-rw-r--r-- | contrib/gcc/cp/cp-tree.h | 23 | ||||
-rw-r--r-- | contrib/gcc/cp/init.c | 16 | ||||
-rw-r--r-- | contrib/gcc/cp/method.c | 2 | ||||
-rw-r--r-- | contrib/gcc/cp/parse.y | 23 | ||||
-rw-r--r-- | contrib/gcc/cp/pt.c | 53 | ||||
-rw-r--r-- | contrib/gcc/cp/search.c | 71 |
9 files changed, 275 insertions, 74 deletions
diff --git a/contrib/gcc/cp/ChangeLog b/contrib/gcc/cp/ChangeLog index 58bd155..854fefa 100644 --- a/contrib/gcc/cp/ChangeLog +++ b/contrib/gcc/cp/ChangeLog @@ -1,3 +1,105 @@ +2003-08-04 Release Manager + + * GCC 3.3.1 Released. + +2003-08-04 Release Manager + + * GCC 3.3.1 Released. + +2003-08-04 Mark Mitchell <mark@codesourcery.com> + + PR c++/11713 + * search.c (setup_class_bindings): Handle conversion operators + specially. + +2003-07-24 Alexandre Oliva <aoliva@redhat.com> + + PR c++/10796 + * decl.c (finish_enum): Make sure the underlying integer type has + the same precision as some full integer type. Reverts part + 2003-06-27's patch that didn't play any role in fixing the PR. + +2003-07-24 Mark Mitchell <mark@codesourcery.com> + + * cp-tree.h (convert_to_base_statically): Declare. + * call.c (build_special_member_call): Convert INSTANCE to the base + type. + * class.c (convert_to_base_statically): New method. + * init.c (construct_virtual_base): Use it. + * method.c (do_build_assign_ref): Fix typo in comment. + +2003-07-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/11513 + * cp-tree.h (PROCESSING_REAL_TEMPLATE_DECL_P): Use current_scope. + +2003-07-23 Mark Mitchell <mark@codesourcery.com> + + PR c++/11645 + * cp-tree.h (accessible_base_p): Declare. + * call.c (build_over_call): Use it. + * search.c (accessible_base_p): New function, split out from ... + (lookup_base): ... here. + +2003-07-23 Nathan Sidwell <nathan@codesourcery.com> + + PR c++/11282 + * decl.c: (reshape_init): Always advance *INITP. + +2003-07-19 Mark Mitchell <mark@codesourcery.com> + + PR c++/11546 + * pt.c (lookup_template_class): Treat TYPE_DECLs as TEMPLATE_DECLs + where appropriate. + +2003-07-14 Mark Mitchell <mark@codesourcery.com> + + PR c++/7053 + * pt.c (unregister_specialization): Rename to ... + (reregister_specialization): ... this. + (tsubst_friend_function): Use it. + (regenerate_decl_from_template): Likewise. + +2003-07-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> + + PR c++/11154 + * pt.c (more_specialized_class): Add full_args parameter. + (most_specialized_class): Adjust calls to more_specialized_class. + * cp-tree.h (more_specialized_class): Adjust declaration. + +2003-07-13 Mark Mitchell <mark@codesourcery.com> + + PR c++/11503 + * cp-tree.h (DECL_SELF_REFERENCE_P): New macro. + (SET_DECL_SELF_REFERENCE_P): Likewise. + * class.c (build_self_reference): Use SET_DECL_SELF_REFERENCE_P. + * pt.c (tsubst_decl): Copy it. + * search.c (lookup_base): Use DECL_SELF_REFERENCE_P. + +2003-07-11 Danny Smith <dannysmith@users.sourceforge.net> + + Backport from mainline. + + 2003-05-21 Danny Smith <dannysmith@users.sourceforge.net> + + PR c++/9738 + * decl.c (duplicate_decls): Re-invoke make_decl_rtl + if the old decl had instantiated DECL_RTL. + (Based on Richard Henderson 2003-05-13 patch to c-decl.c). + +2003-07-11 Mark Mitchell <mark@codesourcery.com> + + PR c++/8164 + * decl.c (duplicate_decls): Avoid mangling names unnecessarily. + +2003-07-10 Mark Mitchell <mark@codesourcery.com> + + PR c++/10558 + * parse.y (class_template_ok_as_expr): New variable. + (template_arg_1): New non-terminal. + (primary): Issue errors about uses of class templates as + expressions. + 2003-07-09 Mark Mitchell <mark@codesourcery.com> PR c++/10032 diff --git a/contrib/gcc/cp/call.c b/contrib/gcc/cp/call.c index ac7aeb8..8750128 100644 --- a/contrib/gcc/cp/call.c +++ b/contrib/gcc/cp/call.c @@ -4527,12 +4527,17 @@ build_over_call (cand, args, flags) TREE_VALUE (arg), cand->conversion_path, 1); + /* Check that the base class is accessible. */ + if (!accessible_base_p (TREE_TYPE (argtype), + BINFO_TYPE (cand->conversion_path))) + error ("`%T' is not an accessible base of `%T'", + BINFO_TYPE (cand->conversion_path), + TREE_TYPE (argtype)); /* If fn was found by a using declaration, the conversion path will be to the derived class, not the base declaring fn. We must convert from derived to base. */ base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)), TREE_TYPE (parmtype), ba_ignore, NULL); - converted_arg = build_base_path (PLUS_EXPR, converted_arg, base_binfo, 1); @@ -4857,11 +4862,23 @@ build_special_member_call (tree instance, tree name, tree args, TREE_TYPE (instance) = build_pointer_type (class_type); instance = build1 (INDIRECT_REF, class_type, instance); } - else if (name == complete_dtor_identifier - || name == base_dtor_identifier - || name == deleting_dtor_identifier) - my_friendly_assert (args == NULL_TREE, 20020712); + else + { + if (name == complete_dtor_identifier + || name == base_dtor_identifier + || name == deleting_dtor_identifier) + my_friendly_assert (args == NULL_TREE, 20020712); + /* We must perform the conversion here so that we do not + subsequently check to see whether BINFO is an accessible + base. (It is OK for a constructor to call a constructor in + an inaccessible base as long as the constructor being called + is accessible.) */ + if (!same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (instance), BINFO_TYPE (binfo))) + instance = convert_to_base_statically (instance, binfo); + } + my_friendly_assert (instance != NULL_TREE, 20020712); /* Resolve the name. */ @@ -4899,7 +4916,9 @@ build_special_member_call (tree instance, tree name, tree args, args = tree_cons (NULL_TREE, sub_vtt, args); } - return build_new_method_call (instance, fns, args, binfo, flags); + return build_new_method_call (instance, fns, args, + TYPE_BINFO (BINFO_TYPE (binfo)), + flags); } /* Build a call to "INSTANCE.FN (ARGS)". */ diff --git a/contrib/gcc/cp/class.c b/contrib/gcc/cp/class.c index 82eede5..c1da654 100644 --- a/contrib/gcc/cp/class.c +++ b/contrib/gcc/cp/class.c @@ -401,6 +401,33 @@ convert_to_base (tree object, tree type, bool check_access) return build_base_path (PLUS_EXPR, object, binfo, /*nonnull=*/1); } +/* EXPR is an expression with class type. BASE is a base class (a + BINFO) of that class type. Returns EXPR, converted to the BASE + type. This function assumes that EXPR is the most derived class; + therefore virtual bases can be found at their static offsets. */ + +tree +convert_to_base_statically (tree expr, tree base) +{ + tree expr_type; + + expr_type = TREE_TYPE (expr); + if (!same_type_p (expr_type, BINFO_TYPE (base))) + { + tree pointer_type; + + pointer_type = build_pointer_type (expr_type); + expr = build_unary_op (ADDR_EXPR, expr, /*noconvert=*/1); + if (!integer_zerop (BINFO_OFFSET (base))) + expr = build (PLUS_EXPR, pointer_type, expr, + build_nop (pointer_type, BINFO_OFFSET (base))); + expr = build_nop (build_pointer_type (BINFO_TYPE (base)), expr); + expr = build1 (INDIRECT_REF, BINFO_TYPE (base), expr); + } + + return expr; +} + /* Virtual function things. */ @@ -6537,6 +6564,7 @@ build_self_reference () DECL_NONLOCAL (value) = 1; DECL_CONTEXT (value) = current_class_type; DECL_ARTIFICIAL (value) = 1; + SET_DECL_SELF_REFERENCE_P (value); if (processing_template_decl) value = push_template_decl (value); diff --git a/contrib/gcc/cp/cp-tree.h b/contrib/gcc/cp/cp-tree.h index bfeec9b..9b529a8 100644 --- a/contrib/gcc/cp/cp-tree.h +++ b/contrib/gcc/cp/cp-tree.h @@ -98,6 +98,7 @@ struct diagnostic_context; 3: DECL_IN_AGGR_P. 4: DECL_C_BIT_FIELD (in a FIELD_DECL) DECL_VAR_MARKED_P (in a VAR_DECL) + DECL_SELF_REFERENCE_P (in a TYPE_DECL) 5: DECL_INTERFACE_KNOWN. 6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL). 7: DECL_DEAD_FOR_LOCAL (in VAR_DECL). @@ -2878,16 +2879,20 @@ struct lang_decl GTY(()) (TREE_CODE (NODE) == TYPE_DECL || DECL_CLASS_TEMPLATE_P (NODE)) /* Nonzero if NODE is the typedef implicitly generated for a type when - the type is declared. (In C++, `struct S {};' is roughly equivalent - to `struct S {}; typedef struct S S;' in C. This macro will hold - for the typedef indicated in this example. Note that in C++, there - is a second implicit typedef for each class, in the scope of `S' - itself, so that you can say `S::S'. This macro does *not* hold for - those typedefs. */ + the type is declared. In C++, `struct S {};' is roughly + equivalent to `struct S {}; typedef struct S S;' in C. + DECL_IMPLICIT_TYPEDEF_P will hold for the typedef indicated in this + example. In C++, there is a second implicit typedef for each + class, in the scope of `S' itself, so that you can say `S::S'. + DECL_SELF_REFERENCE_P will hold for that second typedef. */ #define DECL_IMPLICIT_TYPEDEF_P(NODE) \ (TREE_CODE (NODE) == TYPE_DECL && DECL_LANG_FLAG_2 (NODE)) #define SET_DECL_IMPLICIT_TYPEDEF_P(NODE) \ (DECL_LANG_FLAG_2 (NODE) = 1) +#define DECL_SELF_REFERENCE_P(NODE) \ + (TREE_CODE (NODE) == TYPE_DECL && DECL_LANG_FLAG_4 (NODE)) +#define SET_DECL_SELF_REFERENCE_P(NODE) \ + (DECL_LANG_FLAG_4 (NODE) = 1) /* A `primary' template is one that has its own template header. A member function of a class template is a template, but not primary. @@ -2956,7 +2961,7 @@ struct lang_decl GTY(()) entity with its own template parameter list, and which is not a full specialization. */ #define PROCESSING_REAL_TEMPLATE_DECL_P() \ - (processing_template_decl > template_class_depth (current_class_type)) + (processing_template_decl > template_class_depth (current_scope ())) /* Nonzero if this VAR_DECL or FUNCTION_DECL has already been instantiated, i.e. its definition has been generated from the @@ -3627,6 +3632,7 @@ extern tree perform_direct_initialization_if_possible (tree, tree); /* in class.c */ extern tree build_base_path PARAMS ((enum tree_code, tree, tree, int)); extern tree convert_to_base (tree, tree, bool); +extern tree convert_to_base_statically (tree, tree); extern tree build_vtbl_ref PARAMS ((tree, tree)); extern tree build_vfn_ref PARAMS ((tree, tree)); extern tree get_vtable_decl PARAMS ((tree, int)); @@ -4081,7 +4087,7 @@ extern tree instantiate_decl PARAMS ((tree, int)); extern tree get_bindings PARAMS ((tree, tree, tree)); extern int push_tinst_level PARAMS ((tree)); extern void pop_tinst_level PARAMS ((void)); -extern int more_specialized_class PARAMS ((tree, tree)); +extern int more_specialized_class PARAMS ((tree, tree, tree)); extern int is_member_template PARAMS ((tree)); extern int comp_template_parms PARAMS ((tree, tree)); extern int template_class_depth PARAMS ((tree)); @@ -4117,6 +4123,7 @@ extern int unemitted_tinfo_decl_p PARAMS((tree, void *)); extern int emit_tinfo_decl PARAMS((tree *, void *)); /* in search.c */ +extern bool accessible_base_p (tree, tree); extern tree lookup_base PARAMS ((tree, tree, base_access, base_kind *)); extern int types_overlap_p PARAMS ((tree, tree)); extern tree get_vbase PARAMS ((tree, tree)); diff --git a/contrib/gcc/cp/init.c b/contrib/gcc/cp/init.c index 279e3b1..83a8753 100644 --- a/contrib/gcc/cp/init.c +++ b/contrib/gcc/cp/init.c @@ -880,18 +880,10 @@ construct_virtual_base (tree vbase, tree arguments) constructing virtual bases, then we must be the most derived class. Therefore, we don't have to look up the virtual base; we already know where it is. */ - exp = build (PLUS_EXPR, - TREE_TYPE (current_class_ptr), - current_class_ptr, - fold (build1 (NOP_EXPR, TREE_TYPE (current_class_ptr), - BINFO_OFFSET (vbase)))); - exp = build1 (NOP_EXPR, - build_pointer_type (BINFO_TYPE (vbase)), - exp); - exp = build1 (INDIRECT_REF, BINFO_TYPE (vbase), exp); - - expand_aggr_init_1 (vbase, current_class_ref, exp, - arguments, LOOKUP_COMPLAIN); + exp = convert_to_base_statically (current_class_ref, vbase); + + expand_aggr_init_1 (vbase, current_class_ref, exp, arguments, + LOOKUP_COMPLAIN); finish_compound_stmt (/*has_no_scope=*/1, compound_stmt); finish_then_clause (inner_if_stmt); finish_if_stmt (); diff --git a/contrib/gcc/cp/method.c b/contrib/gcc/cp/method.c index 16682af..1c2d2ea 100644 --- a/contrib/gcc/cp/method.c +++ b/contrib/gcc/cp/method.c @@ -661,7 +661,7 @@ do_build_assign_ref (fndecl) int cvquals = cp_type_quals (TREE_TYPE (parm)); int i; - /* Assign to each of thedirect base classes. */ + /* Assign to each of the direct base classes. */ for (i = 0; i < CLASSTYPE_N_BASECLASSES (current_class_type); ++i) { tree binfo; diff --git a/contrib/gcc/cp/parse.y b/contrib/gcc/cp/parse.y index 46e5021..157a210 100644 --- a/contrib/gcc/cp/parse.y +++ b/contrib/gcc/cp/parse.y @@ -56,6 +56,7 @@ Boston, MA 02111-1307, USA. */ static short *malloced_yyss; static void *malloced_yyvs; +static int class_template_ok_as_expr; #define yyoverflow(MSG, SS, SSSIZE, VS, VSSIZE, YYSSZ) \ do { \ @@ -449,7 +450,7 @@ check_class_key (key, aggr) %type <code> template_close_bracket %type <ttype> apparent_template_type %type <ttype> template_type template_arg_list template_arg_list_opt -%type <ttype> template_arg +%type <ttype> template_arg template_arg_1 %type <ttype> condition xcond paren_cond_or_null %type <ttype> type_name nested_name_specifier nested_type ptr_to_mem %type <ttype> complete_type_name notype_identifier nonnested_type @@ -1121,7 +1122,7 @@ template_close_bracket: template_arg_list_opt: /* empty */ { $$ = NULL_TREE; } - | template_arg_list + | template_arg_list ; template_arg_list: @@ -1132,6 +1133,15 @@ template_arg_list: ; template_arg: + { ++class_template_ok_as_expr; } + template_arg_1 + { + --class_template_ok_as_expr; + $$ = $2; + } + ; + +template_arg_1: type_id { $$ = groktypename ($1.t); } | PTYPENAME @@ -1704,7 +1714,14 @@ primary: $$ = $2; } | overqualified_id %prec HYPERUNARY - { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); } + { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); + if (!class_template_ok_as_expr + && DECL_CLASS_TEMPLATE_P ($$)) + { + error ("invalid use of template `%D'", $$); + $$ = error_mark_node; + } + } | overqualified_id '(' nonnull_exprlist ')' { $$ = parse_finish_call_expr ($1, $3, 0); } | overqualified_id LEFT_RIGHT diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c index 22f93bf..62a66d3 100644 --- a/contrib/gcc/cp/pt.c +++ b/contrib/gcc/cp/pt.c @@ -128,7 +128,7 @@ static tree retrieve_specialization PARAMS ((tree, tree)); static tree retrieve_local_specialization PARAMS ((tree)); static tree register_specialization PARAMS ((tree, tree, tree)); static void register_local_specialization PARAMS ((tree, tree)); -static int unregister_specialization PARAMS ((tree, tree)); +static int reregister_specialization PARAMS ((tree, tree, tree)); static tree reduce_template_parm_level PARAMS ((tree, tree, int)); static tree build_template_decl PARAMS ((tree, tree)); static int mark_template_parm PARAMS ((tree, void *)); @@ -1041,13 +1041,11 @@ register_specialization (spec, tmpl, args) } /* Unregister the specialization SPEC as a specialization of TMPL. - Returns nonzero if the SPEC was listed as a specialization of - TMPL. */ + Replace it with NEW_SPEC, if NEW_SPEC is non-NULL. Returns true + if the SPEC was listed as a specialization of TMPL. */ static int -unregister_specialization (spec, tmpl) - tree spec; - tree tmpl; +reregister_specialization (tree spec, tree tmpl, tree new_spec) { tree* s; @@ -1056,7 +1054,10 @@ unregister_specialization (spec, tmpl) s = &TREE_CHAIN (*s)) if (TREE_VALUE (*s) == spec) { - *s = TREE_CHAIN (*s); + if (!new_spec) + *s = TREE_CHAIN (*s); + else + TREE_VALUE (*s) = new_spec; return 1; } @@ -4086,10 +4087,20 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain) } if (template) context = DECL_CONTEXT (template); + if (template + && TREE_CODE (template) == TYPE_DECL + && IS_AGGR_TYPE (TREE_TYPE (template)) + && TREE_CODE (TREE_TYPE (template)) != TEMPLATE_TYPE_PARM) + { + d1 = template; + goto type_decl; + } } else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE (d1))) { - tree type = TREE_TYPE (d1); + tree type; + type_decl: + type = TREE_TYPE (d1); /* If we are declaring a constructor, say A<T>::A<T>, we will get an implicit typename for the second A. Deal with it. */ @@ -4997,8 +5008,9 @@ tsubst_friend_function (decl, args) DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info; if (TREE_CODE (old_decl) != TEMPLATE_DECL) - /* duplicate_decls will take care of this case. */ - ; + reregister_specialization (new_friend, + most_general_template (old_decl), + old_decl); else { tree t; @@ -6340,6 +6352,8 @@ tsubst_decl (t, args, type, complain) r = copy_decl (t); if (TREE_CODE (r) == VAR_DECL) type = complete_type (type); + else if (DECL_SELF_REFERENCE_P (t)) + SET_DECL_SELF_REFERENCE_P (r); TREE_TYPE (r) = type; c_apply_type_quals_to_decl (cp_type_quals (type), r); DECL_CONTEXT (r) = ctx; @@ -9450,22 +9464,25 @@ more_specialized (pat1, pat2, deduce, len) 1 if PAT1 is more specialized than PAT2 as described in [temp.class.order]. -1 if PAT2 is more specialized than PAT1. - 0 if neither is more specialized. */ + 0 if neither is more specialized. + + FULL_ARGS is the full set of template arguments that triggers this + partial ordering. */ int -more_specialized_class (pat1, pat2) - tree pat1, pat2; +more_specialized_class (pat1, pat2, full_args) + tree pat1, pat2, full_args; { tree targs; int winner = 0; targs = get_class_bindings (TREE_VALUE (pat1), TREE_PURPOSE (pat1), - TREE_PURPOSE (pat2)); + add_outermost_template_args (full_args, TREE_PURPOSE (pat2))); if (targs) --winner; targs = get_class_bindings (TREE_VALUE (pat2), TREE_PURPOSE (pat2), - TREE_PURPOSE (pat1)); + add_outermost_template_args (full_args, TREE_PURPOSE (pat1))); if (targs) ++winner; @@ -9751,7 +9768,7 @@ most_specialized_class (tmpl, args) t = TREE_CHAIN (t); for (; t; t = TREE_CHAIN (t)) { - fate = more_specialized_class (champ, t); + fate = more_specialized_class (champ, t, args); if (fate == 1) ; else @@ -9768,7 +9785,7 @@ most_specialized_class (tmpl, args) for (t = list; t && t != champ; t = TREE_CHAIN (t)) { - fate = more_specialized_class (champ, t); + fate = more_specialized_class (champ, t, args); if (fate != 1) return error_mark_node; } @@ -10106,7 +10123,7 @@ regenerate_decl_from_template (decl, tmpl) instantiation. */ gen_tmpl = most_general_template (tmpl); push_access_scope_real (gen_tmpl, args, DECL_CONTEXT (decl)); - unregistered = unregister_specialization (decl, gen_tmpl); + unregistered = reregister_specialization (decl, gen_tmpl, NULL_TREE); /* If the DECL was not unregistered then something peculiar is happening: we created a specialization but did not call diff --git a/contrib/gcc/cp/search.c b/contrib/gcc/cp/search.c index 7a82796..4721a58 100644 --- a/contrib/gcc/cp/search.c +++ b/contrib/gcc/cp/search.c @@ -254,6 +254,28 @@ lookup_base_r (binfo, base, access, is_virtual, binfo_ptr) return found; } +/* Returns true if type BASE is accessible in T. (BASE is known to be + a base class of T.) */ + +bool +accessible_base_p (tree t, tree base) +{ + tree decl; + + /* [class.access.base] + + A base class is said to be accessible if an invented public + member of the base class is accessible. */ + /* Rather than inventing a public member, we use the implicit + public typedef created in the scope of every class. */ + decl = TYPE_FIELDS (base); + while (!DECL_SELF_REFERENCE_P (decl)) + decl = TREE_CHAIN (decl); + while (ANON_AGGR_TYPE_P (t)) + t = TYPE_CONTEXT (t); + return accessible_p (t, decl); +} + /* Lookup BASE in the hierarchy dominated by T. Do access checking as ACCESS specifies. Return the binfo we discover (which might not be canonical). If KIND_PTR is non-NULL, fill with information about @@ -313,41 +335,24 @@ lookup_base (t, base, access, kind_ptr) break; default: - if (access != ba_ignore + if ((access & ~ba_quiet) != ba_ignore /* If BASE is incomplete, then BASE and TYPE are probably the same, in which case BASE is accessible. If they are not the same, then TYPE is invalid. In that case, there's no need to issue another error here, and there's no implicit typedef to use in the code that follows, so we skip the check. */ - && COMPLETE_TYPE_P (base)) + && COMPLETE_TYPE_P (base) + && !accessible_base_p (t, base)) { - tree decl; - - /* [class.access.base] - - A base class is said to be accessible if an invented public - member of the base class is accessible. */ - /* Rather than inventing a public member, we use the implicit - public typedef created in the scope of every class. */ - decl = TYPE_FIELDS (base); - while (TREE_CODE (decl) != TYPE_DECL - || !DECL_ARTIFICIAL (decl) - || DECL_NAME (decl) != constructor_name (base)) - decl = TREE_CHAIN (decl); - while (ANON_AGGR_TYPE_P (t)) - t = TYPE_CONTEXT (t); - if (!accessible_p (t, decl)) + if (!(access & ba_quiet)) { - if (!(access & ba_quiet)) - { - error ("`%T' is an inaccessible base of `%T'", base, t); - binfo = error_mark_node; - } - else - binfo = NULL_TREE; - bk = bk_inaccessible; + error ("`%T' is an inaccessible base of `%T'", base, t); + binfo = error_mark_node; } + else + binfo = NULL_TREE; + bk = bk_inaccessible; } break; } @@ -2635,6 +2640,20 @@ setup_class_bindings (name, type_binding_p) if (BASELINK_P (value_binding)) /* NAME is some overloaded functions. */ value_binding = BASELINK_FUNCTIONS (value_binding); + /* Two conversion operators that convert to the same type + may have different names. (See + mangle_conv_op_name_for_type.) To avoid recording the + same conversion operator declaration more than once we + must check to see that the same operator was not already + found under another name. */ + if (IDENTIFIER_TYPENAME_P (name) + && is_overloaded_fn (value_binding)) + { + tree fns; + for (fns = value_binding; fns; fns = OVL_NEXT (fns)) + if (IDENTIFIER_CLASS_VALUE (DECL_NAME (OVL_CURRENT (fns)))) + return; + } pushdecl_class_level (value_binding); } } |