From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id B063A3858288 for ; Thu, 10 Aug 2023 15:33:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B063A3858288 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1691681592; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references; bh=VlY5rM8lGcjnQTMZjDFx7Jtgoy6aoO96FsPMMIwNVgg=; b=Hlp7Ig6Qt4zCZgp2mKwrbGoWBTGLHXYfYb7nQ0s0EPPzzy68WDm+H81SMgs8gly+dF08JK FSRobSgvuQWV2RcoUc0e1gkDImGnQPkxdy2ToCjWhN67xHB8AA2oCQhIO/dvW21/SQC5y9 Or4vKVrgejkwElwNg1w1gZZPLiuYvyA= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-462-r3ajs9nMP0C5DaVyDsKYWA-1; Thu, 10 Aug 2023 11:33:10 -0400 X-MC-Unique: r3ajs9nMP0C5DaVyDsKYWA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 910B8858EED; Thu, 10 Aug 2023 15:33:10 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.225.169]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 301A2140E91B; Thu, 10 Aug 2023 15:33:10 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 37AFX7I52356851 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Thu, 10 Aug 2023 17:33:07 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 37AFX6nP2356850; Thu, 10 Aug 2023 17:33:06 +0200 Date: Thu, 10 Aug 2023 17:33:06 +0200 From: Jakub Jelinek To: "Joseph S. Myers" , Marek Polacek , gcc-patches@gcc.gnu.org Subject: [PATCH] c, v2: Add __typeof_unqual__ and __typeof_unqual support Message-ID: Reply-To: Jakub Jelinek References: MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hi! I'd like to ping this patch. Reposting it as the extend.texi hunk didn't apply cleanly anymore. Bootstrapped/regtested again on x86_64-linux and i686-linux, ok for trunk? On Mon, Jun 12, 2023 at 09:51:22PM +0200, Jakub Jelinek via Gcc-patches wrote: > As I mentioned in my stdckdint.h mail, I think having __ prefixed > keywords for the typeof_unqual keyword which can be used in earlier > language modes can be useful, not all code can be switched to C23 > right away. > > The following patch implements that. It keeps the non-C23 behavior > for it for the _Noreturn functions to stay compatible with how > __typeof__ behaves. > > I think we don't need it for C++, in C++ we have standard > traits to remove qualifiers etc. 2023-08-10 Jakub Jelinek gcc/ * doc/extend.texi (Typeof): Document typeof_unqual and __typeof_unqual__. gcc/c-family/ * c-common.cc (c_common_reswords): Add __typeof_unqual and __typeof_unqual__ spellings of typeof_unqual. gcc/c/ * c-parser.cc (c_parser_typeof_specifier): Handle __typeof_unqual and __typeof_unqual__ as !is_std. gcc/testsuite/ * gcc.dg/c11-typeof-2.c: New test. * gcc.dg/c11-typeof-3.c: New test. * gcc.dg/gnu11-typeof-3.c: New test. * gcc.dg/gnu11-typeof-4.c: New test. --- gcc/c-family/c-common.cc.jj 2023-05-20 15:31:09.070663296 +0200 +++ gcc/c-family/c-common.cc 2023-06-10 19:20:11.106910976 +0200 @@ -420,6 +420,8 @@ const struct c_common_resword c_common_r { "__transaction_cancel", RID_TRANSACTION_CANCEL, 0 }, { "__typeof", RID_TYPEOF, 0 }, { "__typeof__", RID_TYPEOF, 0 }, + { "__typeof_unqual", RID_TYPEOF_UNQUAL, D_CONLY }, + { "__typeof_unqual__", RID_TYPEOF_UNQUAL, D_CONLY }, { "__volatile", RID_VOLATILE, 0 }, { "__volatile__", RID_VOLATILE, 0 }, { "__GIMPLE", RID_GIMPLE, D_CONLY }, --- gcc/c/c-parser.cc.jj 2023-06-06 20:02:35.587211846 +0200 +++ gcc/c/c-parser.cc 2023-06-10 19:22:15.577205685 +0200 @@ -4126,7 +4126,8 @@ c_parser_typeof_specifier (c_parser *par { gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF_UNQUAL)); is_unqual = true; - is_std = true; + tree spelling = c_parser_peek_token (parser)->value; + is_std = strcmp (IDENTIFIER_POINTER (spelling), "typeof_unqual") == 0; } c_parser_consume_token (parser); c_inhibit_evaluation_warnings++; --- gcc/doc/extend.texi.jj 2023-08-10 12:59:04.588094460 +0200 +++ gcc/doc/extend.texi 2023-08-10 13:00:09.301167471 +0200 @@ -843,6 +843,13 @@ Thus, @code{array (pointer (char), 4)} i pointers to @code{char}. @end itemize +The ISO C2X operator @code{typeof_unqual} is available in ISO C2X mode +and its result is the non-atomic unqualified version of what @code{typeof} +operator returns. Alternate spelling @code{__typeof_unqual__} is +available in all C modes and provides non-atomic unqualified version of +what @code{__typeof__} operator returns. +@xref{Alternate Keywords}. + @cindex @code{__auto_type} in GNU C In GNU C, but not GNU C++, you may also declare the type of a variable as @code{__auto_type}. In that case, the declaration must declare --- gcc/testsuite/gcc.dg/c11-typeof-2.c.jj 2023-06-10 19:27:38.675779747 +0200 +++ gcc/testsuite/gcc.dg/c11-typeof-2.c 2023-06-10 19:42:27.450606301 +0200 @@ -0,0 +1,177 @@ +/* Test GNU extensions __typeof__ and __typeof_unqual__. Valid code. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +int i; +extern __typeof__ (i) i; +extern __typeof (int) i; +extern __typeof_unqual__ (i) i; +extern __typeof_unqual (int) i; + +volatile int vi; +extern __typeof__ (volatile int) vi; +extern __typeof (vi) vi; + +extern __typeof_unqual__ (volatile int) i; +extern __typeof_unqual__ (vi) i; +extern __typeof__ ((const int) vi) i; +extern __typeof ((volatile int) vi) i; + +const int ci; +extern __typeof (const int) ci; +extern __typeof (ci) ci; + +extern __typeof_unqual (const int) i; +extern __typeof_unqual (ci) i; +extern __typeof__ ((const int) ci) i; +extern __typeof__ (+ci) i; +extern __typeof (0, ci) i; +extern __typeof__ (1 ? ci : ci) i; +extern __typeof (0) i; + +const int fci (void); +extern __typeof__ (fci ()) i; + +_Atomic int ai; +extern __typeof (_Atomic int) ai; +extern __typeof__ (_Atomic (int)) ai; +extern __typeof (ai) ai; + +extern __typeof_unqual__ (_Atomic int) i; +extern __typeof_unqual (_Atomic (int)) i; +extern __typeof_unqual__ (ai) i; +extern __typeof (+ai) i; +extern __typeof__ ((_Atomic int) ai) i; +extern __typeof__ (0, ai) i; +extern __typeof (1 ? ai : ai) i; + +_Atomic int fai (void); +extern __typeof__ (fai ()) i; + +_Atomic const volatile int acvi; +extern __typeof (int volatile const _Atomic) acvi; +extern __typeof (acvi) acvi; +extern const _Atomic volatile __typeof (acvi) acvi; +extern _Atomic volatile __typeof__ (ci) acvi; +extern _Atomic const __typeof (vi) acvi; +extern const __typeof__ (ai) volatile acvi; + +extern __typeof_unqual (acvi) i; +extern __typeof_unqual__ (__typeof (acvi)) i; +extern __typeof_unqual (_Atomic __typeof_unqual__ (acvi)) i; + +extern _Atomic __typeof_unqual (acvi) ai; + +char c; +volatile char vc; +volatile char *pvc; +volatile char *const cpvc; +const char *pcc; +const char *volatile vpcc; +__typeof (*vpcc) cc; + +extern __typeof__ (*cpvc) vc; +extern __typeof_unqual (*cpvc) c; +extern __typeof_unqual__ (cpvc) pvc; +extern __typeof_unqual__ (vpcc) pcc; +extern const char cc; + +extern __typeof (++vi) i; +extern __typeof (++ai) i; +extern __typeof__ (--vi) i; +extern __typeof (--ai) i; +extern __typeof__ (vi++) i; +extern __typeof__ (ai++) i; +extern __typeof (vi--) i; +extern __typeof__ (ai--) i; + +_Bool b; +volatile _Bool vb; +_Atomic _Bool ab; +extern __typeof__ (++vb) b; +extern __typeof__ (++ab) b; +extern __typeof (--vb) b; +extern __typeof__ (--ab) b; +extern __typeof (vb++) b; +extern __typeof (ab++) b; +extern __typeof__ (vb--) b; +extern __typeof (ab--) b; + +extern __typeof__ (vc = 1) c; +extern __typeof__ (vpcc = 0) pcc; +extern __typeof (ai *= 2) i; + +int s = sizeof (__typeof__ (int (*)[++i])); + +void *vp; + +extern void abort (void); +extern void exit (int); + +extern int only_used_in_typeof; + +static int not_defined (void); + +__typeof (i) +main (__typeof (*vp)) +{ + volatile __typeof__ (only_used_in_typeof) ii = 2; + if (ii != 2) + abort (); + const __typeof__ (not_defined ()) jj = 3; + if (jj != 3) + abort (); + unsigned int u = 1; + __typeof__ (u) u2 = 0; + __typeof (int (*)[++u2]) p = 0; + if (u2 != 1) + abort (); + if (sizeof (*p) != sizeof (int)) + abort (); + __typeof_unqual (int (*)[++u2]) q = 0; + if (u2 != 2) + abort (); + if (sizeof (*q) != 2 * sizeof (int)) + abort (); + if (sizeof (*p) != sizeof (int)) + abort (); + __typeof (++u2) u3 = 1; + if (u2 != u + u3) + abort (); + __typeof_unqual__ (++u2) u4 = 2; + if (u2 != u4) + abort (); + u = sizeof (__typeof__ (int (*)[++u2])); + if (u2 != 2) + abort (); + u = sizeof (__typeof_unqual (int (*)[++u2])); + if (u2 != 2) + abort (); + __typeof ((int (*)[++u2]) 0) q2; + if (u2 != 3) + abort (); + __typeof ((void) 0, (int (*)[++u2]) 0) q3; + if (u2 != 4) + abort (); + __typeof__ ((int (*)[++u2]) 0, 0) q4; + if (u2 != 4) + abort (); + __typeof_unqual ((int (*)[++u2]) 0) q5; + if (u2 != 5) + abort (); + __typeof_unqual__ ((void) 0, (int (*)[++u2]) 0) q6; + if (u2 != 6) + abort (); + __typeof_unqual__ ((int (*)[++u2]) 0, 0) q7; + if (u2 != 6) + abort (); + int a1[6], a2[6]; + int (*pa)[u2] = &a1; + __typeof (pa = &a2) pp; + if (pa != &a2) + abort (); + __typeof_unqual (pa = &a1) pp2; + if (pa != &a1) + abort (); + exit (0); +} --- gcc/testsuite/gcc.dg/c11-typeof-3.c.jj 2023-06-10 19:27:42.003734166 +0200 +++ gcc/testsuite/gcc.dg/c11-typeof-3.c 2023-06-10 19:46:38.041174992 +0200 @@ -0,0 +1,58 @@ +/* Test GNU extensions __typeof__ and __typeof_unqual__. Invalid code. */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +struct s { int i : 2; } x; +union u { unsigned int j : 1; } y; + +__typeof__ (x.i) j; /* { dg-error "applied to a bit-field" } */ +__typeof_unqual__ (x.i) j2; /* { dg-error "applied to a bit-field" } */ +__typeof (y.j) j3; /* { dg-error "applied to a bit-field" } */ +__typeof_unqual (y.j) j4; /* { dg-error "applied to a bit-field" } */ + +static int ok (void); +static int also_ok (void); +static int not_defined (void); /* { dg-error "used but never defined" } */ +static int also_not_defined (void); /* { dg-error "used but never defined" } */ + +_Noreturn void nf1 (void); +__attribute__((noreturn)) void nf2 (void); +void fg (void) {} +__typeof__ (&nf1) pnf1 = fg; /* { dg-error "qualified function pointer from unqualified" } */ +__typeof (&nf2) pnf2 = fg; /* { dg-error "qualified function pointer from unqualified" } */ +extern void (*pnf1) (void); /* { dg-error "conflicting types for" } */ +extern void (*pnf2) (void); /* { dg-error "conflicting types for" } */ +extern __typeof (nf1) *pnf1; /* { dg-error "conflicting types for" } */ +extern __typeof (nf1) *pnf2; /* { dg-error "conflicting types for" } */ +extern __typeof__ (nf2) *pnf1; /* { dg-error "conflicting types for" } */ +extern __typeof__ (nf2) *pnf2; /* { dg-error "conflicting types for" } */ +__typeof (*&nf1) fg2, fg2a, fg2b; /* { dg-error "ISO C forbids qualified function types" } */ +__typeof__ (*&nf2) fg3, fg3a, fg3b; /* { dg-error "ISO C forbids qualified function types" } */ +__typeof (nf1) fg4, fg4a, fg4b; +__typeof__ (nf2) fg5, fg5a, fg5b; + +extern void abort (void); + +void fg2 (void) {} /* { dg-error "conflicting type qualifiers for" } */ +_Noreturn void fg2a (void) { abort (); } /* { dg-error "conflicting type qualifiers for" } */ +__attribute__((noreturn)) void fg2b (void) { abort (); } /* { dg-error "conflicting type qualifiers for" } */ +void fg3 (void) {} /* { dg-error "conflicting type qualifiers for" } */ +_Noreturn void fg3a (void) { abort (); } /* { dg-error "conflicting type qualifiers for" } */ +__attribute__((noreturn)) void fg3b (void) { abort (); } /* { dg-error "conflicting type qualifiers for" } */ +void fg4 (void) {} +_Noreturn void fg4a (void) { abort (); } +__attribute__((noreturn)) void fg4b (void) { abort (); } +void fg5 (void) {} +_Noreturn void fg5a (void) { abort (); } +__attribute__((noreturn)) void fg5b (void) { abort (); } + +void +f (void) +{ + __typeof__ (ok ()) x = 2; + __typeof_unqual (also_ok ()) y = 2; + int a[2]; + int (*p)[x] = &a; + __typeof (p + not_defined ()) q; + __typeof_unqual__ (p + also_not_defined ()) q2; +} --- gcc/testsuite/gcc.dg/gnu11-typeof-3.c.jj 2023-06-10 19:39:59.936626612 +0200 +++ gcc/testsuite/gcc.dg/gnu11-typeof-3.c 2023-06-10 19:47:32.861424347 +0200 @@ -0,0 +1,177 @@ +/* Test GNU extensions __typeof__ and __typeof_unqual__. Valid code. */ +/* { dg-do run } */ +/* { dg-options "-std=gnu11" } */ + +int i; +extern __typeof__ (i) i; +extern __typeof (int) i; +extern __typeof_unqual__ (i) i; +extern __typeof_unqual (int) i; + +volatile int vi; +extern __typeof__ (volatile int) vi; +extern __typeof (vi) vi; + +extern __typeof_unqual__ (volatile int) i; +extern __typeof_unqual__ (vi) i; +extern __typeof__ ((const int) vi) i; +extern __typeof ((volatile int) vi) i; + +const int ci; +extern __typeof (const int) ci; +extern __typeof (ci) ci; + +extern __typeof_unqual (const int) i; +extern __typeof_unqual (ci) i; +extern __typeof__ ((const int) ci) i; +extern __typeof__ (+ci) i; +extern __typeof (0, ci) i; +extern __typeof__ (1 ? ci : ci) i; +extern __typeof (0) i; + +const int fci (void); +extern __typeof__ (fci ()) i; + +_Atomic int ai; +extern __typeof (_Atomic int) ai; +extern __typeof__ (_Atomic (int)) ai; +extern __typeof (ai) ai; + +extern __typeof_unqual__ (_Atomic int) i; +extern __typeof_unqual (_Atomic (int)) i; +extern __typeof_unqual__ (ai) i; +extern __typeof (+ai) i; +extern __typeof__ ((_Atomic int) ai) i; +extern __typeof__ (0, ai) i; +extern __typeof (1 ? ai : ai) i; + +_Atomic int fai (void); +extern __typeof__ (fai ()) i; + +_Atomic const volatile int acvi; +extern __typeof (int volatile const _Atomic) acvi; +extern __typeof (acvi) acvi; +extern const _Atomic volatile __typeof (acvi) acvi; +extern _Atomic volatile __typeof__ (ci) acvi; +extern _Atomic const __typeof (vi) acvi; +extern const __typeof__ (ai) volatile acvi; + +extern __typeof_unqual (acvi) i; +extern __typeof_unqual__ (__typeof (acvi)) i; +extern __typeof_unqual (_Atomic __typeof_unqual__ (acvi)) i; + +extern _Atomic __typeof_unqual (acvi) ai; + +char c; +volatile char vc; +volatile char *pvc; +volatile char *const cpvc; +const char *pcc; +const char *volatile vpcc; +__typeof (*vpcc) cc; + +extern __typeof__ (*cpvc) vc; +extern __typeof_unqual (*cpvc) c; +extern __typeof_unqual__ (cpvc) pvc; +extern __typeof_unqual__ (vpcc) pcc; +extern const char cc; + +extern __typeof (++vi) i; +extern __typeof (++ai) i; +extern __typeof__ (--vi) i; +extern __typeof (--ai) i; +extern __typeof__ (vi++) i; +extern __typeof__ (ai++) i; +extern __typeof (vi--) i; +extern __typeof__ (ai--) i; + +_Bool b; +volatile _Bool vb; +_Atomic _Bool ab; +extern __typeof__ (++vb) b; +extern __typeof__ (++ab) b; +extern __typeof (--vb) b; +extern __typeof__ (--ab) b; +extern __typeof (vb++) b; +extern __typeof (ab++) b; +extern __typeof__ (vb--) b; +extern __typeof (ab--) b; + +extern __typeof__ (vc = 1) c; +extern __typeof__ (vpcc = 0) pcc; +extern __typeof (ai *= 2) i; + +int s = sizeof (__typeof__ (int (*)[++i])); + +void *vp; + +extern void abort (void); +extern void exit (int); + +extern int only_used_in_typeof; + +static int not_defined (void); + +__typeof (i) +main (__typeof (*vp)) +{ + volatile __typeof__ (only_used_in_typeof) ii = 2; + if (ii != 2) + abort (); + const __typeof__ (not_defined ()) jj = 3; + if (jj != 3) + abort (); + unsigned int u = 1; + __typeof__ (u) u2 = 0; + __typeof (int (*)[++u2]) p = 0; + if (u2 != 1) + abort (); + if (sizeof (*p) != sizeof (int)) + abort (); + __typeof_unqual (int (*)[++u2]) q = 0; + if (u2 != 2) + abort (); + if (sizeof (*q) != 2 * sizeof (int)) + abort (); + if (sizeof (*p) != sizeof (int)) + abort (); + __typeof (++u2) u3 = 1; + if (u2 != u + u3) + abort (); + __typeof_unqual__ (++u2) u4 = 2; + if (u2 != u4) + abort (); + u = sizeof (__typeof__ (int (*)[++u2])); + if (u2 != 2) + abort (); + u = sizeof (__typeof_unqual (int (*)[++u2])); + if (u2 != 2) + abort (); + __typeof ((int (*)[++u2]) 0) q2; + if (u2 != 3) + abort (); + __typeof ((void) 0, (int (*)[++u2]) 0) q3; + if (u2 != 4) + abort (); + __typeof__ ((int (*)[++u2]) 0, 0) q4; + if (u2 != 4) + abort (); + __typeof_unqual ((int (*)[++u2]) 0) q5; + if (u2 != 5) + abort (); + __typeof_unqual__ ((void) 0, (int (*)[++u2]) 0) q6; + if (u2 != 6) + abort (); + __typeof_unqual__ ((int (*)[++u2]) 0, 0) q7; + if (u2 != 6) + abort (); + int a1[6], a2[6]; + int (*pa)[u2] = &a1; + __typeof (pa = &a2) pp; + if (pa != &a2) + abort (); + __typeof_unqual (pa = &a1) pp2; + if (pa != &a1) + abort (); + exit (0); +} --- gcc/testsuite/gcc.dg/gnu11-typeof-4.c.jj 2023-06-10 19:40:04.211568056 +0200 +++ gcc/testsuite/gcc.dg/gnu11-typeof-4.c 2023-06-10 19:50:07.819302529 +0200 @@ -0,0 +1,58 @@ +/* Test GNU extensions __typeof__ and __typeof_unqual__. Invalid code. */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu11" } */ + +struct s { int i : 2; } x; +union u { unsigned int j : 1; } y; + +__typeof__ (x.i) j; /* { dg-error "applied to a bit-field" } */ +__typeof_unqual__ (x.i) j2; /* { dg-error "applied to a bit-field" } */ +__typeof (y.j) j3; /* { dg-error "applied to a bit-field" } */ +__typeof_unqual (y.j) j4; /* { dg-error "applied to a bit-field" } */ + +static int ok (void); +static int also_ok (void); +static int not_defined (void); /* { dg-warning "used but never defined" } */ +static int also_not_defined (void); /* { dg-warning "used but never defined" } */ + +_Noreturn void nf1 (void); +__attribute__((noreturn)) void nf2 (void); +void fg (void) {} +__typeof__ (&nf1) pnf1 = fg; /* { dg-warning "qualified function pointer from unqualified" } */ +__typeof (&nf2) pnf2 = fg; /* { dg-warning "qualified function pointer from unqualified" } */ +extern void (*pnf1) (void); /* { dg-error "conflicting types for" } */ +extern void (*pnf2) (void); /* { dg-error "conflicting types for" } */ +extern __typeof (nf1) *pnf1; /* { dg-error "conflicting types for" } */ +extern __typeof (nf1) *pnf2; /* { dg-error "conflicting types for" } */ +extern __typeof__ (nf2) *pnf1; /* { dg-error "conflicting types for" } */ +extern __typeof__ (nf2) *pnf2; /* { dg-error "conflicting types for" } */ +__typeof (*&nf1) fg2, fg2a, fg2b; +__typeof__ (*&nf2) fg3, fg3a, fg3b; +__typeof (nf1) fg4, fg4a, fg4b; +__typeof__ (nf2) fg5, fg5a, fg5b; + +extern void abort (void); + +void fg2 (void) {} /* { dg-error "conflicting type qualifiers for" } */ +_Noreturn void fg2a (void) { abort (); } /* { dg-error "conflicting type qualifiers for" } */ +__attribute__((noreturn)) void fg2b (void) { abort (); } /* { dg-error "conflicting type qualifiers for" } */ +void fg3 (void) {} /* { dg-error "conflicting type qualifiers for" } */ +_Noreturn void fg3a (void) { abort (); } /* { dg-error "conflicting type qualifiers for" } */ +__attribute__((noreturn)) void fg3b (void) { abort (); } /* { dg-error "conflicting type qualifiers for" } */ +void fg4 (void) {} +_Noreturn void fg4a (void) { abort (); } +__attribute__((noreturn)) void fg4b (void) { abort (); } +void fg5 (void) {} +_Noreturn void fg5a (void) { abort (); } +__attribute__((noreturn)) void fg5b (void) { abort (); } + +void +f (void) +{ + __typeof__ (ok ()) x = 2; + __typeof_unqual (also_ok ()) y = 2; + int a[2]; + int (*p)[x] = &a; + __typeof (p + not_defined ()) q; + __typeof_unqual__ (p + also_not_defined ()) q2; +} Jakub