aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2005-08-15 20:38:23 +0000
committerFariborz Jahanian <fjahanian@gcc.gnu.org>2005-08-15 20:38:23 +0000
commit30f86ec3fba12cb0574db51d75d3355f7264aa77 (patch)
tree9eb1bd6359f4248ee64777e3f0ec9b93df966070 /gcc
parentbe53afcf39fe960cc00e151afc7776683f0a677d (diff)
downloadgcc-30f86ec3fba12cb0574db51d75d3355f7264aa77.zip
gcc-30f86ec3fba12cb0574db51d75d3355f7264aa77.tar.gz
gcc-30f86ec3fba12cb0574db51d75d3355f7264aa77.tar.bz2
Fix Infinite Stack Recursion Regression.
* cp-tree.h (can_convert_arg, fn_type_unification): New argument. * call.c (add_template_candidate_real): Pass down 'flags' to fn_type_unification. (can_convert_arg): New 'flags' argument. Pass it to call to implicit_conversion instead of LOOKUP_NORMAL. (can_convert): Add LOOKUP_NORMAL to call to can_convert_arg. * class.c (resolve_address_of_overloaded_function): Ditto. (resolve_address_of_overloaded_function): Ditto. * decl.c (reshape_init, check_default_argument): Ditto. * typeck.c (build_ptrmemfunc): Ditto. * pt.c (type_unification_real): Add 'flags' argument. (fn_type_unification): Pass 'flags' to type_unification_real. (type_unification_real): Pass new 'flags' argument to call to can_convert_arg. Oked by Geoff Keating. From-SVN: r103120
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog17
-rw-r--r--gcc/cp/call.c8
-rw-r--r--gcc/cp/class.c7
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/decl.c4
-rw-r--r--gcc/cp/pt.c18
-rw-r--r--gcc/cp/typeck.c2
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/template/local6.C19
9 files changed, 64 insertions, 19 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 335d313..cdbd2b6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,20 @@
+2005-08-15 Fariborz Jahanian <fjahanian@apple.com>
+
+ * cp-tree.h (can_convert_arg, fn_type_unification): New argument.
+ * call.c (add_template_candidate_real): Pass down 'flags' to
+ fn_type_unification.
+ (can_convert_arg): New 'flags' argument. Pass it to call to
+ implicit_conversion instead of LOOKUP_NORMAL.
+ (can_convert): Add LOOKUP_NORMAL to call to can_convert_arg.
+ * class.c (resolve_address_of_overloaded_function): Ditto.
+ (resolve_address_of_overloaded_function): Ditto.
+ * decl.c (reshape_init, check_default_argument): Ditto.
+ * typeck.c (build_ptrmemfunc): Ditto.
+ * pt.c (type_unification_real): Add 'flags' argument.
+ (fn_type_unification): Pass 'flags' to type_unification_real.
+ (type_unification_real): Pass new 'flags' argument to call to
+ can_convert_arg.
+
2005-08-12 Giovanni Bajo <giovannibajo@libero.it>
Nathan Sidwell <nathan@codesourcery.com>
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index cdc068c..9f277cd 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -2203,7 +2203,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
i = fn_type_unification (tmpl, explicit_targs, targs,
args_without_in_chrg,
- return_type, strict);
+ return_type, strict, flags);
if (i != 0)
return NULL;
@@ -6286,13 +6286,13 @@ tourney (struct z_candidate *candidates)
bool
can_convert (tree to, tree from)
{
- return can_convert_arg (to, from, NULL_TREE);
+ return can_convert_arg (to, from, NULL_TREE, LOOKUP_NORMAL);
}
/* Returns nonzero if ARG (of type FROM) can be converted to TO. */
bool
-can_convert_arg (tree to, tree from, tree arg)
+can_convert_arg (tree to, tree from, tree arg, int flags)
{
conversion *t;
void *p;
@@ -6302,7 +6302,7 @@ can_convert_arg (tree to, tree from, tree arg)
p = conversion_obstack_alloc (0);
t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
- LOOKUP_NORMAL);
+ flags);
ok_p = (t && !t->bad_p);
/* Free all the conversions we allocated. */
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 4d57a73..98a8800 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5656,7 +5656,7 @@ resolve_address_of_overloaded_function (tree target_type,
else if (!is_reference)
fntype = build_pointer_type (fntype);
- if (can_convert_arg (target_type, fntype, fn))
+ if (can_convert_arg (target_type, fntype, fn, LOOKUP_NORMAL))
matches = tree_cons (fn, NULL_TREE, matches);
}
}
@@ -5704,7 +5704,7 @@ resolve_address_of_overloaded_function (tree target_type,
targs = make_tree_vec (DECL_NTPARMS (fn));
if (fn_type_unification (fn, explicit_targs, targs,
target_arg_types, target_ret_type,
- DEDUCE_EXACT))
+ DEDUCE_EXACT, LOOKUP_NORMAL))
/* Argument deduction failed. */
continue;
@@ -5721,7 +5721,8 @@ resolve_address_of_overloaded_function (tree target_type,
build_ptrmemfunc_type (build_pointer_type (instantiation_type));
else if (!is_reference)
instantiation_type = build_pointer_type (instantiation_type);
- if (can_convert_arg (target_type, instantiation_type, instantiation))
+ if (can_convert_arg (target_type, instantiation_type, instantiation,
+ LOOKUP_NORMAL))
matches = tree_cons (instantiation, fn, matches);
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 0ac7bba..ff9c8bb 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3650,7 +3650,7 @@ extern tree build_special_member_call (tree, tree, tree, tree, int);
extern tree build_new_op (enum tree_code, int, tree, tree, tree, bool *);
extern tree build_op_delete_call (enum tree_code, tree, tree, bool, tree);
extern bool can_convert (tree, tree);
-extern bool can_convert_arg (tree, tree, tree);
+extern bool can_convert_arg (tree, tree, tree, int);
extern bool can_convert_arg_bad (tree, tree, tree);
extern bool enforce_access (tree, tree);
extern tree convert_default_arg (tree, tree, tree, int);
@@ -3992,7 +3992,7 @@ extern int uses_template_parms_level (tree, int);
extern tree instantiate_class_template (tree);
extern tree instantiate_template (tree, tree, tsubst_flags_t);
extern int fn_type_unification (tree, tree, tree, tree,
- tree, unification_kind_t);
+ tree, unification_kind_t, int);
extern void mark_decl_instantiated (tree, int);
extern int more_specialized_fn (tree, tree, int);
extern void mark_class_instantiated (tree, int);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e2bd165..eb212c2 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4347,7 +4347,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
initializer is considered for the initialization of the first
member of the subaggregate. */
if (TREE_CODE (init) != CONSTRUCTOR
- && can_convert_arg (type, TREE_TYPE (init), init))
+ && can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL))
{
d->cur++;
return init;
@@ -8406,7 +8406,7 @@ check_default_argument (tree decl, tree arg)
A default argument expression is implicitly converted to the
parameter type. */
if (!TREE_TYPE (arg)
- || !can_convert_arg (decl_type, TREE_TYPE (arg), arg))
+ || !can_convert_arg (decl_type, TREE_TYPE (arg), arg, LOOKUP_NORMAL))
{
if (decl)
error ("default argument for %q#D has type %qT",
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a56dd04..73e2a25 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -109,7 +109,7 @@ static tree add_outermost_template_args (tree, tree);
static bool check_instantiated_args (tree, tree, tsubst_flags_t);
static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*);
static int type_unification_real (tree, tree, tree, tree,
- int, unification_kind_t);
+ int, unification_kind_t, int);
static void note_template_header (int);
static tree convert_nontype_argument_function (tree, tree);
static tree convert_nontype_argument (tree, tree);
@@ -9119,7 +9119,8 @@ fn_type_unification (tree fn,
tree targs,
tree args,
tree return_type,
- unification_kind_t strict)
+ unification_kind_t strict,
+ int flags)
{
tree parms;
tree fntype;
@@ -9197,7 +9198,7 @@ fn_type_unification (tree fn,
event. */
result = type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
targs, parms, args, /*subr=*/0,
- strict);
+ strict, flags);
if (result == 0)
/* All is well so far. Now, check:
@@ -9313,7 +9314,8 @@ type_unification_real (tree tparms,
tree xparms,
tree xargs,
int subr,
- unification_kind_t strict)
+ unification_kind_t strict,
+ int flags)
{
tree parm, arg;
int i;
@@ -9381,7 +9383,8 @@ type_unification_real (tree tparms,
if (same_type_p (parm, type))
continue;
if (strict != DEDUCE_EXACT
- && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg))
+ && can_convert_arg (parm, type, TYPE_P (arg) ? NULL_TREE : arg,
+ flags))
continue;
return 1;
@@ -10280,7 +10283,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
TREE_TYPE (arg), UNIFY_ALLOW_NONE))
return 1;
return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
- TYPE_ARG_TYPES (arg), 1, DEDUCE_EXACT);
+ TYPE_ARG_TYPES (arg), 1, DEDUCE_EXACT,
+ LOOKUP_NORMAL);
case OFFSET_TYPE:
/* Unify a pointer to member with a pointer to member function, which
@@ -10665,7 +10669,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
decl_arg_types,
(check_rettype || DECL_CONV_FN_P (fn)
? TREE_TYPE (decl_type) : NULL_TREE),
- DEDUCE_EXACT))
+ DEDUCE_EXACT, LOOKUP_NORMAL))
return NULL_TREE;
return targs;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 18d5bb6..3a3bbea 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5696,7 +5696,7 @@ build_ptrmemfunc (tree type, tree pfn, int force, bool c_cast_p)
tree n;
if (!force
- && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn))
+ && !can_convert_arg (to_type, TREE_TYPE (pfn), pfn, LOOKUP_NORMAL))
error ("invalid conversion to type %qT from type %qT",
to_type, pfn_type);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 65f56b9..c23ebec 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2005-08-15 Fariborz Jahanian <fjahanian@apple.com>
+
+ * g++.dg/template/local6.C: New test.
+
2005-08-14 Andrew Pinski <pinskia@physics.uc.edu>
* execute/exceptions/finally-1.m: Check that the catch and finally are
diff --git a/gcc/testsuite/g++.dg/template/local6.C b/gcc/testsuite/g++.dg/template/local6.C
new file mode 100644
index 0000000..3472f59
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/local6.C
@@ -0,0 +1,19 @@
+template <class T> struct PCVector2
+{ // { dg-error "" }
+ template <class T2> PCVector2(const PCVector2<T> &cv) ;
+
+ PCVector2<T> operator- (const PCVector2<T> &ov) const
+ {
+ return PCVector2<T>(ov.xFIELD, ov.yFIELD); // { dg-error "" }
+ }
+
+ T xFIELD, yFIELD;
+};
+
+void findIntersection( PCVector2<double>& p0, PCVector2<double>& p1);
+
+
+void findIntersection( PCVector2<double>& p0, PCVector2<double>& p1)
+{
+ PCVector2<double> e = p1 - p0; // { dg-error "" }
+}