https://gcc.gnu.org/g:acbe4fd145a2d6f5537553a43ec67dfd46739438
commit r16-5636-gacbe4fd145a2d6f5537553a43ec67dfd46739438 Author: Alejandro Colomar <[email protected]> Date: Wed Nov 26 01:12:49 2025 +0100 c: Add _Maxof and _Minof operators Link: <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3628.txt> These operators have not yet been accepted by the C Committee, so this is implemented as a GNU extension. gcc/ChangeLog: * doc/extend.texi (Syntax Extensions): Document _Maxof & _Minof. gcc/c-family/ChangeLog: * c-common.cc (c_common_reswords): Add _Maxof & _Minof keywords. (c_maxof_type, c_minof_type): New functions. * c-common.def (MAXOF_EXPR, MINOF_EXPR): New trees. * c-common.h (enum rid): Add RID_MAXOF & RID_MINOF constants. (c_maxof_type, c_minof_type): New prototypes. gcc/c/ChangeLog: * c-parser.cc (c_parser_maxof_or_minof_expression): New func. (c_parser_unary_expression): Add RID_MAXOF & RID_MINOF cases. * c-tree.h (c_expr_maxof_type): New prototype. (c_expr_minof_type): New prototype. * c-typeck.cc (c_expr_maxof_type): New function. (c_expr_minof_type): New function. gcc/testsuite/ChangeLog: * gcc.dg/maxof-bitint.c: New test. * gcc.dg/maxof-bitint575.c: New test. * gcc.dg/maxof-compile.c: New test. * gcc.dg/maxof-pedantic-errors.c: New test. * gcc.dg/maxof-pedantic.c: New test. Signed-off-by: Alejandro Colomar <[email protected]> Diff: --- gcc/c-family/c-common.cc | 44 ++++++++ gcc/c-family/c-common.def | 6 + gcc/c-family/c-common.h | 4 +- gcc/c/c-parser.cc | 67 ++++++++++++ gcc/c/c-tree.h | 2 + gcc/c/c-typeck.cc | 54 +++++++++ gcc/doc/extend.texi | 20 ++++ gcc/testsuite/gcc.dg/maxof-bitint.c | 20 ++++ gcc/testsuite/gcc.dg/maxof-bitint575.c | 39 +++++++ gcc/testsuite/gcc.dg/maxof-compile.c | 158 +++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/maxof-pedantic-errors.c | 5 + gcc/testsuite/gcc.dg/maxof-pedantic.c | 5 + 12 files changed, 423 insertions(+), 1 deletion(-) diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc index ef1ce62068dd..3cec729c901c 100644 --- a/gcc/c-family/c-common.cc +++ b/gcc/c-family/c-common.cc @@ -397,6 +397,8 @@ const struct c_common_resword c_common_reswords[] = { "_Alignas", RID_ALIGNAS, D_CONLY }, { "_Alignof", RID_ALIGNOF, D_CONLY }, { "_Countof", RID_COUNTOF, D_CONLY }, + { "_Maxof", RID_MAXOF, D_CONLY }, + { "_Minof", RID_MINOF, D_CONLY }, { "_Atomic", RID_ATOMIC, D_CONLY }, { "_BitInt", RID_BITINT, D_CONLY }, { "_Bool", RID_BOOL, D_CONLY }, @@ -4164,6 +4166,48 @@ c_countof_type (location_t loc, tree type) return value; } +/* Implement the _Maxof operator: + Return the maximum representable value of an integer type. */ + +tree +c_maxof_type (location_t loc, tree type) +{ + if (!INTEGRAL_TYPE_P (type)) + { + error_at (loc, "invalid application of %<_Maxof%> to type %qT", type); + return error_mark_node; + } + if (!COMPLETE_TYPE_P (type)) + { + error_at (loc, "invalid application of %<_Maxof%> to incomplete type %qT", + type); + return error_mark_node; + } + + return TYPE_MAX_VALUE (type); +} + +/* Implement the _Minof operator: + Return the minimum representable value of an integer type. */ + +tree +c_minof_type (location_t loc, tree type) +{ + if (!INTEGRAL_TYPE_P (type)) + { + error_at (loc, "invalid application of %<_Minof%> to type %qT", type); + return error_mark_node; + } + if (!COMPLETE_TYPE_P (type)) + { + error_at (loc, "invalid application of %<_Minof%> to incomplete type %qT", + type); + return error_mark_node; + } + + return TYPE_MIN_VALUE (type); +} + /* Handle C and C++ default attributes. */ enum built_in_attribute diff --git a/gcc/c-family/c-common.def b/gcc/c-family/c-common.def index 0bcc4998afe6..9b1f034579b7 100644 --- a/gcc/c-family/c-common.def +++ b/gcc/c-family/c-common.def @@ -53,6 +53,12 @@ DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3) /* Represents a 'countof' expression. */ DEFTREECODE (COUNTOF_EXPR, "countof_expr", tcc_expression, 1) +/* Represents a 'maxof' expression. */ +DEFTREECODE (MAXOF_EXPR, "maxof_expr", tcc_expression, 1) + +/* Represents a 'minof' expression. */ +DEFTREECODE (MINOF_EXPR, "minof_expr", tcc_expression, 1) + /* Represents a 'sizeof' expression during C++ template expansion, or for the purpose of -Wsizeof-pointer-memaccess warning. */ DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1) diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 8b7f4ae44717..6a92bd6ef762 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -105,7 +105,7 @@ enum rid /* C extensions */ RID_ASM, RID_TYPEOF, RID_TYPEOF_UNQUAL, RID_ALIGNOF, RID_ATTRIBUTE, - RID_COUNTOF, + RID_COUNTOF, RID_MAXOF, RID_MINOF, RID_C23_VA_START, RID_VA_ARG, RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR, RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE, @@ -893,6 +893,8 @@ extern void c_apply_type_quals_to_decl (int, tree); extern tree c_sizeof_or_alignof_type (location_t, tree, bool, bool, int); extern tree c_alignof_expr (location_t, tree); extern tree c_countof_type (location_t, tree); +extern tree c_maxof_type (location_t, tree); +extern tree c_minof_type (location_t, tree); /* Print an error message for invalid operands to arith operation CODE. NOP_EXPR is used as a special case (see truthvalue_conversion). */ extern void binary_op_error (rich_location *, enum tree_code, tree, tree); diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index aa7b50c8a234..b4dc741c6fd4 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -1865,6 +1865,7 @@ static struct c_expr c_parser_unary_expression (c_parser *); static struct c_expr c_parser_sizeof_or_countof_expression (c_parser *, enum rid); static struct c_expr c_parser_alignof_expression (c_parser *); +static struct c_expr c_parser_maxof_or_minof_expression (c_parser *, enum rid); static struct c_expr c_parser_postfix_expression (c_parser *); static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *, struct c_declspecs *, @@ -10642,6 +10643,8 @@ c_parser_cast_expression (c_parser *parser, struct c_expr *after) unary-expression: __alignof__ unary-expression __alignof__ ( type-name ) + _Maxof ( type-name ) + _Minof ( type-name ) && identifier (C11 permits _Alignof with type names only.) @@ -10774,6 +10777,9 @@ c_parser_unary_expression (c_parser *parser) return c_parser_sizeof_or_countof_expression (parser, rid); case RID_ALIGNOF: return c_parser_alignof_expression (parser); + case RID_MAXOF: + case RID_MINOF: + return c_parser_maxof_or_minof_expression (parser, rid); case RID_BUILTIN_HAS_ATTRIBUTE: return c_parser_has_attribute_expression (parser); case RID_EXTENSION: @@ -11017,6 +11023,67 @@ c_parser_alignof_expression (c_parser *parser) } } +/* Parse a _Maxof or _Minof expression. */ + +static struct c_expr +c_parser_maxof_or_minof_expression (c_parser *parser, enum rid rid) +{ + const char *op_name = (rid == RID_MAXOF) ? "_Maxof" : "_Minof"; + struct c_expr result; + location_t expr_loc; + struct c_type_name *type_name; + matching_parens parens; + gcc_assert (c_parser_next_token_is_keyword (parser, rid)); + + location_t start; + location_t finish = UNKNOWN_LOCATION; + + start = c_parser_peek_token (parser)->location; + + pedwarn (start, OPT_Wpedantic, "ISO C does not support %qs", op_name); + + c_parser_consume_token (parser); + c_inhibit_evaluation_warnings++; + if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN)) + { + c_parser_error (parser, "expected %<(%>"); + goto fail; + } + parens.consume_open (parser); + expr_loc = c_parser_peek_token (parser)->location; + if (!c_token_starts_typename (c_parser_peek_token (parser))) + { + error_at (expr_loc, "invalid application of %qs to something not a type", op_name); + parens.skip_until_found_close (parser); + goto fail; + } + type_name = c_parser_type_name (parser, true); + if (type_name == NULL) + { + // c_parser_type_name() has already diagnosed the error. + parens.skip_until_found_close (parser); + goto fail; + } + parens.skip_until_found_close (parser); + finish = parser->tokens_buf[0].location; + if (type_name->specs->alignas_p) + error_at (type_name->specs->locations[cdw_alignas], + "alignment specified for type name in %qs", op_name); + c_inhibit_evaluation_warnings--; + if (rid == RID_MAXOF) + result = c_expr_maxof_type (expr_loc, type_name); + else + result = c_expr_minof_type (expr_loc, type_name); + set_c_expr_source_range (&result, start, finish); + return result; +fail: + c_inhibit_evaluation_warnings--; + result.set_error (); + result.original_code = ERROR_MARK; + result.original_type = NULL; + return result; +} + /* Parse the __builtin_has_attribute ([expr|type], attribute-spec) expression. */ diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index ff63d69e85d5..80b147154032 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -856,6 +856,8 @@ extern struct c_expr c_expr_sizeof_type (location_t, struct c_type_name *); extern struct c_expr c_expr_countof_expr (location_t, struct c_expr); extern struct c_expr c_expr_countof_type (location_t loc, struct c_type_name *); +extern struct c_expr c_expr_maxof_type (location_t loc, struct c_type_name *); +extern struct c_expr c_expr_minof_type (location_t loc, struct c_type_name *); extern struct c_expr parser_build_unary_op (location_t, enum tree_code, struct c_expr); extern struct c_expr parser_build_binary_op (location_t, diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index e1d2d1173dc7..7eb413885b87 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -4120,6 +4120,60 @@ c_expr_countof_type (location_t loc, struct c_type_name *t) return ret; } +/* Return the result of maxof applied to T, a structure for the type + name passed to maxof (rather than the type itself). LOC is the + location of the original expression. */ + +struct c_expr +c_expr_maxof_type (location_t loc, struct c_type_name *t) +{ + tree type; + struct c_expr ret; + tree type_expr = NULL_TREE; + bool type_expr_const = true; + type = groktypename (t, &type_expr, &type_expr_const); + ret.value = c_maxof_type (loc, type); + c_last_sizeof_arg = type; + c_last_sizeof_loc = loc; + ret.original_code = MAXOF_EXPR; + ret.original_type = NULL; + ret.m_decimal = 0; + if (type == error_mark_node) + { + ret.value = error_mark_node; + ret.original_code = ERROR_MARK; + } + pop_maybe_used (type != error_mark_node); + return ret; +} + +/* Return the result of minof applied to T, a structure for the type + name passed to minof (rather than the type itself). LOC is the + location of the original expression. */ + +struct c_expr +c_expr_minof_type (location_t loc, struct c_type_name *t) +{ + tree type; + struct c_expr ret; + tree type_expr = NULL_TREE; + bool type_expr_const = true; + type = groktypename (t, &type_expr, &type_expr_const); + ret.value = c_minof_type (loc, type); + c_last_sizeof_arg = type; + c_last_sizeof_loc = loc; + ret.original_code = MINOF_EXPR; + ret.original_type = NULL; + ret.m_decimal = 0; + if (type == error_mark_node) + { + ret.value = error_mark_node; + ret.original_code = ERROR_MARK; + } + pop_maybe_used (type != error_mark_node); + return ret; +} + /* Build a function call to function FUNCTION with parameters PARAMS. The function call is at LOC. PARAMS is a list--a chain of TREE_LIST nodes--in which the diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index b9d1a6aac75a..cc414313884b 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -13567,6 +13567,7 @@ C and/or C++ standards, while others remain specific to GNU C. * Nested Functions:: Nested functions in GNU C. * Typeof:: @code{typeof}: referring to the type of an expression. * _Countof:: Determining the number of elements of arrays +* _Maxof and _Minof:: The maximum and minimum representable values of a type. * Offsetof:: Special syntax for @code{offsetof}. * Alignment:: Determining the alignment of a function, type or variable. * Enum Extensions:: Forward declarations and specifying the underlying type. @@ -14233,6 +14234,25 @@ _Countof (int [7][n++]); // integer constant expression _Countof (int [n++][7]); // run-time value; n++ is evaluated @end smallexample +@node _Maxof and _Minof +@subsection The maximum and minimum representable values of a type +@findex _Maxof +@findex _Minof + +The keywords @code{_Maxof} and @code{_Minof} determine +the maximum and minimum representable values of an integer type. +Their syntax is similar to @code{sizeof}. +The operand must be +a parenthesized integer type. +The result of these operators is an integer constant expression +of the same type as the operand. +For example: + +@smallexample +_Maxof (int); // returns '(int) INT_MAX' +_Minof (short); // returns '(short) SHRT_MIN' +@end smallexample + @node Offsetof @subsection Support for @code{offsetof} @findex __builtin_offsetof diff --git a/gcc/testsuite/gcc.dg/maxof-bitint.c b/gcc/testsuite/gcc.dg/maxof-bitint.c new file mode 100644 index 000000000000..647909c97aaa --- /dev/null +++ b/gcc/testsuite/gcc.dg/maxof-bitint.c @@ -0,0 +1,20 @@ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-std=gnu2y" } */ + +void +limits (void) +{ + _Static_assert (_Maxof (_BitInt (5)) == 15); + _Static_assert (_Minof (_BitInt (5)) == -16); + _Static_assert (_Maxof (unsigned _BitInt (5)) == 31); + _Static_assert (_Minof (unsigned _BitInt (5)) == 0); +} + +void +type (void) +{ + _Generic (_Maxof (_BitInt (5)), _BitInt (5): 0); + _Generic (_Minof (_BitInt (5)), _BitInt (5): 0); + _Generic (_Maxof (unsigned _BitInt (5)), unsigned _BitInt (5): 0); + _Generic (_Minof (unsigned _BitInt (5)), unsigned _BitInt (5): 0); +} diff --git a/gcc/testsuite/gcc.dg/maxof-bitint575.c b/gcc/testsuite/gcc.dg/maxof-bitint575.c new file mode 100644 index 000000000000..f43951a51f06 --- /dev/null +++ b/gcc/testsuite/gcc.dg/maxof-bitint575.c @@ -0,0 +1,39 @@ +/* { dg-do run { target bitint575 } } */ +/* { dg-options "-std=gnu2y" } */ + +#define assert(e) ((e) ? (void) 0 : __builtin_abort ()) + +void limits (void); + +int +main (void) +{ + limits (); +} + +void +limits (void) +{ + unsigned _BitInt (500) u; + _BitInt (500) i; + + u = 0; + u--; + + assert (_Maxof (unsigned _BitInt (500)) == u); + assert (_Minof (unsigned _BitInt (500)) == 0); + + i = u >> 1; + + assert (_Maxof (_BitInt (500)) == i); + assert (_Minof (_BitInt (500)) == -i-1); +} + +void +type (void) +{ + _Generic (_Maxof (_BitInt (500)), _BitInt (500): 0); + _Generic (_Minof (_BitInt (500)), _BitInt (500): 0); + _Generic (_Maxof (unsigned _BitInt (500)), unsigned _BitInt (500): 0); + _Generic (_Minof (unsigned _BitInt (500)), unsigned _BitInt (500): 0); +} diff --git a/gcc/testsuite/gcc.dg/maxof-compile.c b/gcc/testsuite/gcc.dg/maxof-compile.c new file mode 100644 index 000000000000..098cade1426f --- /dev/null +++ b/gcc/testsuite/gcc.dg/maxof-compile.c @@ -0,0 +1,158 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu2y" } */ + +#define SCHAR_MAX __SCHAR_MAX__ +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define UCHAR_MAX (SCHAR_MAX * 2 + 1) + +#define SHRT_MAX __SHRT_MAX__ +#define SHRT_MIN (-SHRT_MAX - 1) +#define USHRT_MAX (SHRT_MAX * 2U + 1) + +#define INT_MAX __INT_MAX__ +#define INT_MIN (-INT_MAX - 1) +#define UINT_MAX (INT_MAX * 2U + 1) + +#define LONG_MAX __LONG_MAX__ +#define LONG_MIN (-LONG_MAX - 1L) +#define ULONG_MAX (LONG_MAX * 2LU + 1) + +void +integer (void) +{ + _Static_assert (_Maxof (char) == SCHAR_MAX || _Maxof (char) == UCHAR_MAX); + _Static_assert (_Minof (char) == SCHAR_MIN || _Minof (char) == 0); + + _Static_assert (_Maxof (signed char) == SCHAR_MAX); + _Static_assert (_Maxof (short) == SHRT_MAX); + _Static_assert (_Maxof (int) == INT_MAX); + _Static_assert (_Maxof (long) == LONG_MAX); + _Static_assert (_Maxof (long long) >= LONG_MAX); + + _Static_assert (_Minof (signed char) == SCHAR_MIN); + _Static_assert (_Minof (short) == SHRT_MIN); + _Static_assert (_Minof (int) == INT_MIN); + _Static_assert (_Minof (long) == LONG_MIN); + _Static_assert (_Minof (long long) <= LONG_MIN); + + _Static_assert (_Maxof (unsigned char) == UCHAR_MAX); + _Static_assert (_Maxof (unsigned short) == USHRT_MAX); + _Static_assert (_Maxof (unsigned int) == UINT_MAX); + _Static_assert (_Maxof (unsigned long) == ULONG_MAX); + _Static_assert (_Maxof (unsigned long long) >= ULONG_MAX); + + _Static_assert (_Minof (unsigned char) == 0); + _Static_assert (_Minof (unsigned short) == 0); + _Static_assert (_Minof (unsigned int) == 0); + _Static_assert (_Minof (unsigned long) == 0); + _Static_assert (_Minof (unsigned long long) == 0); + + _Static_assert (_Maxof (bool) == true); + _Static_assert (_Minof (bool) == false); +} + +void +enums (void) +{ + enum e1 { E1 }; + enum e2 : short { E2 }; + + _Maxof (enum e1); + _Minof (enum e1); + _Static_assert (_Maxof (enum e2) == SHRT_MAX); + _Static_assert (_Minof (enum e2) == SHRT_MIN); +} + +void +expr (void) +{ + int x; + + _Maxof (x); /* { dg-error "to something not a type" } */ + /* { dg-error "expected '\\)'" "syntax error" { target *-*-* } .-1 } */ + _Minof (x); /* { dg-error "to something not a type" } */ + /* { dg-error "expected '\\)'" "syntax error" { target *-*-* } .-1 } */ + _Maxof (1); /* { dg-error "to something not a type" } */ + /* { dg-error "expected '\\)'" "syntax error" { target *-*-* } .-1 } */ + _Minof (1); /* { dg-error "to something not a type" } */ + /* { dg-error "expected '\\)'" "syntax error" { target *-*-* } .-1 } */ + _Maxof 1; /* { dg-error "expected '\\('" } */ + _Minof 1; /* { dg-error "expected '\\('" } */ + _Maxof (int) {1}; /* { dg-error "expected ';'" } */ + _Minof (int) {1}; /* { dg-error "expected ';'" } */ +} + +void +incomplete (void) +{ + _Maxof (enum e); /* { dg-error "to incomplete type" } */ + _Minof (enum e); /* { dg-error "to incomplete type" } */ +} + +void +non_int (void) +{ + struct s {int x;}; + union u {int x;}; + + _Maxof (struct s); /* { dg-error "to type" } */ + _Minof (struct s); /* { dg-error "to type" } */ + _Maxof (union u); /* { dg-error "to type" } */ + _Minof (union u); /* { dg-error "to type" } */ + _Maxof (int [1]); /* { dg-error "to type" } */ + _Minof (int [1]); /* { dg-error "to type" } */ +} + +void +specs (void) +{ + _Maxof (static int); /* { dg-error "to something not a type" } */ + /* { dg-error "expected '\\)'" "syntax error" { target *-*-* } .-1 } */ + _Minof (static int); /* { dg-error "to something not a type" } */ + /* { dg-error "expected '\\)'" "syntax error" { target *-*-* } .-1 } */ + _Maxof (alignas(8) int); /* { dg-error "alignment specified" } */ + _Minof (alignas(8) int); /* { dg-error "alignment specified" } */ +} + +void +bogus (void) +{ + _Maxof (int x); /* { dg-error "expected '\\)'" } */ + _Minof (int x); /* { dg-error "expected '\\)'" } */ + _Maxof (int (!)); /* { dg-error "expected '\\)'" } */ + _Minof (int (!)); /* { dg-error "expected '\\)'" } */ +} + +void +type (void) +{ + _Generic (_Maxof (char), char: 0); + _Generic (_Minof (char), char: 0); + + _Generic (_Maxof (signed char), signed char: 0); + _Generic (_Maxof (short), short: 0); + _Generic (_Maxof (int), int: 0); + _Generic (_Maxof (long), long: 0); + _Generic (_Maxof (long long), long long: 0); + + _Generic (_Minof (signed char), signed char: 0); + _Generic (_Minof (short), short: 0); + _Generic (_Minof (int), int: 0); + _Generic (_Minof (long), long: 0); + _Generic (_Minof (long long), long long: 0); + + _Generic (_Maxof (unsigned char), unsigned char: 0); + _Generic (_Maxof (unsigned short), unsigned short: 0); + _Generic (_Maxof (unsigned int), unsigned int: 0); + _Generic (_Maxof (unsigned long), unsigned long: 0); + _Generic (_Maxof (unsigned long long), unsigned long long: 0); + + _Generic (_Minof (unsigned char), unsigned char: 0); + _Generic (_Minof (unsigned short), unsigned short: 0); + _Generic (_Minof (unsigned int), unsigned int: 0); + _Generic (_Minof (unsigned long), unsigned long: 0); + _Generic (_Minof (unsigned long long), unsigned long long: 0); + + _Generic (_Maxof (bool), bool: 0); + _Generic (_Minof (bool), bool: 0); +} diff --git a/gcc/testsuite/gcc.dg/maxof-pedantic-errors.c b/gcc/testsuite/gcc.dg/maxof-pedantic-errors.c new file mode 100644 index 000000000000..dcb64bb06bb5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/maxof-pedantic-errors.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c23 -pedantic-errors" } */ + +int a[_Maxof(char)]; /* { dg-error "ISO C does not support" } */ +int b[1 + _Minof(unsigned char)]; /* { dg-error "ISO C does not support" } */ diff --git a/gcc/testsuite/gcc.dg/maxof-pedantic.c b/gcc/testsuite/gcc.dg/maxof-pedantic.c new file mode 100644 index 000000000000..fa2582c2baa5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/maxof-pedantic.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c23 -pedantic" } */ + +int a[_Maxof(char)]; /* { dg-warning "ISO C does not support" } */ +int b[1 + _Minof(unsigned char)]; /* { dg-warning "ISO C does not support" } */
