@@ -1356,12 +1356,22 @@ cp_build_qualified_type_real (tree type,
/* A reference or method type shall not be cv-qualified.
[dcl.ref], [dcl.fct]. This used to be an error, but as of DR 295
(in CD1) we always ignore extra cv-quals on functions. */
+
+ /* PR 101783
+ Cv-qualified references are ill-formed except when the cv-qualifiers
+ are introduced through the use of a typedef-name ([dcl.typedef],
+ [temp.param]) or decltype-specifier ([dcl.type.decltype]),
+ in which case the cv-qualifiers are ignored.
+ */
if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
&& (TYPE_REF_P (type)
|| FUNC_OR_METHOD_TYPE_P (type)))
{
- if (TYPE_REF_P (type))
+ // do NOT set bad_quals when non-method reference is introduced by typedef.
+ if (TYPE_REF_P (type)
+ && (!typedef_variant_p (type) || FUNC_OR_METHOD_TYPE_P (type)))
bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ // non-method reference introduced by typedef is also dropped silently
type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
}
new file mode 100644
@@ -0,0 +1,5 @@
+template<class T> struct A{
+ typedef T& Type;
+};
+template<class T> void f(const typename A<T>::Type){}
+template <> void f<int>(const typename A<int>::Type){}