summaryrefslogtreecommitdiffstats
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c12
-rw-r--r--gcc/cp/decl2.c32
-rw-r--r--gcc/cp/friend.c5
-rw-r--r--gcc/cp/pt.c4
5 files changed, 40 insertions, 15 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c3c7c868e25..37170e2ca71 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3721,7 +3721,7 @@ extern void maybe_make_one_only (tree);
extern void grokclassfn (tree, tree, enum overload_flags, tree);
extern tree grok_array_decl (tree, tree);
extern tree delete_sanity (tree, tree, bool, int);
-extern tree check_classfn (tree, tree, bool);
+extern tree check_classfn (tree, tree, tree);
extern void check_member_template (tree);
extern tree grokfield (tree, tree, tree, tree, tree);
extern tree grokbitfield (tree, tree, tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 1b788310ca3..17b625f668c 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3727,8 +3727,10 @@ start_decl (tree declarator,
else
{
tree field = check_classfn (context, decl,
- processing_template_decl
- > template_class_depth (context));
+ (processing_template_decl
+ > template_class_depth (context))
+ ? current_template_parms
+ : NULL_TREE);
if (field && duplicate_decls (decl, field))
decl = field;
}
@@ -5691,8 +5693,10 @@ grokfndecl (tree ctype,
tree old_decl;
old_decl = check_classfn (ctype, decl,
- processing_template_decl
- > template_class_depth (ctype));
+ (processing_template_decl
+ > template_class_depth (ctype))
+ ? current_template_parms
+ : NULL_TREE);
if (old_decl && TREE_CODE (old_decl) == TEMPLATE_DECL)
/* Because grokfndecl is always supposed to return a
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index e094493f988..5730d369efc 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -612,15 +612,19 @@ check_java_method (tree method)
/* Sanity check: report error if this function FUNCTION is not
really a member of the class (CTYPE) it is supposed to belong to.
- CNAME is the same here as it is for grokclassfn above.
- TEMPLATE_HEADER_P is true when this declaration comes with a
- template header. */
+ TEMPLATE_PARMS is used to specifiy the template parameters of a member
+ template passed as FUNCTION_DECL. If the member template is passed as a
+ TEMPLATE_DECL, it can be NULL since the parameters can be extracted
+ from the declaration. If the function is not a function template, it
+ must be NULL.
+ It returns the original declaration for the function, or NULL_TREE
+ if no declaration was found (and an error was emitted). */
tree
-check_classfn (tree ctype, tree function, bool template_header_p)
+check_classfn (tree ctype, tree function, tree template_parms)
{
int ix;
- int is_template;
+ bool is_template;
if (DECL_USE_TEMPLATE (function)
&& !(TREE_CODE (function) == TEMPLATE_DECL
@@ -638,9 +642,20 @@ check_classfn (tree ctype, tree function, bool template_header_p)
find the method, but we don't complain. */
return NULL_TREE;
+ /* Basic sanity check: for a template function, the template parameters
+ either were not passed, or they are the same of DECL_TEMPLATE_PARMS. */
+ if (TREE_CODE (function) == TEMPLATE_DECL)
+ {
+ my_friendly_assert (!template_parms
+ || comp_template_parms
+ (template_parms,
+ DECL_TEMPLATE_PARMS (function)),
+ 20040303);
+ template_parms = DECL_TEMPLATE_PARMS (function);
+ }
+
/* OK, is this a definition of a member template? */
- is_template = (TREE_CODE (function) == TEMPLATE_DECL
- || template_header_p);
+ is_template = (template_parms != NULL_TREE);
ix = lookup_fnfields_1 (complete_type (ctype),
DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
@@ -684,6 +699,9 @@ check_classfn (tree ctype, tree function, bool template_header_p)
if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
TREE_TYPE (TREE_TYPE (fndecl)))
&& compparms (p1, p2)
+ && (!is_template
+ || comp_template_parms (template_parms,
+ DECL_TEMPLATE_PARMS (fndecl)))
&& (DECL_TEMPLATE_SPECIALIZATION (function)
== DECL_TEMPLATE_SPECIALIZATION (fndecl))
&& (!DECL_TEMPLATE_SPECIALIZATION (function)
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index c81bd934e0a..e55adaa8bc0 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -397,7 +397,10 @@ do_friend (tree ctype, tree declarator, tree decl,
validity of the declaration later. */
decl = push_template_decl_real (decl, /*is_friend=*/1);
else
- decl = check_classfn (ctype, decl, template_member_p);
+ decl = check_classfn (ctype, decl,
+ template_member_p
+ ? current_template_parms
+ : NULL_TREE);
if (template_member_p && decl && TREE_CODE (decl) == FUNCTION_DECL)
decl = DECL_TI_TEMPLATE (decl);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5d2c95ac155..96ee6875a56 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5142,8 +5142,8 @@ tsubst_friend_function (tree decl, tree args)
{
/* Check to see that the declaration is really present, and,
possibly obtain an improved declaration. */
- tree fn = check_classfn (DECL_CONTEXT (new_friend),
- new_friend, false);
+ tree fn = check_classfn (DECL_CONTEXT (new_friend),
+ new_friend, NULL_TREE);
if (fn)
new_friend = fn;
OpenPOWER on IntegriCloud