aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJoseph Myers <josmyers@redhat.com>2024-11-22 20:33:10 +0000
committerJoseph Myers <josmyers@redhat.com>2024-11-22 20:33:10 +0000
commit84a335eb4f9641a471184d86900609dd97215218 (patch)
tree4a0b1d3a538c3956c0c11918562e346483a0cfdf /gcc
parent684595188dea02d246edb66106d82bb7a9a22d79 (diff)
downloadgcc-84a335eb4f9641a471184d86900609dd97215218.zip
gcc-84a335eb4f9641a471184d86900609dd97215218.tar.gz
gcc-84a335eb4f9641a471184d86900609dd97215218.tar.bz2
c: Fix typeof_unqual handling of qualified array types [PR112841]
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c/c-parser.cc3
-rw-r--r--gcc/testsuite/gcc.dg/c23-typeof-4.c10
2 files changed, 12 insertions, 1 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index f3ed610..44d344f 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -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
index 0000000..471d082
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-typeof-4.c
@@ -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;