Commit 2e9ceb77 by Nathan Sidwell Committed by Nathan Sidwell

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
parent efe4ba3d
2004-04-02 Nathan Sidwell <nathan@codesourcery.com>
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 <jh@suse.cz> 2004-04-02 Jan Hubicka <jh@suse.cz>
* cp-lang. (LANG_HOOKS_UPDATE_DECL_AFTER_SAVING): Define. * cp-lang. (LANG_HOOKS_UPDATE_DECL_AFTER_SAVING): Define.
......
...@@ -9543,7 +9543,7 @@ template_decl_level (tree decl) ...@@ -9543,7 +9543,7 @@ template_decl_level (tree decl)
/* Decide whether ARG can be unified with PARM, considering only the /* Decide whether ARG can be unified with PARM, considering only the
cv-qualifiers of each type, given STRICT as documented for unify. 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 static int
check_cv_quals_for_unify (int strict, tree arg, tree parm) 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) ...@@ -9553,15 +9553,22 @@ check_cv_quals_for_unify (int strict, tree arg, tree parm)
if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM) if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM)
{ {
/* If the cvr quals of parm will not unify with ARG, they'll be /* Although a CVR qualifier is ignored when being applied to a
ignored in instantiation, so we have to do the same here. */ substituted template parameter ([8.3.2]/1 for example), that
if (TREE_CODE (arg) == REFERENCE_TYPE) does not apply during deduction [14.8.2.4]/1, (even though
parm_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); that is not explicitly mentioned, [14.8.2.4]/9 indicates
if (!POINTER_TYPE_P (arg) && this). */
TREE_CODE (arg) != TEMPLATE_TYPE_PARM) if ((TREE_CODE (arg) == REFERENCE_TYPE
parm_quals &= ~TYPE_QUAL_RESTRICT; || 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)) if (!(strict & (UNIFY_ALLOW_MORE_CV_QUAL | UNIFY_ALLOW_OUTER_MORE_CV_QUAL))
&& (arg_quals & parm_quals) != parm_quals) && (arg_quals & parm_quals) != parm_quals)
return 0; return 0;
......
...@@ -433,11 +433,6 @@ cp_build_qualified_type_real (tree type, ...@@ -433,11 +433,6 @@ cp_build_qualified_type_real (tree type,
{ {
tree result; tree result;
int bad_quals = TYPE_UNQUALIFIED; 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) if (type == error_mark_node)
return type; return type;
...@@ -507,8 +502,6 @@ cp_build_qualified_type_real (tree type, ...@@ -507,8 +502,6 @@ cp_build_qualified_type_real (tree type,
|| TREE_CODE (type) == METHOD_TYPE)) || TREE_CODE (type) == METHOD_TYPE))
{ {
bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); 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); type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
} }
...@@ -527,21 +520,17 @@ cp_build_qualified_type_real (tree type, ...@@ -527,21 +520,17 @@ cp_build_qualified_type_real (tree type,
/*OK*/; /*OK*/;
else if (!(complain & (tf_error | tf_ignore_bad_quals))) else if (!(complain & (tf_error | tf_ignore_bad_quals)))
return error_mark_node; return error_mark_node;
else if (bad_func_quals && !(complain & tf_error))
return error_mark_node;
else else
{ {
if (complain & tf_ignore_bad_quals) if (complain & tf_ignore_bad_quals)
/* We're not going to warn about constifying things that can't /* We're not going to warn about constifying things that can't
be constified. */ be constified. */
bad_quals &= ~TYPE_QUAL_CONST; bad_quals &= ~TYPE_QUAL_CONST;
bad_quals |= bad_func_quals;
if (bad_quals) if (bad_quals)
{ {
tree bad_type = build_qualified_type (ptr_type_node, bad_quals); tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
if (!(complain & tf_ignore_bad_quals) if (!(complain & tf_ignore_bad_quals))
|| bad_func_quals)
error ("`%V' qualifiers cannot be applied to `%T'", error ("`%V' qualifiers cannot be applied to `%T'",
bad_type, type); bad_type, type);
} }
......
2004-04-02 Nathan Sidwell <nathan@codesourcery.com>
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 <mark@codesourcery.com> 2004-04-01 Mark Mitchell <mark@codesourcery.com>
PR c++/14803 PR c++/14803
......
...@@ -19,17 +19,17 @@ template <typename T> struct B1 : T ...@@ -19,17 +19,17 @@ template <typename T> struct B1 : T
typedef typename T::myT __restrict__ p;// { dg-warning "ignoring `__restrict__'" "" { xfail *-*-* } } typedef typename T::myT __restrict__ p;// { dg-warning "ignoring `__restrict__'" "" { xfail *-*-* } }
// The following are DR 295 dependent // The following are DR 295 dependent
typedef typename T::myT volatile *myvolatile; // { dg-error "qualifiers" "" } typedef typename T::myT volatile *myvolatile;
typename T::myT volatile *a; // { dg-error "qualifiers" "" } typename T::myT volatile *a;
myvolatile b; // { dg-error "qualifiers" "" } myvolatile b;
}; };
template <typename T> struct B2 : T template <typename T> struct B2 : T
{ {
// The following are DR 295 dependent // The following are DR 295 dependent
typedef typename T::myT const *myconst; // { dg-error "qualifiers" "" } typedef typename T::myT const *myconst;
typename T::myT const *a; // { dg-error "qualifiers" "" } typename T::myT const *a;
myconst b; // { dg-error "qualifiers" "" } myconst b;
}; };
B1<AS> b1; // { dg-error "instantiated" "" } B1<AS> b1; // { dg-error "instantiated" "" }
B2<AS> b2; // { dg-error "instantiated" "" } B2<AS> b2;
// Copyright (C) 2004 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 1 Apr 2004 <nathan@codesourcery.com>
// Origin:Matt Austern <austern@apple.com>
// PR:c++/14007
template <typename T> struct X {}; // #1
template <typename T> struct X<const T>; //#2
template struct X<int&>; //#3
// Copyright (C) 2004 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 1 Apr 2004 <nathan@codesourcery.com>
void Baz ();
template <typename T> void Foo1 (T *); // #1
template <typename T> void Foo1 (T const *a) {a (1);} // #2
template <typename T> T const *Foo2 (T *);
template <typename T> void Foo3 (T *, T const * = 0);
void Bar ()
{
Foo1 (&Baz); // #1
Foo2 (&Baz);
Foo3 (&Baz);
Foo3 (&Baz, &Baz); // { dg-error "no matching function" "" }
}
...@@ -47,8 +47,8 @@ class X{ ...@@ -47,8 +47,8 @@ class X{
typedef int const * bart (); typedef int const * bart ();
//The following is DR295 dependant //The following is DR295 dependant
typedef bart const * const * bar2; // { dg-error "" } constifying qualifiers typedef bart const * const * bar2;
typedef bart volatile * const * bar2v; // { dg-error "" } qualifiers typedef bart volatile * const * bar2v;
bar2 baz (X::Y y) bar2 baz (X::Y y)
{ // { dg-error "" } in this context { // { dg-error "" } in this context
......
...@@ -11,8 +11,8 @@ class C ...@@ -11,8 +11,8 @@ class C
public: public:
func_type *Function; func_type *Function;
// The following is DR 295 dependent // The following is DR 295 dependent
const func_type* function(void) { return Function; } // { dg-error "" } constifying const func_type* function(void) { return Function; }
volatile func_type* functionv(void); // { dg-error "" } qualifier volatile func_type* functionv(void);
} action; } action;
void work(const char *source) void work(const char *source)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment