Two little things I noticed while working on another issue:
1) We were passing tf_none to tsubst_template_argument even when we want to explain a deduction failure.
2) We were calling tsubst_aggr_type and *then* checking whether it's a type. Tested x86_64-pc-linux-gnu, applying to trunk.
commit 319f3236e80f88852d19017ea472881e2d19c3e8 Author: Jason Merrill <ja...@redhat.com> Date: Tue Sep 6 22:17:18 2011 -0400 * pt.c (type_unification_real): Correct complain arg for tsubsting default template args. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d883c16..d326c84 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14804,6 +14804,10 @@ type_unification_real (tree tparms, if (!subr) { + tsubst_flags_t complain = (explain_p + ? tf_warning_or_error + : tf_none); + /* Check to see if we need another pass before we start clearing ARGUMENT_PACK_INCOMPLETE_P. */ for (i = 0; i < ntparms; i++) @@ -14854,11 +14858,8 @@ type_unification_real (tree tparms, { tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i)); tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i)); - arg = tsubst_template_arg (arg, targs, tf_none, NULL_TREE); - arg = convert_template_argument (parm, arg, targs, - (explain_p - ? tf_warning_or_error - : tf_none), + arg = tsubst_template_arg (arg, targs, complain, NULL_TREE); + arg = convert_template_argument (parm, arg, targs, complain, i, NULL_TREE); if (arg == error_mark_node) return 1; diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae11.C b/gcc/testsuite/g++.dg/cpp0x/sfinae11.C index e62c089..25902cb 100644 --- a/gcc/testsuite/g++.dg/cpp0x/sfinae11.C +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae11.C @@ -52,5 +52,6 @@ int main() noexcept( f1(z) ); // { dg-message "required" } static_assert( noexcept( f2(z) ), "shall be ill-formed." ); // { dg-error "no match|could not convert" } + // { dg-error "no member" "" { target *-*-* } 54 } noexcept( f3(z) ); // { dg-message "required" } } diff --git a/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc b/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc index daa815c..f5a08c2 100644 --- a/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc +++ b/libstdc++-v3/testsuite/20_util/bind/ref_neg.cc @@ -29,8 +29,8 @@ int inc(int& i) { return ++i; } void test01() { const int dummy = 0; - std::bind(&inc, _1)(0); // { dg-error "no match" } - std::bind(&inc, std::ref(dummy))(); // { dg-error "no match" } + std::bind(&inc, _1)(0); // { dg-error "no match|rvalue" } + std::bind(&inc, std::ref(dummy))(); // { dg-error "no match|const" } } struct Inc diff --git a/libstdc++-v3/testsuite/20_util/duration/cons/1_neg.cc b/libstdc++-v3/testsuite/20_util/duration/cons/1_neg.cc index eddd57c..97f4ef1 100644 --- a/libstdc++-v3/testsuite/20_util/duration/cons/1_neg.cc +++ b/libstdc++-v3/testsuite/20_util/duration/cons/1_neg.cc @@ -26,7 +26,7 @@ void test01() { - std::chrono::duration<int> d1(1.0); // { dg-error "no matching" } + std::chrono::duration<int> d1(1.0); // { dg-error "no matching|no type" } } void @@ -35,6 +35,6 @@ test02() using namespace std::chrono; duration<int, std::micro> d2(8); - duration<int, std::milli> d2_copy(d2); // { dg-error "no matching" } + duration<int, std::milli> d2_copy(d2); // { dg-error "no matching|no type" } }
commit 7a78b2be5ddd397e87c0781262ea1f37a040494a Author: Jason Merrill <ja...@redhat.com> Date: Tue Sep 6 22:02:14 2011 -0400 * pt.c (tsubst_aggr_type): Check TYPE_P before tsubsting. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 1f43ff1..d883c16 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9590,14 +9590,13 @@ tsubst_aggr_type (tree t, /* First, determine the context for the type we are looking up. */ context = TYPE_CONTEXT (t); - if (context) + if (context && TYPE_P (context)) { context = tsubst_aggr_type (context, args, complain, in_decl, /*entering_scope=*/1); /* If context is a nested class inside a class template, it may still need to be instantiated (c++/33959). */ - if (TYPE_P (context)) - context = complete_type (context); + context = complete_type (context); } /* Then, figure out what arguments are appropriate for the