From 195584ff788e48c111a2613104bb968f0b6bc527 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 19 May 2010 11:44:08 -0400 Subject: [PATCH] re PR c++/44193 (function types, cv-quals and typename) PR c++/44193 * pt.c (tsubst) [TYPENAME_TYPE]: Discard cv-quals on function/reference type. From-SVN: r159575 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/pt.c | 12 +++++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/template/fntype1.C | 26 +++++++++++++++++++++++ gcc/testsuite/g++.dg/template/qualttp20.C | 2 +- 5 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/fntype1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5b891c00a883..df69a8ec077e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2010-05-19 Jason Merrill + + PR c++/44193 + * pt.c (tsubst) [TYPENAME_TYPE]: Discard cv-quals on + function/reference type. + 2010-04-20 Richard Guenther Backport from mainline diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 46866c030485..434e0cf8bfff 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9411,6 +9411,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) in_decl, /*entering_scope=*/1); tree f = tsubst_copy (TYPENAME_TYPE_FULLNAME (t), args, complain, in_decl); + int quals; if (ctx == error_mark_node || f == error_mark_node) return error_mark_node; @@ -9460,8 +9461,15 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) t, f); } - return cp_build_qualified_type_real - (f, cp_type_quals (f) | cp_type_quals (t), complain); + /* cv-quals from the template are discarded when + substituting in a function or reference type. */ + if (TREE_CODE (f) == FUNCTION_TYPE + || TREE_CODE (f) == METHOD_TYPE + || TREE_CODE (f) == REFERENCE_TYPE) + quals = cp_type_quals (f); + else + quals = cp_type_quals (f) | cp_type_quals (t); + return cp_build_qualified_type_real (f, quals, complain); } case UNBOUND_CLASS_TEMPLATE: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 93a89110b605..d5955128b94a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-05-19 Jason Merrill + + PR c++/44193 + * g++.dg/template/fntype1.C: New. + 2010-04-30 DJ Delorie * gcc.c-torture/execute/20100430-1.c: New test. diff --git a/gcc/testsuite/g++.dg/template/fntype1.C b/gcc/testsuite/g++.dg/template/fntype1.C new file mode 100644 index 000000000000..d7be273aa421 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/fntype1.C @@ -0,0 +1,26 @@ +bool f(int i) { return i != 5; } + +template +struct Traits +{ + typedef P type; +}; + +template ::type> +struct S +{ + const P& p_; + S( const P& p ) : p_(p) {} // const reference +}; + +template +S make_s(const typename Traits::type & p) // const reference +{ + return S(p); // << HERE +} + + +int main() +{ + make_s(f); +} diff --git a/gcc/testsuite/g++.dg/template/qualttp20.C b/gcc/testsuite/g++.dg/template/qualttp20.C index ae20d7629020..ea581db54465 100644 --- a/gcc/testsuite/g++.dg/template/qualttp20.C +++ b/gcc/testsuite/g++.dg/template/qualttp20.C @@ -17,7 +17,7 @@ struct AS template struct B1 : T { typedef typename T::L __restrict__ r;// { dg-error "'__restrict__' qualifiers cannot" "" } - typedef typename T::myT __restrict__ p;// { dg-error "ignoring '__restrict__'" } + typedef typename T::myT __restrict__ p; // The following are DR 295 dependent typedef typename T::myT volatile *myvolatile; -- 2.47.2