*PING* Re: [PATCH] c++: Suppress error when cv-qualified reference is introduced by typedef [PR101783]
Commit Message
Reference with cv-qualifiers should be ignored instead of causing an error
because standard accepts cv-qualified references introduced by typedef which
is ignored.
Therefore, the fix prevents GCC from reporting error by not setting variable
"bad_quals" in case the reference is introduced by typedef. Still the
cv-qualifier is silently ignored.
Here I quote spec (https://timsong-cpp.github.io/cppwp/dcl.ref#1):
"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."
PR c++/101783
gcc/cp/ChangeLog:
2021-08-27 qingzhe huang <nickhuang99@hotmail.com>
* tree.c (cp_build_qualified_type_real):
gcc/testsuite/ChangeLog:
2021-08-27 qingzhe huang <nickhuang99@hotmail.com>
* g++.dg/parse/pr101783.C: New test.
@@ -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){}