From: Nathan Sidwell Date: Fri, 2 Apr 2004 11:48:56 +0000 (+0000) Subject: re PR c++/14007 (Incorrect use of const partial specialization for reference template... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2e9ceb77befba5b08e2e27eeed70550e5be570b2;p=gcc.git re PR c++/14007 (Incorrect use of const partial specialization for reference template argument) cp: PR c++/14007 * pt.c (check_cv_quals_for_unify): Correct logic for disallowed cv-qualifier unification. * tree.c (cp_build_qualified_type_real): Renable DR295 logic. testsuite: PR c++/14007 * g++.dg/template/unify5.C: New. * g++.dg/template/unify6.C: New. * g++.dg/template/qualttp20.C: Adjust. * g++.old-deja/g++.jason/report.C: Adjust. * g++.old-deja/g++.other/qual1.C: Adjust. From-SVN: r80351 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 75a948b4dc1..73aa9144902 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2004-04-02 Nathan Sidwell + + PR c++/14007 + * pt.c (check_cv_quals_for_unify): Correct logic for disallowed + cv-qualifier unification. + * tree.c (cp_build_qualified_type_real): Renable DR295 logic. + 2004-04-02 Jan Hubicka * cp-lang. (LANG_HOOKS_UPDATE_DECL_AFTER_SAVING): Define. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b096017430e..fd38b0a381c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9543,7 +9543,7 @@ template_decl_level (tree decl) /* Decide whether ARG can be unified with PARM, considering only the cv-qualifiers of each type, given STRICT as documented for unify. - Returns nonzero iff the unification is OK on that basis.*/ + Returns nonzero iff the unification is OK on that basis. */ static int check_cv_quals_for_unify (int strict, tree arg, tree parm) @@ -9553,15 +9553,22 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm) if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM) { - /* If the cvr quals of parm will not unify with ARG, they'll be - ignored in instantiation, so we have to do the same here. */ - if (TREE_CODE (arg) == REFERENCE_TYPE) - parm_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); - if (!POINTER_TYPE_P (arg) && - TREE_CODE (arg) != TEMPLATE_TYPE_PARM) - parm_quals &= ~TYPE_QUAL_RESTRICT; + /* Although a CVR qualifier is ignored when being applied to a + substituted template parameter ([8.3.2]/1 for example), that + does not apply during deduction [14.8.2.4]/1, (even though + that is not explicitly mentioned, [14.8.2.4]/9 indicates + this). */ + if ((TREE_CODE (arg) == REFERENCE_TYPE + || TREE_CODE (arg) == FUNCTION_TYPE + || TREE_CODE (arg) == METHOD_TYPE) + && (parm_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))) + return 0; + + if ((!POINTER_TYPE_P (arg) && TREE_CODE (arg) != TEMPLATE_TYPE_PARM) + && (parm_quals & TYPE_QUAL_RESTRICT)) + return 0; } - + if (!(strict & (UNIFY_ALLOW_MORE_CV_QUAL | UNIFY_ALLOW_OUTER_MORE_CV_QUAL)) && (arg_quals & parm_quals) != parm_quals) return 0; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index afa5c4b445c..adf3b391114 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -433,11 +433,6 @@ cp_build_qualified_type_real (tree type, { tree result; int bad_quals = TYPE_UNQUALIFIED; - /* We keep bad function qualifiers separate, so that we can decide - whether to implement DR 295 or not. DR 295 break existing code, - unfortunately. Remove this variable to implement the defect - report. */ - int bad_func_quals = TYPE_UNQUALIFIED; if (type == error_mark_node) return type; @@ -507,8 +502,6 @@ cp_build_qualified_type_real (tree type, || TREE_CODE (type) == METHOD_TYPE)) { bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); - if (TREE_CODE (type) != REFERENCE_TYPE) - bad_func_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); } @@ -527,21 +520,17 @@ cp_build_qualified_type_real (tree type, /*OK*/; else if (!(complain & (tf_error | tf_ignore_bad_quals))) return error_mark_node; - else if (bad_func_quals && !(complain & tf_error)) - return error_mark_node; else { if (complain & tf_ignore_bad_quals) /* We're not going to warn about constifying things that can't be constified. */ bad_quals &= ~TYPE_QUAL_CONST; - bad_quals |= bad_func_quals; if (bad_quals) { tree bad_type = build_qualified_type (ptr_type_node, bad_quals); - if (!(complain & tf_ignore_bad_quals) - || bad_func_quals) + if (!(complain & tf_ignore_bad_quals)) error ("`%V' qualifiers cannot be applied to `%T'", bad_type, type); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 41d311a3860..420a53d49a4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2004-04-02 Nathan Sidwell + + PR c++/14007 + * g++.dg/template/unify5.C: New. + * g++.dg/template/unify6.C: New. + * g++.dg/template/qualttp20.C: Adjust. + * g++.old-deja/g++.jason/report.C: Adjust. + * g++.old-deja/g++.other/qual1.C: Adjust. + 2004-04-01 Mark Mitchell PR c++/14803 diff --git a/gcc/testsuite/g++.dg/template/qualttp20.C b/gcc/testsuite/g++.dg/template/qualttp20.C index 13f07e14c5c..e58e2d2748d 100644 --- a/gcc/testsuite/g++.dg/template/qualttp20.C +++ b/gcc/testsuite/g++.dg/template/qualttp20.C @@ -19,17 +19,17 @@ template struct B1 : T typedef typename T::myT __restrict__ p;// { dg-warning "ignoring `__restrict__'" "" { xfail *-*-* } } // The following are DR 295 dependent - typedef typename T::myT volatile *myvolatile; // { dg-error "qualifiers" "" } - typename T::myT volatile *a; // { dg-error "qualifiers" "" } - myvolatile b; // { dg-error "qualifiers" "" } + typedef typename T::myT volatile *myvolatile; + typename T::myT volatile *a; + myvolatile b; }; template struct B2 : T { // The following are DR 295 dependent - typedef typename T::myT const *myconst; // { dg-error "qualifiers" "" } - typename T::myT const *a; // { dg-error "qualifiers" "" } - myconst b; // { dg-error "qualifiers" "" } + typedef typename T::myT const *myconst; + typename T::myT const *a; + myconst b; }; B1 b1; // { dg-error "instantiated" "" } -B2 b2; // { dg-error "instantiated" "" } +B2 b2; diff --git a/gcc/testsuite/g++.dg/template/unify5.C b/gcc/testsuite/g++.dg/template/unify5.C new file mode 100644 index 00000000000..6928f1f8429 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify5.C @@ -0,0 +1,10 @@ + +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 1 Apr 2004 +// Origin:Matt Austern + +// PR:c++/14007 + +template struct X {}; // #1 +template struct X; //#2 +template struct X; //#3 diff --git a/gcc/testsuite/g++.dg/template/unify6.C b/gcc/testsuite/g++.dg/template/unify6.C new file mode 100644 index 00000000000..ee6a8ce0fdb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/unify6.C @@ -0,0 +1,22 @@ +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 1 Apr 2004 + +void Baz (); + +template void Foo1 (T *); // #1 +template void Foo1 (T const *a) {a (1);} // #2 + +template T const *Foo2 (T *); + +template void Foo3 (T *, T const * = 0); + +void Bar () +{ + Foo1 (&Baz); // #1 + + Foo2 (&Baz); + + Foo3 (&Baz); + + Foo3 (&Baz, &Baz); // { dg-error "no matching function" "" } +} diff --git a/gcc/testsuite/g++.old-deja/g++.jason/report.C b/gcc/testsuite/g++.old-deja/g++.jason/report.C index fad87fcd024..13557f166ef 100644 --- a/gcc/testsuite/g++.old-deja/g++.jason/report.C +++ b/gcc/testsuite/g++.old-deja/g++.jason/report.C @@ -47,8 +47,8 @@ class X{ typedef int const * bart (); //The following is DR295 dependant -typedef bart const * const * bar2; // { dg-error "" } constifying qualifiers -typedef bart volatile * const * bar2v; // { dg-error "" } qualifiers +typedef bart const * const * bar2; +typedef bart volatile * const * bar2v; bar2 baz (X::Y y) { // { dg-error "" } in this context diff --git a/gcc/testsuite/g++.old-deja/g++.other/qual1.C b/gcc/testsuite/g++.old-deja/g++.other/qual1.C index 8040ee29695..b6eba42ddcf 100644 --- a/gcc/testsuite/g++.old-deja/g++.other/qual1.C +++ b/gcc/testsuite/g++.old-deja/g++.other/qual1.C @@ -11,8 +11,8 @@ class C public: func_type *Function; // The following is DR 295 dependent - const func_type* function(void) { return Function; } // { dg-error "" } constifying - volatile func_type* functionv(void); // { dg-error "" } qualifier + const func_type* function(void) { return Function; } + volatile func_type* functionv(void); } action; void work(const char *source)