aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2006-02-08 20:26:58 +0000
committerPaul Brook <paul@codesourcery.com>2006-02-08 20:26:58 +0000
commit5e642ab44d458b85bcde5b20dccbb68dbe0cd3d9 (patch)
treee07a2bd1b7a01b095e6aeb0826b1302ffb42f4be /gcc/cp
parent1bbb1a67870cb029d7cf9587b4b84fd04c7a0405 (diff)
Merge from gcc-4_1-branch revision 110478.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/csl/sourcerygxx-4_1@110766 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog96
-rw-r--r--gcc/cp/call.c13
-rw-r--r--gcc/cp/class.c70
-rw-r--r--gcc/cp/cp-tree.h17
-rw-r--r--gcc/cp/decl.c26
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/cp/name-lookup.c109
-rw-r--r--gcc/cp/parser.c42
-rw-r--r--gcc/cp/pt.c272
-rw-r--r--gcc/cp/search.c2
-rw-r--r--gcc/cp/typeck.c2
12 files changed, 441 insertions, 213 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 10737329f33..7a0357b5c47 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,99 @@
+2006-01-31 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25342
+ * cp-tree.h (DECL_TEMPLATE_SPECIALIZATIONS): Revise
+ documentation.
+ * pt.c (determine_specialization): Use INNERMOST_TEMPLATE_PARMS,
+ not TREE_VALUE.
+ (instantiate_class_template): Simplify.
+ (verify_class_unification): Remove.
+ (unify): Document parameters. Use INNERMOST_TEMPLATE_ARGS to
+ permit multiple levels of template arguments.
+ (more_specialized_class): Simplify.
+ (get_class_bindings): Pass full arguments to unify. Fold
+ verify_class_unification into this function. Return full
+ arguments.
+ (most_specialized_class): Adjust for changes to
+ get_class_bindings. Issue errors here for ambiguity. Return the
+ fully deduced arguments for the most specialized class, in
+ addition to the partial specialization.
+
+2006-01-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25999
+ * decl.c (start_preparsed_function): Call maybe_apply_pragma_weak
+ here, not ...
+ (start_function): ... here.
+
+ PR c++/25855
+ * pt.c (most_speialized_instantiation): When a tie occurs, set the
+ current presumed champion to the next template.
+
+2006-01-24 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/25552
+ * parser.c (cp_parser_unqualified_id): Check that destructor name
+ and scope match.
+ * call.c (check_dtor_name): Do not expect a BIT_NOT_EXPR.
+ Adjust comment. Use same_type_p to compare types.
+ * typeck.c (lookup_destructor): Adjust call to check_dtor_name.
+ * init.c (build_offset_ref): Adjust call to check_dtor_name.
+
+2006-01-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25895
+ * class.c (build_base_path): Generate a NOP_EXPR instead of a
+ COMPONENT_REF if the base and derived classes are at the same
+ address.
+
+ PR c++/25856
+ * decl.c (begin_destructor_body): Robustify.
+
+ PR c++/25858
+ * parser.c (cp_parser_direct_declarator): Robustify.
+
+2006-01-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/22136
+ * name-lookup.c (do_class_using_decl): Don't try to look up base
+ classes in templates with dependent base types.
+
+2006-01-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/25854
+ * pt.c (maybe_process_partial_specialization): Return early on
+ error_mark_node.
+
+2006-01-19 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/16829
+ * decl.c (start_preparsed_function): Check default arguments
+ unconditionally.
+ * name-lookup.c (pushdecl_maybe_friend): Check default arguments
+ of all functions and function templates.
+ * parser.c (cp_parser_late_parsing_default_args): Check default
+ arguments.
+ * decl2.c (check_default_args): Set missing default arguments to
+ error_mark_node.
+
+2006-01-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/25836
+ * cp-tree.h (push_class_stack): New function.
+ (pop_class_stack): Likewise.
+ * class.c (class_stack_node): Add hidden field.
+ (pushclass): Clear it.
+ (push_class_stack): New function.
+ (pop_class_stack): Likewise.
+ (currently_open_class): Ignore hidden classes.
+ (currently_open_derived_class): Likewise.
+ * name-lookup.c (push_to_top_level): Call push_class_stack.
+ (pop_from_top_level): Call pop_class_stack.
+
+2006-01-18 Jakub Jelinek <jakub@redhat.com>
+
+ * search.c (lookup_conversions_r): Fix a pasto.
+
2006-01-17 Jakub Jelinek <jakub@redhat.com>
PR c/25682
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index ea1ebc26dfe..690125dfca3 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -198,15 +198,12 @@ typedef void (*diagnostic_fn_t) (const char *, ...) ATTRIBUTE_GCC_CXXDIAG(1,2);
static tree build_temp (tree, tree, int, diagnostic_fn_t *);
static void check_constructor_callable (tree, tree);
-/* Returns nonzero iff the destructor name specified in NAME
- (a BIT_NOT_EXPR) matches BASETYPE. The operand of NAME can take many
- forms... */
+/* Returns nonzero iff the destructor name specified in NAME matches BASETYPE.
+ NAME can take many forms... */
bool
check_dtor_name (tree basetype, tree name)
{
- name = TREE_OPERAND (name, 0);
-
/* Just accept something we've already complained about. */
if (name == error_mark_node)
return true;
@@ -237,9 +234,9 @@ check_dtor_name (tree basetype, tree name)
return false;
}
- if (name && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (name))
- return true;
- return false;
+ if (!name)
+ return false;
+ return same_type_p (TYPE_MAIN_VARIANT (basetype), TYPE_MAIN_VARIANT (name));
}
/* We want the address of a function or method. We avoid creating a
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 67071dc660d..1dffcec22d4 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -60,6 +60,10 @@ typedef struct class_stack_node {
/* If were defining TYPE, the names used in this class. */
splay_tree names_used;
+
+ /* Nonzero if this class is no longer open, because of a call to
+ push_to_top_level. */
+ size_t hidden;
}* class_stack_node_t;
typedef struct vtbl_init_data_s
@@ -285,13 +289,23 @@ build_base_path (enum tree_code code,
offset = BINFO_OFFSET (binfo);
fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
+ target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
/* Do we need to look in the vtable for the real offset? */
virtual_access = (v_binfo && fixed_type_p <= 0);
/* Do we need to check for a null pointer? */
- if (want_pointer && !nonnull && (virtual_access || !integer_zerop (offset)))
- null_test = error_mark_node;
+ if (want_pointer && !nonnull)
+ {
+ /* If we know the conversion will not actually change the value
+ of EXPR, then we can avoid testing the expression for NULL.
+ We have to avoid generating a COMPONENT_REF for a base class
+ field, because other parts of the compiler know that such
+ expressions are always non-NULL. */
+ if (!virtual_access && integer_zerop (offset))
+ return build_nop (build_pointer_type (target_type), expr);
+ null_test = error_mark_node;
+ }
/* Protect against multiple evaluation if necessary. */
if (TREE_SIDE_EFFECTS (expr) && (null_test || virtual_access))
@@ -372,8 +386,6 @@ build_base_path (enum tree_code code,
offset = v_offset;
}
- target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
-
target_type = cp_build_qualified_type
(target_type, cp_type_quals (TREE_TYPE (TREE_TYPE (expr))));
ptr_target_type = build_pointer_type (target_type);
@@ -5387,6 +5399,8 @@ restore_class_cache (void)
void
pushclass (tree type)
{
+ class_stack_node_t csn;
+
type = TYPE_MAIN_VARIANT (type);
/* Make sure there is enough room for the new entry on the stack. */
@@ -5400,10 +5414,12 @@ pushclass (tree type)
}
/* Insert a new entry on the class stack. */
- current_class_stack[current_class_depth].name = current_class_name;
- current_class_stack[current_class_depth].type = current_class_type;
- current_class_stack[current_class_depth].access = current_access_specifier;
- current_class_stack[current_class_depth].names_used = 0;
+ csn = current_class_stack + current_class_depth;
+ csn->name = current_class_name;
+ csn->type = current_class_type;
+ csn->access = current_access_specifier;
+ csn->names_used = 0;
+ csn->hidden = 0;
current_class_depth++;
/* Now set up the new type. */
@@ -5460,6 +5476,24 @@ popclass (void)
splay_tree_delete (current_class_stack[current_class_depth].names_used);
}
+/* Mark the top of the class stack as hidden. */
+
+void
+push_class_stack (void)
+{
+ if (current_class_depth)
+ ++current_class_stack[current_class_depth - 1].hidden;
+}
+
+/* Mark the top of the class stack as un-hidden. */
+
+void
+pop_class_stack (void)
+{
+ if (current_class_depth)
+ --current_class_stack[current_class_depth - 1].hidden;
+}
+
/* Returns 1 if current_class_type is either T or a nested type of T.
We start looking from 1 because entry 0 is from global scope, and has
no type. */
@@ -5470,10 +5504,14 @@ currently_open_class (tree t)
int i;
if (current_class_type && same_type_p (t, current_class_type))
return 1;
- for (i = 1; i < current_class_depth; ++i)
- if (current_class_stack[i].type
- && same_type_p (current_class_stack [i].type, t))
- return 1;
+ for (i = current_class_depth - 1; i > 0; --i)
+ {
+ if (current_class_stack[i].hidden)
+ break;
+ if (current_class_stack[i].type
+ && same_type_p (current_class_stack [i].type, t))
+ return 1;
+ }
return 0;
}
@@ -5497,8 +5535,12 @@ currently_open_derived_class (tree t)
return current_class_type;
for (i = current_class_depth - 1; i > 0; --i)
- if (DERIVED_FROM_P (t, current_class_stack[i].type))
- return current_class_stack[i].type;
+ {
+ if (current_class_stack[i].hidden)
+ break;
+ if (DERIVED_FROM_P (t, current_class_stack[i].type))
+ return current_class_stack[i].type;
+ }
return NULL_TREE;
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6765eb5a6dc..492e3b95805 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2729,12 +2729,13 @@ extern void decl_shadowed_for_var_insert (tree, tree);
For a class template, this list contains the partial
specializations of this template. (Full specializations are not
- recorded on this list.) The TREE_PURPOSE holds the innermost
- arguments used in the partial specialization (e.g., for `template
- <class T> struct S<T*, int>' this will be `T*'.) The TREE_VALUE
- holds the innermost template parameters for the specialization
- (e.g., `T' in the example above.) The TREE_TYPE is the _TYPE node
- for the partial specialization.
+ recorded on this list.) The TREE_PURPOSE holds the arguments used
+ in the partial specialization (e.g., for `template <class T> struct
+ S<T*, int>' this will be `T*'.) The arguments will also include
+ any outer template arguments. The TREE_VALUE holds the innermost
+ template parameters for the specialization (e.g., `T' in the
+ example above.) The TREE_TYPE is the _TYPE node for the partial
+ specialization.
This list is not used for static variable templates. */
#define DECL_TEMPLATE_SPECIALIZATIONS(NODE) DECL_SIZE (NODE)
@@ -3755,6 +3756,8 @@ extern tree cp_fold_obj_type_ref (tree, tree);
extern void set_linkage_according_to_type (tree, tree);
extern void determine_key_method (tree);
extern void check_for_override (tree, tree);
+extern void push_class_stack (void);
+extern void pop_class_stack (void);
/* in cvt.c */
extern tree convert_to_reference (tree, tree, int, int, tree);
@@ -4037,7 +4040,7 @@ extern void do_type_instantiation (tree, tree, tsubst_flags_t);
extern tree instantiate_decl (tree, int, bool);
extern int push_tinst_level (tree);
extern void pop_tinst_level (void);
-extern int more_specialized_class (tree, tree, tree);
+extern int more_specialized_class (tree, tree);
extern int comp_template_parms (tree, tree);
extern int template_class_depth (tree);
extern int is_specialization_of (tree, tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 85bf371c8b8..c8cb38f1954 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10215,6 +10215,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
you declare a function, these types can be incomplete, but they
must be complete when you define the function. */
check_function_type (decl1, current_function_parms);
+ /* Make sure no default arg is missing. */
+ check_default_args (decl1);
/* Build the return declaration for the function. */
restype = TREE_TYPE (fntype);
@@ -10281,10 +10283,19 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
/* We need to set the DECL_CONTEXT. */
if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1))
DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1));
- /* And make sure we have enough default args. */
- check_default_args (decl1);
}
fntype = TREE_TYPE (decl1);
+
+ /* If #pragma weak applies, mark the decl appropriately now.
+ The pragma only applies to global functions. Because
+ determining whether or not the #pragma applies involves
+ computing the mangled name for the declaration, we cannot
+ apply the pragma until after we have merged this declaration
+ with any previous declarations; if the original declaration
+ has a linkage specification, that specification applies to
+ the definition as well, and may affect the mangled name. */
+ if (!DECL_CONTEXT (decl1))
+ maybe_apply_pragma_weak (decl1);
}
/* Determine the ELF visibility attribute for the function. We must
@@ -10456,10 +10467,6 @@ start_function (cp_decl_specifier_seq *declspecs,
if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
return 0;
- /* If #pragma weak was used, mark the decl weak now. */
- if (global_scope_p (current_binding_level))
- maybe_apply_pragma_weak (decl1);
-
if (DECL_MAIN_P (decl1))
/* main must return int. grokfndecl should have corrected it
(and issued a diagnostic) if the user got it wrong. */
@@ -10627,6 +10634,13 @@ begin_destructor_body (void)
tree if_stmt;
tree compound_stmt;
+ /* If the CURRENT_CLASS_TYPE is incomplete, we will have already
+ issued an error message. We still want to try to process the
+ body of the function, but initialize_vtbl_ptrs will crash if
+ TYPE_BINFO is NULL. */
+ if (!COMPLETE_TYPE_P (current_class_type))
+ return;
+
/* If the dtor is empty, and we know there is not any possible
way we could use any vtable entries, before they are possibly
set by a base class dtor, we don't have to setup the vtables,
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 47b476cd500..4a776d91194 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3228,7 +3228,7 @@ check_default_args (tree x)
else if (saw_def)
{
error ("default argument missing for parameter %P of %q+#D", i, x);
- break;
+ TREE_PURPOSE (arg) = error_mark_node;
}
}
}
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 3953fccd9e4..5c6a075220f 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1393,9 +1393,10 @@ build_offset_ref (tree type, tree name, bool address_p)
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
+ name = TREE_OPERAND (name, 0);
if (! check_dtor_name (type, name))
error ("qualified type %qT does not match destructor name %<~%T%>",
- type, TREE_OPERAND (name, 0));
+ type, name);
name = dtor_identifier;
}
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 5e5f64df381..dfbf28f6798 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -602,6 +602,9 @@ pushdecl_maybe_friend (tree x, bool is_friend)
{
int different_binding_level = 0;
+ if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))
+ check_default_args (x);
+
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
name = TREE_OPERAND (name, 0);
@@ -710,8 +713,6 @@ pushdecl_maybe_friend (tree x, bool is_friend)
{
if (TREE_CODE (t) == TYPE_DECL)
SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
- else if (TREE_CODE (t) == FUNCTION_DECL)
- check_default_args (t);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
@@ -994,9 +995,6 @@ pushdecl_maybe_friend (tree x, bool is_friend)
}
}
- if (TREE_CODE (x) == FUNCTION_DECL)
- check_default_args (x);
-
if (TREE_CODE (x) == VAR_DECL)
maybe_register_incomplete_var (x);
}
@@ -2724,9 +2722,21 @@ push_class_level_binding (tree name, tree x)
tree
do_class_using_decl (tree scope, tree name)
{
- tree value, decl, binfo;
- base_kind b_kind;
- bool dependent_p;
+ /* The USING_DECL returned by this function. */
+ tree value;
+ /* The declaration (or declarations) name by this using
+ declaration. NULL if we are in a template and cannot figure out
+ what has been named. */
+ tree decl;
+ /* True if SCOPE is a dependent type. */
+ bool scope_dependent_p;
+ /* True if SCOPE::NAME is dependent. */
+ bool name_dependent_p;
+ /* True if any of the bases of CURRENT_CLASS_TYPE are dependent. */
+ bool bases_dependent_p;
+ tree binfo;
+ tree base_binfo;
+ int i;
if (!scope || !TYPE_P (scope))
{
@@ -2734,25 +2744,6 @@ do_class_using_decl (tree scope, tree name)
return NULL_TREE;
}
- /* Make sure the scope is a base. */
- dependent_p = dependent_type_p (scope);
- if (!dependent_p)
- binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
- else
- {
- binfo = NULL;
- if (same_type_p (current_class_type, scope))
- b_kind = bk_same_type;
- else
- b_kind = bk_proper_base;
- }
-
- if (b_kind < bk_proper_base)
- {
- error_not_base_type (scope, current_class_type);
- return NULL_TREE;
- }
-
/* Make sure the name is not invalid */
if (TREE_CODE (name) == BIT_NOT_EXPR)
{
@@ -2771,32 +2762,64 @@ do_class_using_decl (tree scope, tree name)
return NULL_TREE;
}
- if (!dependent_p
- && IDENTIFIER_OPNAME_P (name) && dependent_type_p (TREE_TYPE (name)))
- dependent_p = 1;
+ scope_dependent_p = dependent_type_p (scope);
+ name_dependent_p = (scope_dependent_p
+ || (IDENTIFIER_OPNAME_P (name)
+ && dependent_type_p (TREE_TYPE (name))));
+
+ bases_dependent_p = false;
+ if (processing_template_decl)
+ for (binfo = TYPE_BINFO (current_class_type), i = 0;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo);
+ i++)
+ if (dependent_type_p (TREE_TYPE (base_binfo)))
+ {
+ bases_dependent_p = true;
+ break;
+ }
+
+ decl = NULL_TREE;
- /* See if there are any members of the base. */
- if (!dependent_p)
- {
- decl = lookup_member (binfo, name, 0, false);
+ /* From [namespace.udecl]:
- if (!decl)
+ A using-declaration used as a member-declaration shall refer to a
+ member of a base class of the class being defined.
+
+ In general, we cannot check this constraint in a template because
+ we do not know the entire set of base classes of the current
+ class type. However, if all of the base classes are
+ non-dependent, then we can avoid delaying the check until
+ instantiation. */
+ if (!scope_dependent_p && !bases_dependent_p)
+ {
+ base_kind b_kind;
+ tree binfo;
+ binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
+ if (b_kind < bk_proper_base)
{
- error ("no members matching %<%T::%D%> in %q#T", scope, name, scope);
+ error_not_base_type (scope, current_class_type);
return NULL_TREE;
}
- if (BASELINK_P (decl))
- /* Ignore base type this came from. */
- decl = BASELINK_FUNCTIONS (decl);
+ if (!name_dependent_p)
+ {
+ decl = lookup_member (binfo, name, 0, false);
+ if (!decl)
+ {
+ error ("no members matching %<%T::%D%> in %q#T", scope, name,
+ scope);
+ return NULL_TREE;
+ }
+ /* The binfo from which the functions came does not matter. */
+ if (BASELINK_P (decl))
+ decl = BASELINK_FUNCTIONS (decl);
+ }
}
- else
- decl = NULL_TREE;
value = build_lang_decl (USING_DECL, name, NULL_TREE);
USING_DECL_DECLS (value) = decl;
USING_DECL_SCOPE (value) = scope;
- DECL_DEPENDENT_P (value) = dependent_p;
+ DECL_DEPENDENT_P (value) = !decl;
return value;
}
@@ -5018,6 +5041,7 @@ push_to_top_level (void)
current_lang_base = VEC_alloc (tree, gc, 10);
current_lang_name = lang_name_cplusplus;
current_namespace = global_namespace;
+ push_class_stack ();
skip_evaluation = 0;
timevar_pop (TV_NAME_LOOKUP);
}
@@ -5033,6 +5057,7 @@ pop_from_top_level (void)
/* Clear out class-level bindings cache. */
if (previous_class_level)
invalidate_class_lookup_cache ();
+ pop_class_stack ();
current_lang_base = 0;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 537f1e70b4c..829afa03b60 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -3426,6 +3426,15 @@ cp_parser_unqualified_id (cp_parser* parser,
else if (type_decl == error_mark_node)
return error_mark_node;
+ /* Check that destructor name and scope match. */
+ if (declarator_p && scope && !check_dtor_name (scope, type_decl))
+ {
+ if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
+ error ("declaration of %<~%T%> as member of %qT",
+ type_decl, scope);
+ return error_mark_node;
+ }
+
/* [class.dtor]
A typedef-name that names a class shall not be used as the
@@ -11440,22 +11449,24 @@ cp_parser_direct_declarator (cp_parser* parser,
if (TREE_CODE (unqualified_name) == TYPE_DECL)
{
- if (qualifying_scope
- && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name)))
+ tree name_type = TREE_TYPE (unqualified_name);
+ if (class_type && same_type_p (name_type, class_type))
{
- error ("invalid use of constructor as a template");
- inform ("use %<%T::%D%> instead of %<%T::%T%> to name "
- "the constructor in a qualified name",
- class_type,
- DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
- class_type, class_type);
- declarator = cp_error_declarator;
- break;
+ if (qualifying_scope
+ && CLASSTYPE_USE_TEMPLATE (name_type))
+ {
+ error ("invalid use of constructor as a template");
+ inform ("use %<%T::%D%> instead of %<%T::%D%> to "
+ "name the constructor in a qualified name",
+ class_type,
+ DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
+ class_type, name_type);
+ declarator = cp_error_declarator;
+ break;
+ }
+ else
+ unqualified_name = constructor_name (class_type);
}
- else if (class_type
- && same_type_p (TREE_TYPE (unqualified_name),
- class_type))
- unqualified_name = constructor_name (class_type);
else
{
/* We do not attempt to print the declarator
@@ -15788,6 +15799,9 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
cp_parser_pop_lexer (parser);
}
+ /* Make sure no default arg is missing. */
+ check_default_args (fn);
+
/* Restore the state of local_variables_forbidden_p. */
parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 62b4a6bb5cb..51d26784c1a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -147,7 +147,6 @@ static void set_current_access_from_decl (tree);
static void check_default_tmpl_args (tree, tree, int, int);
static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree);
static tree get_template_base (tree, tree, tree, tree);
-static int verify_class_unification (tree, tree, tree);
static tree try_class_unification (tree, tree, tree, tree);
static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
tree, tree);
@@ -695,8 +694,12 @@ check_explicit_instantiation_namespace (tree spec)
void
maybe_process_partial_specialization (tree type)
{
- /* TYPE maybe an ERROR_MARK_NODE. */
- tree context = TYPE_P (type) ? TYPE_CONTEXT (type) : NULL_TREE;
+ tree context;
+
+ if (type == error_mark_node)
+ return;
+
+ context = TYPE_CONTEXT (type);
if (CLASS_TYPE_P (type) && CLASSTYPE_USE_TEMPLATE (type))
{
@@ -1459,7 +1462,8 @@ determine_specialization (tree template_id,
if (current_binding_level->kind == sk_template_parms
&& !current_binding_level->explicit_spec_p
&& (TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (fn))
- != TREE_VEC_LENGTH (TREE_VALUE (current_template_parms))))
+ != TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS
+ (current_template_parms))))
continue;
/* See whether this function might be a specialization of this
@@ -2756,7 +2760,7 @@ process_partial_specialization (tree decl)
return decl;
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)
- = tree_cons (inner_args, inner_parms,
+ = tree_cons (specargs, inner_parms,
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl));
TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type;
return decl;
@@ -5493,34 +5497,34 @@ instantiate_class_template (tree type)
template = most_general_template (CLASSTYPE_TI_TEMPLATE (type));
gcc_assert (TREE_CODE (template) == TEMPLATE_DECL);
- /* Figure out which arguments are being used to do the
- instantiation. */
- args = CLASSTYPE_TI_ARGS (type);
-
/* Determine what specialization of the original template to
instantiate. */
- t = most_specialized_class (template, args);
+ t = most_specialized_class (type, template);
if (t == error_mark_node)
{
- const char *str = "candidates are:";
- error ("ambiguous class template instantiation for %q#T", type);
- for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t;
- t = TREE_CHAIN (t))
- {
- if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args))
- {
- error ("%s %+#T", str, TREE_TYPE (t));
- str = " ";
- }
- }
TYPE_BEING_DEFINED (type) = 1;
return error_mark_node;
}
+ else if (t)
+ {
+ /* This TYPE is actually an instantiation of a partial
+ specialization. We replace the innermost set of ARGS with
+ the arguments appropriate for substitution. For example,
+ given:
+
+ template <class T> struct S {};
+ template <class T> struct S<T*> {};
- if (t)
- pattern = TREE_TYPE (t);
+ and supposing that we are instantiating S<int*>, ARGS will
+ presently be {int*} -- but we need {int}. */
+ pattern = TREE_TYPE (t);
+ args = TREE_PURPOSE (t);
+ }
else
- pattern = TREE_TYPE (template);
+ {
+ pattern = TREE_TYPE (template);
+ args = CLASSTYPE_TI_ARGS (type);
+ }
/* If the template we're instantiating is incomplete, then clearly
there's nothing we can do. */
@@ -5541,34 +5545,6 @@ instantiate_class_template (tree type)
push_to_top_level ();
- if (t)
- {
- /* This TYPE is actually an instantiation of a partial
- specialization. We replace the innermost set of ARGS with
- the arguments appropriate for substitution. For example,
- given:
-
- template <class T> struct S {};
- template <class T> struct S<T*> {};
-
- and supposing that we are instantiating S<int*>, ARGS will
- present be {int*} but we need {int}. */
- tree inner_args
- = get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t),
- args);
-
- /* If there were multiple levels in ARGS, replacing the
- innermost level would alter CLASSTYPE_TI_ARGS, which we don't
- want, so we make a copy first. */
- if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
- {
- args = copy_node (args);
- SET_TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args), inner_args);
- }
- else
- args = inner_args;
- }
-
SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
/* Set the input location to the template definition. This is needed
@@ -9766,34 +9742,6 @@ try_one_overload (tree tparms,
return 1;
}
-/* Verify that nondeduce template argument agrees with the type
- obtained from argument deduction. Return nonzero if the
- verification fails.
-
- For example:
-
- struct A { typedef int X; };
- template <class T, class U> struct C {};
- template <class T> struct C<T, typename T::X> {};
-
- Then with the instantiation `C<A, int>', we can deduce that
- `T' is `A' but unify () does not check whether `typename T::X'
- is `int'. This function ensure that they agree.
-
- TARGS, PARMS are the same as the arguments of unify.
- ARGS contains template arguments from all levels. */
-
-static int
-verify_class_unification (tree targs, tree parms, tree args)
-{
- parms = tsubst (parms, add_outermost_template_args (args, targs),
- tf_none, NULL_TREE);
- if (parms == error_mark_node)
- return 1;
-
- return !comp_template_args (parms, INNERMOST_TEMPLATE_ARGS (args));
-}
-
/* PARM is a template class (perhaps with unbound template
parameters). ARG is a fully instantiated type. If ARG can be
bound to PARM, return ARG, otherwise return NULL_TREE. TPARMS and
@@ -9956,9 +9904,18 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm)
return 1;
}
-/* Takes parameters as for type_unification. Returns 0 if the
- type deduction succeeds, 1 otherwise. The parameter STRICT is a
- bitwise or of the following flags:
+/* Deduce the value of template parameters. TPARMS is the (innermost)
+ set of template parameters to a template. TARGS is the bindings
+ for those template parameters, as determined thus far; TARGS may
+ include template arguments for outer levels of template parameters
+ as well. PARM is a parameter to a template function, or a
+ subcomponent of that parameter; ARG is the corresponding argument.
+ This function attempts to match PARM with ARG in a manner
+ consistent with the existing assignments in TARGS. If more values
+ are deduced, then TARGS is updated.
+
+ Returns 0 if the type deduction succeeds, 1 otherwise. The
+ parameter STRICT is a bitwise or of the following flags:
UNIFY_ALLOW_NONE:
Require an exact match between PARM and ARG.
@@ -10063,7 +10020,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
return (TREE_CODE (arg) == TREE_CODE (parm)
&& same_type_p (parm, arg)) ? 0 : 1;
idx = TEMPLATE_TYPE_IDX (parm);
- targ = TREE_VEC_ELT (targs, idx);
+ targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx));
/* Check for mixed types and values. */
@@ -10164,7 +10121,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
return 1;
}
- TREE_VEC_ELT (targs, idx) = arg;
+ TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
return 0;
case TEMPLATE_PARM_INDEX:
@@ -10178,7 +10135,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
&& cp_tree_equal (parm, arg));
idx = TEMPLATE_PARM_IDX (parm);
- targ = TREE_VEC_ELT (targs, idx);
+ targ = TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx);
if (targ)
return !cp_tree_equal (targ, arg);
@@ -10212,7 +10169,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
else
return 1;
- TREE_VEC_ELT (targs, idx) = arg;
+ TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
return 0;
case PTRMEM_CST:
@@ -10737,33 +10694,44 @@ more_specialized_fn (tree pat1, tree pat2, int len)
return (better1 > 0) - (better2 > 0);
}
-/* Given two class template specialization list nodes PAT1 and PAT2, return:
+/* Determine which of two partial specializations is more specialized.
+
+ PAT1 is a TREE_LIST whose TREE_TYPE is the _TYPE node corresponding
+ to the first partial specialization. The TREE_VALUE is the
+ innermost set of template parameters for the partial
+ specialization. PAT2 is similar, but for the second template.
- 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.
+ Return 1 if the first partial specialization is more specialized;
+ -1 if the second is more specialized; 0 if neither is more
+ specialized.
- FULL_ARGS is the full set of template arguments that triggers this
- partial ordering. */
+ See [temp.class.order] for information about determining which of
+ two templates is more specialized. */
int
-more_specialized_class (tree pat1, tree pat2, tree full_args)
+more_specialized_class (tree pat1, tree pat2)
{
tree targs;
+ tree tmpl1, tmpl2;
int winner = 0;
+
+ tmpl1 = TREE_TYPE (pat1);
+ tmpl2 = TREE_TYPE (pat2);
/* Just like what happens for functions, if we are ordering between
different class template specializations, we may encounter dependent
types in the arguments, and we need our dependency check functions
to behave correctly. */
++processing_template_decl;
- targs = get_class_bindings (TREE_VALUE (pat1), TREE_PURPOSE (pat1),
- add_outermost_template_args (full_args, TREE_PURPOSE (pat2)));
+ targs = get_class_bindings (TREE_VALUE (pat1),
+ CLASSTYPE_TI_ARGS (tmpl1),
+ CLASSTYPE_TI_ARGS (tmpl2));
if (targs)
--winner;
- targs = get_class_bindings (TREE_VALUE (pat2), TREE_PURPOSE (pat2),
- add_outermost_template_args (full_args, TREE_PURPOSE (pat1)));
+ targs = get_class_bindings (TREE_VALUE (pat2),
+ CLASSTYPE_TI_ARGS (tmpl2),
+ CLASSTYPE_TI_ARGS (tmpl1));
if (targs)
++winner;
--processing_template_decl;
@@ -10838,28 +10806,59 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
template <class T> struct S<T*, int> {};
Then, suppose we want to get `S<double*, int>'. The TPARMS will be
- {T}, the PARMS will be {T*, int} and the ARGS will be {double*,
+ {T}, the SPEC_ARGS will be {T*, int} and the ARGS will be {double*,
int}. The resulting vector will be {double}, indicating that `T'
is bound to `double'. */
static tree
-get_class_bindings (tree tparms, tree parms, tree args)
+get_class_bindings (tree tparms, tree spec_args, tree args)
{
int i, ntparms = TREE_VEC_LENGTH (tparms);
- tree vec = make_tree_vec (ntparms);
+ tree deduced_args;
+ tree innermost_deduced_args;
- if (unify (tparms, vec, parms, INNERMOST_TEMPLATE_ARGS (args),
+ innermost_deduced_args = make_tree_vec (ntparms);
+ if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
+ {
+ deduced_args = copy_node (args);
+ SET_TMPL_ARGS_LEVEL (deduced_args,
+ TMPL_ARGS_DEPTH (deduced_args),
+ innermost_deduced_args);
+ }
+ else
+ deduced_args = innermost_deduced_args;
+
+ if (unify (tparms, deduced_args,
+ INNERMOST_TEMPLATE_ARGS (spec_args),
+ INNERMOST_TEMPLATE_ARGS (args),
UNIFY_ALLOW_NONE))
return NULL_TREE;
for (i = 0; i < ntparms; ++i)
- if (! TREE_VEC_ELT (vec, i))
+ if (! TREE_VEC_ELT (innermost_deduced_args, i))
return NULL_TREE;
- if (verify_class_unification (vec, parms, args))
+ /* Verify that nondeduced template arguments agree with the type
+ obtained from argument deduction.
+
+ For example:
+
+ struct A { typedef int X; };
+ template <class T, class U> struct C {};
+ template <class T> struct C<T, typename T::X> {};
+
+ Then with the instantiation `C<A, int>', we can deduce that
+ `T' is `A' but unify () does not check whether `typename T::X'
+ is `int'. */
+ spec_args = tsubst (spec_args, deduced_args, tf_none, NULL_TREE);
+ if (spec_args == error_mark_node
+ /* We only need to check the innermost arguments; the other
+ arguments will always agree. */
+ || !comp_template_args (INNERMOST_TEMPLATE_ARGS (spec_args),
+ INNERMOST_TEMPLATE_ARGS (args)))
return NULL_TREE;
- return vec;
+ return deduced_args;
}
/* In INSTANTIATIONS is a list of <INSTANTIATION, TEMPLATE> pairs.
@@ -10901,6 +10900,7 @@ most_specialized_instantiation (tree instantiations)
/* Equally specialized, move to next function. If there
is no next function, nothing's most specialized. */
fn = TREE_CHAIN (fn);
+ champ = fn;
if (!fn)
break;
}
@@ -11009,26 +11009,42 @@ most_general_template (tree decl)
return decl;
}
-/* Return the most specialized of the class template specializations
- of TMPL which can produce an instantiation matching ARGS, or
- error_mark_node if the choice is ambiguous. */
+/* Return the most specialized of the class template partial
+ specializations of TMPL which can produce TYPE, a specialization of
+ TMPL. The value returned is actually a TREE_LIST; the TREE_TYPE is
+ a _TYPE node corresponding to the partial specialization, while the
+ TREE_PURPOSE is the set of template arguments that must be
+ substituted into the TREE_TYPE in order to generate TYPE.
+
+ If the choice of partial specialization is ambiguous, a diagnostic
+ is issued, and the error_mark_node is returned. If there are no
+ partial specializations of TMPL matching TYPE, then NULL_TREE is
+ returned. */
static tree
-most_specialized_class (tree tmpl, tree args)
+most_specialized_class (tree type, tree tmpl)
{
tree list = NULL_TREE;
tree t;
tree champ;
int fate;
+ bool ambiguous_p;
+ tree args;
tmpl = most_general_template (tmpl);
+ args = CLASSTYPE_TI_ARGS (type);
for (t = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); t; t = TREE_CHAIN (t))
{
- tree spec_args
- = get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args);
+ tree partial_spec_args;
+ tree spec_args;
+
+ partial_spec_args = CLASSTYPE_TI_ARGS (TREE_TYPE (t));
+ spec_args = get_class_bindings (TREE_VALUE (t),
+ partial_spec_args,
+ args);
if (spec_args)
{
- list = tree_cons (TREE_PURPOSE (t), TREE_VALUE (t), list);
+ list = tree_cons (spec_args, TREE_VALUE (t), list);
TREE_TYPE (list) = TREE_TYPE (t);
}
}
@@ -11036,12 +11052,13 @@ most_specialized_class (tree tmpl, tree args)
if (! list)
return NULL_TREE;
+ ambiguous_p = false;
t = list;
champ = t;
t = TREE_CHAIN (t);
for (; t; t = TREE_CHAIN (t))
{
- fate = more_specialized_class (champ, t, args);
+ fate = more_specialized_class (champ, t);
if (fate == 1)
;
else
@@ -11050,17 +11067,36 @@ most_specialized_class (tree tmpl, tree args)
{
t = TREE_CHAIN (t);
if (! t)
- return error_mark_node;
+ {
+ ambiguous_p = true;
+ break;
+ }
}
champ = t;
}
}
- for (t = list; t && t != champ; t = TREE_CHAIN (t))
+ if (!ambiguous_p)
+ for (t = list; t && t != champ; t = TREE_CHAIN (t))
+ {
+ fate = more_specialized_class (champ, t);
+ if (fate != 1)
+ {
+ ambiguous_p = true;
+ break;
+ }
+ }
+
+ if (ambiguous_p)
{
- fate = more_specialized_class (champ, t, args);
- if (fate != 1)
- return error_mark_node;
+ const char *str = "candidates are:";
+ error ("ambiguous class template instantiation for %q#T", type);
+ for (t = list; t; t = TREE_CHAIN (t))
+ {
+ error ("%s %+#T", str, TREE_TYPE (t));
+ str = " ";
+ }
+ return error_mark_node;
}
return champ;
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 090510b4103..90e88d6865e 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -2355,7 +2355,7 @@ lookup_conversions_r (tree binfo,
{
parent_tpl_convs = tree_cons (binfo, my_tpl_convs, parent_tpl_convs);
if (virtual_depth)
- TREE_STATIC (parent_convs) = 1;
+ TREE_STATIC (parent_tpl_convs) = 1;
}
child_convs = other_convs;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 291d5216ebc..bd64a845595 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1828,7 +1828,7 @@ lookup_destructor (tree object, tree scope, tree dtor_name)
tree dtor_type = TREE_OPERAND (dtor_name, 0);
tree expr;
- if (scope && !check_dtor_name (scope, dtor_name))
+ if (scope && !check_dtor_name (scope, dtor_type))
{
error ("qualified type %qT does not match destructor name ~%qT",
scope, dtor_type);