This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for new testcase in c++/14912
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 29 Jul 2009 16:34:29 -0400
- Subject: C++ PATCH for new testcase in c++/14912
A recent comment to closed PR 14912 shows a problem with the patch:
substituting into the default template argument can require class
template instantiations that would not normally be needed, which is
particularly problematic if those instantiations are ill-formed. Fixed
thus.
Tested x86_64-pc-linux-gnu, applied to trunk.
2009-07-29 Jason Merrill <jason@redhat.com>
PR c++/14912
* cp-tree.h (enum tsubst_flags): Add tf_no_class_instantiations.
* error.c (count_non_default_template_args): Pass it.
* pt.c (tsubst) [TYPENAME_TYPE]: Don't complete type if it's set.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 2bc2d62..dcad934 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3616,6 +3616,8 @@ enum tsubst_flags {
conversion. */
tf_no_access_control = 1 << 7, /* Do not perform access checks, even
when issuing other errors. */
+ /* Do not instantiate classes (used by count_non_default_template_args). */
+ tf_no_class_instantiations = 1 << 8,
/* Convenient substitution flags combinations. */
tf_warning_or_error = tf_warning | tf_error
};
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index c5310ff..25a0580 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -182,7 +182,10 @@ count_non_default_template_args (tree args, tree params)
if (uses_template_parms (def))
{
++processing_template_decl;
- def = tsubst_copy_and_build (def, args, tf_none, NULL_TREE, false, true);
+ /* This speculative substitution must not cause any classes to be
+ instantiated that otherwise wouldn't be. */
+ def = tsubst_copy_and_build (def, args, tf_no_class_instantiations,
+ NULL_TREE, false, true);
--processing_template_decl;
}
if (!cp_tree_equal (TREE_VEC_ELT (inner_args, last), def))
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index de9f828..ed45324 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -9890,7 +9890,8 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
But, such constructs have already been resolved by this
point, so here CTX really should have complete type, unless
it's a partial instantiation. */
- ctx = complete_type (ctx);
+ if (!(complain & tf_no_class_instantiations))
+ ctx = complete_type (ctx);
if (!COMPLETE_TYPE_P (ctx))
{
if (complain & tf_error)
diff --git a/gcc/testsuite/g++.dg/template/defarg13.C b/gcc/testsuite/g++.dg/template/defarg13.C
new file mode 100644
index 0000000..ba2980b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/defarg13.C
@@ -0,0 +1,19 @@
+// PR c++/14912
+// Bug: We were instantiating A<B> in order to compare it to the matching
+// argument for C<B,B>, which fails.
+
+template <class T>
+struct A
+{
+ typedef typename T::F F;
+};
+
+struct B { };
+
+template <class T, class U = typename A<T>::F >
+struct C
+{
+ typename T::F f; // { dg-error "no type" }
+};
+
+C<B, B> c; // { dg-message "instantiated" }