c++: Diagnose cv-qualified decltype(auto) [PR79815]
authorMarek Polacek <polacek@redhat.com>
Wed, 8 Jul 2020 23:45:34 +0000 (19:45 -0400)
committerMarek Polacek <polacek@redhat.com>
Fri, 17 Jul 2020 15:43:39 +0000 (11:43 -0400)
"If the placeholder is the decltype(auto) type-specifier, T shall be the
placeholder alone." but we weren't detecting "const decltype(auto)".

I've just expanded the existing diagnostic detecting "decltype(auto) &"
and similar.

gcc/cp/ChangeLog:

PR c++/79815
* decl.c (grokdeclarator): Detect cv-qual decltype(auto).
* pt.c (do_auto_deduction): Likewise.

gcc/testsuite/ChangeLog:

PR c++/79815
* g++.dg/cpp1y/auto-fn59.C: New test.

gcc/cp/decl.c
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp1y/auto-fn59.C [new file with mode: 0644]

index 6e4d546d55e7b0ce5e56e138a66361a7c8342a11..db91b50a4f0d36d58868575c9c3e2597f52c7c38 100644 (file)
@@ -12250,11 +12250,20 @@ grokdeclarator (const cp_declarator *declarator,
            /* Only plain decltype(auto) is allowed.  */
            if (tree a = type_uses_auto (type))
              {
-               if (AUTO_IS_DECLTYPE (a) && a != type)
+               if (AUTO_IS_DECLTYPE (a))
                  {
-                   error_at (typespec_loc, "%qT as type rather than "
-                             "plain %<decltype(auto)%>", type);
-                   return error_mark_node;
+                   if (a != type)
+                     {
+                       error_at (typespec_loc, "%qT as type rather than "
+                                 "plain %<decltype(auto)%>", type);
+                       return error_mark_node;
+                     }
+                   else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
+                     {
+                       error_at (typespec_loc, "%<decltype(auto)%> cannot be "
+                                 "cv-qualified");
+                       return error_mark_node;
+                     }
                  }
              }
 
index 4e1c77a6bd73b3fcee9785a1ed38655f178ab297..defc2a9abd840a5183b20ff25bbb1335804c855f 100644 (file)
@@ -28993,6 +28993,12 @@ do_auto_deduction (tree type, tree init, tree auto_node,
            error ("%qT as type rather than plain %<decltype(auto)%>", type);
          return error_mark_node;
        }
+      else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
+       {
+         if (complain & tf_error)
+           error ("%<decltype(auto)%> cannot be cv-qualified");
+         return error_mark_node;
+       }
     }
   else
     {
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn59.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn59.C
new file mode 100644 (file)
index 0000000..8f6ec9b
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/79815
+// { dg-do compile { target c++14 } }
+
+decltype(auto) const x = 1; // { dg-error "cannot be cv-qualified" }
+volatile decltype(auto) x2 = 1; // { dg-error "cannot be cv-qualified" }
+const volatile decltype(auto) x3 = 1; // { dg-error "cannot be cv-qualified" }
+const decltype(auto) fn() { return 42; } // { dg-error "cannot be cv-qualified" }
+const decltype(auto) fn2(); // { dg-error "cannot be cv-qualified" }