* Add '_Defer' as an extension to all c versions, while keeping 'defer' gated behind '-fdefer-ts'. This matches the behaviour that clang is going[3] for and the new ts revision[4].
--- * Remove backwards jump constraint, as per v3 of the ts[2]. bringing the behaviour more in line with the cleanup attribute. --- * remove the need of -std=c2y for -fdefer-ts to take effect --- * added a test jumping into a defer block from above. * reworded the lookup_label_for_goto error message to mention the error is a jump into the defer block, instead of out. * moved the 'defer' keyword behind a -fdefer-ts flag, and added texinfo docs plus related failure test. --- based on n3589[1], this feature mostly makes use of already-established logic, namely push_cleanup used by the cleanup attribute, and the constraints put in place for checking local jumps against statement expressions 1: https://open-std.org/JTC1/SC22/WG14/www/docs/n3589.pdf 2: https://open-std.org/JTC1/SC22/WG14/www/docs/n3688.pdf 3: https://github.com/llvm/llvm-project/pull/162848 4: https://thephd.dev/_vendor/future_cxx/technical%20specification/C%20-%20defer/C%20-%20defer%20Technical%20Specification.pdf Anna (navi) Figueiredo Gomes (3): c: handle expression nodes in push_cleanup c: introduce jump barriers for statement expressions c: implement the defer keyword gcc/c-family/c-common.cc | 2 + gcc/c-family/c-common.h | 2 + gcc/c-family/c-cppbuiltin.cc | 3 + gcc/c-family/c.opt | 4 + gcc/c/c-decl.cc | 136 +++++++++++++----- gcc/c/c-parser.cc | 41 ++++++ gcc/c/c-tree.h | 8 +- gcc/c/c-typeck.cc | 56 ++++++-- gcc/doc/invoke.texi | 6 +- gcc/doc/standards.texi | 3 +- gcc/testsuite/gcc.dg/defer-1.c | 255 +++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/defer-2.c | 76 ++++++++++ gcc/testsuite/gcc.dg/defer-3.c | 15 ++ gcc/testsuite/gcc.dg/defer-4.c | 8 ++ 14 files changed, 565 insertions(+), 50 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/defer-1.c create mode 100644 gcc/testsuite/gcc.dg/defer-2.c create mode 100644 gcc/testsuite/gcc.dg/defer-3.c create mode 100644 gcc/testsuite/gcc.dg/defer-4.c Range-diff against v4: 1: da835e79572 = 1: da835e79572 c: handle expression nodes in push_cleanup 2: b0fd9d8165a = 2: b0fd9d8165a c: introduce jump barriers for statement expressions 3: a43878af76c ! 3: 60197f74dab c: implement the defer keyword @@ Metadata ## Commit message ## c: implement the defer keyword - based on the technical specification n3589[1], and set behind the - command line flag '-fdefer-ts' + based on the technical specification 25755[1][2] + + the keyword '_Defer' is enabled by default as an extension, while + 'defer' is gated by '-fdefer-ts' deferred statements execute at the end of the scope they're added on, similar to the cleanup attribute, and they have much of the same @@ Commit message and continue, jump out of one 1: https://open-std.org/JTC1/SC22/WG14/www/docs/n3589.pdf + 2: https://thephd.dev/_vendor/future_cxx/technical%20specification/C%20-%20defer/C%20-%20defer%20Technical%20Specification.pdf gcc/ChangeLog: @@ Commit message gcc/c-family/ChangeLog: - * c-common.cc: Add defer keyword. + * c-common.cc: Add defer and _Defer keywords. * c-common.h (enum rid): Add RID_DEFER. (D_CXX11): Adjust. (D_EXT): Likewise. @@ Commit message Signed-off-by: Anna (navi) Figueiredo Gomes <[email protected]> ## gcc/c-family/c-common.cc ## +@@ gcc/c-family/c-common.cc: const struct c_common_resword c_common_reswords[] = + { "_Decimal64", RID_DFLOAT64, D_CONLY }, + { "_Decimal128", RID_DFLOAT128, D_CONLY }, + { "_Decimal64x", RID_DFLOAT64X, D_CONLY }, ++ { "_Defer", RID_DEFER, D_CONLY | D_EXT }, + { "_Fract", RID_FRACT, D_CONLY | D_EXT }, + { "_Accum", RID_ACCUM, D_CONLY | D_EXT }, + { "_Sat", RID_SAT, D_CONLY | D_EXT }, @@ gcc/c-family/c-common.cc: const struct c_common_resword c_common_reswords[] = { "continue", RID_CONTINUE, 0 }, { "decltype", RID_DECLTYPE, D_CXXONLY | D_CXX11 | D_CXXWARN }, @@ gcc/c-family/c-common.cc: const struct c_common_resword c_common_reswords[] = ## gcc/c-family/c-common.h ## @@ gcc/c-family/c-common.h: enum rid - RID_IMAGINARY, - - /* C */ -- RID_INT, RID_CHAR, RID_FLOAT, RID_DOUBLE, RID_VOID, -- RID_ENUM, RID_STRUCT, RID_UNION, RID_IF, RID_ELSE, -- RID_WHILE, RID_DO, RID_FOR, RID_SWITCH, RID_CASE, -- RID_DEFAULT, RID_BREAK, RID_CONTINUE, RID_RETURN, RID_GOTO, -- RID_SIZEOF, RID_BITINT, -+ RID_INT, RID_CHAR, RID_FLOAT, RID_DOUBLE, RID_VOID, -+ RID_ENUM, RID_STRUCT, RID_UNION, RID_IF, RID_ELSE, -+ RID_WHILE, RID_DO, RID_FOR, RID_SWITCH, RID_CASE, -+ RID_DEFAULT, RID_DEFER, RID_BREAK, RID_CONTINUE, RID_RETURN, -+ RID_GOTO, RID_SIZEOF, RID_BITINT, - - /* C extensions */ - RID_ASM, RID_TYPEOF, RID_TYPEOF_UNQUAL, RID_ALIGNOF, RID_ATTRIBUTE, + RID_BUILTIN_HAS_ATTRIBUTE, RID_BUILTIN_ASSOC_BARRIER, RID_BUILTIN_STDC, + RID_BUILTIN_COUNTED_BY_REF, + RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128, RID_DFLOAT64X, ++ RID_DEFER, + + /* TS 18661-3 keywords, in the same sequence as the TI_* values. */ + RID_FLOAT16, @@ gcc/c-family/c-common.h: extern machine_mode c_default_pointer_mode; - #define D_CXXONLY 0x0002 /* C++ only (not in C). */ - #define D_C99 0x0004 /* In C, C99 only. */ - #define D_C23 0x0008 /* In C, C23 only. */ --#define D_CXX11 0x0010 /* In C++, C++11 only. */ --#define D_EXT 0x0020 /* GCC extension. */ --#define D_EXT89 0x0040 /* GCC extension incorporated in C99. */ --#define D_EXT11 0x0080 /* GCC extension incorporated in C23. */ --#define D_ASM 0x0100 /* Disabled by -fno-asm. */ --#define D_OBJC 0x0200 /* In Objective C and neither C nor C++. */ --#define D_CXX_OBJC 0x0400 /* In Objective C, and C++, but not C. */ --#define D_CXXWARN 0x0800 /* In C warn with -Wcxx-compat. */ --#define D_CXX_CONCEPTS 0x1000 /* In C++, only with concepts. */ --#define D_TRANSMEM 0x2000 /* C++ transactional memory TS. */ --#define D_CXX_CHAR8_T 0x4000 /* In C++, only with -fchar8_t. */ --#define D_CXX20 0x8000 /* In C++, C++20 only. */ --#define D_CXX_COROUTINES 0x10000 /* In C++, only with coroutines. */ --#define D_CXX_MODULES 0x20000 /* In C++, only with modules. */ -+#define D_DEFER 0x0010 /* C defer statements TS. */ -+#define D_CXX11 0x0020 /* In C++, C++11 only. */ -+#define D_EXT 0x0040 /* GCC extension. */ -+#define D_EXT89 0x0080 /* GCC extension incorporated in C99. */ -+#define D_EXT11 0x0100 /* GCC extension incorporated in C23. */ -+#define D_ASM 0x0200 /* Disabled by -fno-asm. */ -+#define D_OBJC 0x0400 /* In Objective C and neither C nor C++. */ -+#define D_CXX_OBJC 0x0800 /* In Objective C, and C++, but not C. */ -+#define D_CXXWARN 0x1000 /* In C warn with -Wcxx-compat. */ -+#define D_CXX_CONCEPTS 0x2000 /* In C++, only with concepts. */ -+#define D_TRANSMEM 0x4000 /* C++ transactional memory TS. */ -+#define D_CXX_CHAR8_T 0x8000 /* In C++, only with -fchar8_t. */ -+#define D_CXX20 0x10000 /* In C++, C++20 only. */ -+#define D_CXX_COROUTINES 0x20000 /* In C++, only with coroutines. */ -+#define D_CXX_MODULES 0x40000 /* In C++, only with modules. */ + #define D_CXX20 0x8000 /* In C++, C++20 only. */ + #define D_CXX_COROUTINES 0x10000 /* In C++, only with coroutines. */ + #define D_CXX_MODULES 0x20000 /* In C++, only with modules. */ ++#define D_DEFER 0x40000 /* In C, only with -fdefer-ts */ #define D_CXX_CONCEPTS_FLAGS D_CXXONLY | D_CXX_CONCEPTS #define D_CXX_CHAR8_T_FLAGS D_CXXONLY | D_CXX_CHAR8_T @@ gcc/c-family/c-cppbuiltin.cc: c_cpp_builtins (cpp_reader *pfile) if (flag_iso) cpp_define (pfile, "__STRICT_ANSI__"); -+ if (flag_defer_ts) ++ if (!flag_no_gnu_keywords || flag_defer_ts) + builtin_define_with_int_value ("__STDC_DEFER_TS25755__", 1); + if (!flag_signed_char) @@ gcc/testsuite/gcc.dg/defer-3.c (new) ## gcc/testsuite/gcc.dg/defer-4.c (new) ## @@ +/* { dg-do compile } */ ++/* { dg-options "" } */ + +int main(void) +{ ++ _Defer; + defer; /* { dg-error "'defer' undeclared" "undeclared identifier" } */ +} -- 2.51.0
