aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@yorick.cygnus.com>1999-03-09 19:37:02 +0000
committerJason Merrill <jason@gcc.gnu.org>1999-03-09 14:37:02 -0500
commit8f96c7ac27203b9c74a1d244c52ce242b65e8681 (patch)
treee76fcf35fd811414c2922db3992bb03de0cefd7b
parent19f019c25c29269223cb246c2a86cb48ec792bbd (diff)
downloadgcc-8f96c7ac27203b9c74a1d244c52ce242b65e8681.zip
gcc-8f96c7ac27203b9c74a1d244c52ce242b65e8681.tar.gz
gcc-8f96c7ac27203b9c74a1d244c52ce242b65e8681.tar.bz2
call.c (add_function_candidate): Check for proper number of args before checking the validity of those args.
* call.c (add_function_candidate): Check for proper number of args before checking the validity of those args. From-SVN: r25660
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/call.c68
2 files changed, 53 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 602fa44..3ec99ad 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+1999-03-09 Jason Merrill <jason@yorick.cygnus.com>
+
+ * call.c (add_function_candidate): Check for proper number of args
+ before checking the validity of those args.
+
1999-03-06 Jason Merrill <jason@yorick.cygnus.com>
* cp-tree.h (struct lang_type): Add anon_union field.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 9bf5035..e6b1125 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1134,24 +1134,60 @@ add_function_candidate (candidates, fn, arglist, flags)
tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
int i, len;
tree convs;
- tree parmnode = parmlist;
- tree argnode = arglist;
+ tree parmnode, argnode;
int viable = 1;
/* The `this' and `in_chrg' arguments to constructors are not considered
in overload resolution. */
if (DECL_CONSTRUCTOR_P (fn))
{
- parmnode = TREE_CHAIN (parmnode);
- argnode = TREE_CHAIN (argnode);
+ parmlist = TREE_CHAIN (parmlist);
+ arglist = TREE_CHAIN (arglist);
if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn)))
{
- parmnode = TREE_CHAIN (parmnode);
- argnode = TREE_CHAIN (argnode);
+ parmlist = TREE_CHAIN (parmlist);
+ arglist = TREE_CHAIN (arglist);
}
}
- len = list_length (argnode);
+ len = list_length (arglist);
+
+ /* 13.3.2 - Viable functions [over.match.viable]
+ First, to be a viable function, a candidate function shall have enough
+ parameters to agree in number with the arguments in the list.
+
+ We need to check this first; otherwise, checking the ICSes might cause
+ us to produce an ill-formed template instantiation. */
+
+ parmnode = parmlist;
+ for (i = 0; i < len; ++i)
+ {
+ if (parmnode == NULL_TREE || parmnode == void_list_node)
+ break;
+ parmnode = TREE_CHAIN (parmnode);
+ }
+
+ if (i < len && parmnode)
+ viable = 0;
+
+ /* Make sure there are default args for the rest of the parms. */
+ else for (; parmnode && parmnode != void_list_node;
+ parmnode = TREE_CHAIN (parmnode))
+ if (! TREE_PURPOSE (parmnode))
+ {
+ viable = 0;
+ break;
+ }
+
+ if (! viable)
+ goto out;
+
+ /* Second, for F to be a viable function, there shall exist for each
+ argument an implicit conversion sequence that converts that argument
+ to the corresponding parameter of F. */
+
+ parmnode = parmlist;
+ argnode = arglist;
convs = make_scratch_vec (len);
for (i = 0; i < len; ++i)
@@ -1196,7 +1232,10 @@ add_function_candidate (candidates, fn, arglist, flags)
TREE_VEC_ELT (convs, i) = t;
if (! t)
- break;
+ {
+ viable = 0;
+ break;
+ }
if (ICS_BAD_FLAG (t))
viable = -1;
@@ -1206,18 +1245,7 @@ add_function_candidate (candidates, fn, arglist, flags)
argnode = TREE_CHAIN (argnode);
}
- if (i < len)
- viable = 0;
-
- /* Make sure there are default args for the rest of the parms. */
- for (; parmnode && parmnode != void_list_node;
- parmnode = TREE_CHAIN (parmnode))
- if (! TREE_PURPOSE (parmnode))
- {
- viable = 0;
- break;
- }
-
+ out:
return add_candidate (candidates, fn, convs, viable);
}