]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c: Fix typeof_unqual handling of qualified array types [PR112841]
authorJoseph Myers <josmyers@redhat.com>
Fri, 22 Nov 2024 20:33:10 +0000 (20:33 +0000)
committerJoseph Myers <josmyers@redhat.com>
Fri, 22 Nov 2024 20:33:10 +0000 (20:33 +0000)
As reported in bug 112841, typeof_unqual fails to remove qualifiers
from qualified array types.  In C23 (unlike in previous standard
versions), array types are considered to have the qualifiers of the
element type, so typeof_unqual should remove such qualifiers (and an
example in the standard shows that is as intended).  Fix this by
calling strip_array_types when checking for the presence of
qualifiers.  (The reason we check for qualifiers rather than just
using TYPE_MAIN_VARIANT unconditionally is to avoid, as a quality of
implementation matter, unnecessarily losing typedef information in the
case where the type is already unqualified.)

Bootstrapped with no regressions for x86_64-pc-linux-gnu.

PR c/112841

gcc/c/
* c-parser.cc (c_parser_typeof_specifier): Call strip_array_types
when checking for type qualifiers for typeof_unqual.

gcc/testsuite/
* gcc.dg/c23-typeof-4.c: New test.

gcc/c/c-parser.cc
gcc/testsuite/gcc.dg/c23-typeof-4.c [new file with mode: 0644]

index f3ed61047477ca5816bf825ae92049ede9e0c5d4..44d344fcd32abebe6d0bfef329259ab870a26aca 100644 (file)
@@ -4444,7 +4444,8 @@ c_parser_typeof_specifier (c_parser *parser)
   parens.skip_until_found_close (parser);
   if (ret.spec != error_mark_node)
     {
-      if (is_unqual && TYPE_QUALS (ret.spec) != TYPE_UNQUALIFIED)
+      if (is_unqual
+         && TYPE_QUALS (strip_array_types (ret.spec)) != TYPE_UNQUALIFIED)
        ret.spec = TYPE_MAIN_VARIANT (ret.spec);
       if (is_std)
        {
diff --git a/gcc/testsuite/gcc.dg/c23-typeof-4.c b/gcc/testsuite/gcc.dg/c23-typeof-4.c
new file mode 100644 (file)
index 0000000..471d082
--- /dev/null
@@ -0,0 +1,10 @@
+/* Test C23 typeof and typeof_unqual on qualified arrays (bug 112841).  */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+const int a[] = { 1, 2, 3 };
+int b[3];
+extern typeof (a) a;
+extern typeof (const int [3]) a;
+extern typeof_unqual (a) b;
+extern typeof_unqual (const int [3]) b;