|
| 1 | +// RUN: %clang_cc1 -verify -std=c99 %s |
| 2 | +// RUN: %clang_cc1 -verify -std=c23 %s |
| 3 | + |
| 4 | +/* WG14 N448: Partial |
| 5 | + * Restricted pointers |
| 6 | + * |
| 7 | + * NB: we claim partial conformance only because LLVM does not attempt to apply |
| 8 | + * the semantics on local variables or structure data members; it only |
| 9 | + * considers function parameters. However, Clang itself is fully conforming for |
| 10 | + * this feature. |
| 11 | + */ |
| 12 | + |
| 13 | +// Restrict is only allowed on pointers. |
| 14 | +int * restrict ipr; |
| 15 | +int restrict ir; // expected-error {{restrict requires a pointer or reference ('int' is invalid)}} |
| 16 | + |
| 17 | +// Restrict only applies to object pointers. |
| 18 | +void (* restrict fp)(void); // expected-error {{pointer to function type 'void (void)' may not be 'restrict' qualified}} |
| 19 | + |
| 20 | +typedef int *int_ptr; |
| 21 | +int_ptr restrict ipr2; // okay, still applied to the pointer. |
| 22 | + |
| 23 | +// Show that the qualifer is dropped on lvalue conversion |
| 24 | +_Static_assert( |
| 25 | + _Generic(ipr, |
| 26 | + int * : 1, |
| 27 | + int * restrict : 0, // expected-warning {{due to lvalue conversion of the controlling expression, association of type 'int *restrict' will never be selected because it is qualified}} |
| 28 | + default : 0), |
| 29 | + ""); |
| 30 | + |
| 31 | +// Show that it's allowed as a qualifier for array parameters. |
| 32 | +void f(int array[restrict]) { |
| 33 | + int *ipnr = ipr; // okay to drop the top-level qualifier |
| 34 | + |
| 35 | + // Show that it's not okay to drop the qualifier when it's not at the top level. |
| 36 | + int * restrict * restrict iprpr; |
| 37 | + int **ipp = iprpr; // expected-warning {{initializing 'int **' with an expression of type 'int *restrict *restrict' discards qualifiers}} |
| 38 | + int ** restrict ippr = iprpr; // expected-warning {{initializing 'int **restrict' with an expression of type 'int *restrict *restrict' discards qualifiers}} |
| 39 | +} |
| 40 | + |
| 41 | +#if __STDC_VERSION__ >= 202311L |
| 42 | +// C23 doesn't allow constexpr to mix with restrict. See C23 6.7.2p5. |
| 43 | +constexpr int * restrict ip; // expected-error {{constexpr variable cannot have type 'int *const restrict'}} |
| 44 | +#endif // __STDC_VERSION__ >= 202311L |
0 commit comments