summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2003-08-22 02:56:07 +0000
committerkan <kan@FreeBSD.org>2003-08-22 02:56:07 +0000
commit08db0e4d745472adc9c30de407304713c78e950e (patch)
treeaa86de970d24a76b30b53157cf41e9d09ffe4d51 /contrib/gcc/cp
parent7b704871fdac058719f34a1e6b9de71ee76c5be4 (diff)
downloadFreeBSD-src-08db0e4d745472adc9c30de407304713c78e950e.zip
FreeBSD-src-08db0e4d745472adc9c30de407304713c78e950e.tar.gz
Gcc 3.3.1-release.
Diffstat (limited to 'contrib/gcc/cp')
-rw-r--r--contrib/gcc/cp/ChangeLog102
-rw-r--r--contrib/gcc/cp/call.c31
-rw-r--r--contrib/gcc/cp/class.c28
-rw-r--r--contrib/gcc/cp/cp-tree.h23
-rw-r--r--contrib/gcc/cp/decl.c34
-rw-r--r--contrib/gcc/cp/init.c16
-rw-r--r--contrib/gcc/cp/method.c2
-rw-r--r--contrib/gcc/cp/parse.y23
-rw-r--r--contrib/gcc/cp/pt.c53
-rw-r--r--contrib/gcc/cp/search.c71
10 files changed, 298 insertions, 85 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/decl.c b/contrib/gcc/cp/decl.c
index be31ac2..a392ee0 100644
--- a/contrib/gcc/cp/decl.c
+++ b/contrib/gcc/cp/decl.c
@@ -3514,7 +3514,9 @@ duplicate_decls (newdecl, olddecl)
/* Already complained about this, so don't do so again. */
else if (current_class_type == NULL_TREE
- || IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type)
+ || !DECL_ASSEMBLER_NAME_SET_P (newdecl)
+ || (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl))
+ != current_class_type))
{
error ("conflicting types for `%#D'", newdecl);
cp_error_at ("previous declaration as `%#D'", olddecl);
@@ -4039,6 +4041,15 @@ duplicate_decls (newdecl, olddecl)
Update OLDDECL to be the same. */
DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);
+ /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
+ so that encode_section_info has a chance to look at the new decl
+ flags and attributes. */
+ if (DECL_RTL_SET_P (olddecl)
+ && (TREE_CODE (olddecl) == FUNCTION_DECL
+ || (TREE_CODE (olddecl) == VAR_DECL
+ && TREE_STATIC (olddecl))))
+ make_decl_rtl (olddecl, NULL);
+
return 1;
}
@@ -8191,6 +8202,7 @@ reshape_init (tree type, tree *initp)
{
my_friendly_assert (TREE_CODE (old_init) == TREE_LIST, 20021202);
TREE_VALUE (old_init) = error_mark_node;
+ *initp = TREE_CHAIN (old_init);
return old_init;
}
@@ -14004,16 +14016,16 @@ finish_enum (enumtype)
else
fixup_signed_type (enumtype);
- /* We use "int" or "unsigned int" as the underlying type, unless all
- the values will not fit or the user has requested that we try to
- use shorter types where possible. */
- if (precision < TYPE_PRECISION (integer_type_node)
- && !flag_short_enums)
- {
- TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
- TYPE_SIZE (enumtype) = NULL_TREE;
- layout_type (enumtype);
- }
+ if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node)))
+ /* Use the width of the narrowest normal C type which is wide
+ enough. */
+ TYPE_PRECISION (enumtype) = TYPE_PRECISION (c_common_type_for_size
+ (precision, 1));
+ else
+ TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
+
+ TYPE_SIZE (enumtype) = NULL_TREE;
+ layout_type (enumtype);
/* Fix up all variant types of this enum type. */
for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t))
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);
}
}
OpenPOWER on IntegriCloud