https://gcc.gnu.org/g:c21e657b7f9a9ad669fb38e0f82e13d22e12c114
commit r17-5433-gc21e657b7f9a9ad669fb38e0f82e13d22e12c114 Author: Owen Avery <[email protected]> Date: Thu Sep 24 19:40:16 2026 -0400 gccrs: Handle 1.55 rustc_feature "active" features can be "incomplete" and declare_features can invoke itself with __status_to_bool. gcc/rust/ChangeLog: * checks/errors/feature/contrib/Makefile: Remove copyright year templating. * checks/errors/feature/contrib/copyright-stub.h: Fill in copyright year. * checks/errors/feature/contrib/parse.y: Handle incomplete and __status_to_bool. * checks/errors/feature/contrib/scan.l: Likewise and improve string literal escape handling. Signed-off-by: Owen Avery <[email protected]> Diff: --- gcc/rust/checks/errors/feature/contrib/Makefile | 3 +- .../checks/errors/feature/contrib/copyright-stub.h | 2 +- gcc/rust/checks/errors/feature/contrib/parse.y | 30 ++++++++++++---- gcc/rust/checks/errors/feature/contrib/scan.l | 40 ++++++++++++++++++++-- 4 files changed, 63 insertions(+), 12 deletions(-) diff --git a/gcc/rust/checks/errors/feature/contrib/Makefile b/gcc/rust/checks/errors/feature/contrib/Makefile index 03623616651b..15344e1712cd 100644 --- a/gcc/rust/checks/errors/feature/contrib/Makefile +++ b/gcc/rust/checks/errors/feature/contrib/Makefile @@ -45,8 +45,7 @@ build/download.rs: fetch $(OUT): build/feature-extract build/download.rs # add copyright header + newline echo | \ - cat copyright-stub.h - | \ - sed "s/YYYY/$$(date +%Y)/" > build/rust-feature-defs.h + cat copyright-stub.h - > build/rust-feature-defs.h cat build/download.rs | ./$< >> build/rust-feature-defs.h clang-format -i build/rust-feature-defs.h \ --style=file:../../../../../../contrib/clang-format diff --git a/gcc/rust/checks/errors/feature/contrib/copyright-stub.h b/gcc/rust/checks/errors/feature/contrib/copyright-stub.h index 662bad37bc18..9164dc944108 100644 --- a/gcc/rust/checks/errors/feature/contrib/copyright-stub.h +++ b/gcc/rust/checks/errors/feature/contrib/copyright-stub.h @@ -1,4 +1,4 @@ -// Copyright (C) YYYY Free Software Foundation, Inc. +// Copyright (C) 2025-2026 Free Software Foundation, Inc. // This file is part of GCC. diff --git a/gcc/rust/checks/errors/feature/contrib/parse.y b/gcc/rust/checks/errors/feature/contrib/parse.y index 175721f4b9ba..02d9e38f4dcd 100644 --- a/gcc/rust/checks/errors/feature/contrib/parse.y +++ b/gcc/rust/checks/errors/feature/contrib/parse.y @@ -40,7 +40,7 @@ void yyerror (char const *); %token <str> IDENT STR NUM %token SCOPE %token K_SOME K_NONE -%token K_ACTIVE K_ACCEPTED K_REMOVED K_STABLE_REMOVED +%token K_ACTIVE K_INCOMPLETE K_STATUS_TO_BOOL K_ACCEPTED K_REMOVED K_STABLE_REMOVED %token K_E_START K_E_2018 %type <str> issue @@ -55,11 +55,11 @@ multi_database: multi_database database database: '(' entry_list ')'; -entry_list: entry_list entry ',' -| entry ',' +entry_list: entry_list entry +| entry ; -entry: '(' K_ACTIVE ',' IDENT ',' STR ',' issue ',' edition ')' { +entry: '(' K_ACTIVE ',' IDENT ',' STR ',' issue ',' edition ')' ',' { char *ident_upper = strdup ($4); for (size_t i = 0; ident_upper[i]; i++) ident_upper[i] = toupper (ident_upper[i]); @@ -69,7 +69,18 @@ entry: '(' K_ACTIVE ',' IDENT ',' STR ',' issue ',' edition ')' { free ($6); free ($8); } -| '(' K_ACCEPTED ',' IDENT ',' STR ',' issue ',' K_NONE ')' { +| '(' K_INCOMPLETE ',' IDENT ',' STR ',' issue ',' edition ')' ',' { + char *ident_upper = strdup ($4); + for (size_t i = 0; ident_upper[i]; i++) + ident_upper[i] = toupper (ident_upper[i]); + // TODO: pass incomplete flag to C++? + printf ("FEATURE_ACTIVE (\"%s\", %s, %s, %s%s%s, EDITION_%s)\n", $4, ident_upper, $6, UNWRAP_OPT_STR ("ISSUE", $8), $10 ? $10 : "NONE"); + free ($4); + free (ident_upper); + free ($6); + free ($8); +} +| '(' K_ACCEPTED ',' IDENT ',' STR ',' issue ',' K_NONE ')' ',' { char *ident_upper = strdup ($4); for (size_t i = 0; ident_upper[i]; i++) ident_upper[i] = toupper (ident_upper[i]); @@ -79,7 +90,7 @@ entry: '(' K_ACTIVE ',' IDENT ',' STR ',' issue ',' edition ')' { free ($6); free ($8); } -| '(' K_REMOVED ',' IDENT ',' STR ',' issue ',' K_NONE ',' reason ')' { +| '(' K_REMOVED ',' IDENT ',' STR ',' issue ',' K_NONE ',' reason ')' ',' { char *ident_upper; // HACK: convert no_debug to F_NO_DEBUG instead // since NO_DEBUG is used as an unrelated macro @@ -100,7 +111,7 @@ entry: '(' K_ACTIVE ',' IDENT ',' STR ',' issue ',' edition ')' { free ($8); free ($12); } -| '(' K_STABLE_REMOVED ',' IDENT ',' STR ',' issue ',' K_NONE ')' { +| '(' K_STABLE_REMOVED ',' IDENT ',' STR ',' issue ',' K_NONE ')' ',' { char *ident_upper = strdup ($4); for (size_t i = 0; ident_upper[i]; i++) ident_upper[i] = toupper (ident_upper[i]); @@ -110,6 +121,11 @@ entry: '(' K_ACTIVE ',' IDENT ',' STR ',' issue ',' edition ')' { free ($6); free ($8); } +| K_STATUS_TO_BOOL IDENT { + // no-op + // declare_features! sometimes invokes itself + // false positive +} ; issue: K_SOME '(' NUM ')' { $$ = $3; } diff --git a/gcc/rust/checks/errors/feature/contrib/scan.l b/gcc/rust/checks/errors/feature/contrib/scan.l index e2778b63b58a..4c3ba0bcf7a6 100644 --- a/gcc/rust/checks/errors/feature/contrib/scan.l +++ b/gcc/rust/checks/errors/feature/contrib/scan.l @@ -22,6 +22,40 @@ along with GCC; see the file COPYING3. If not see static int p_count = 0; +static void expand_char_lit (char *contents) +{ + // can not consume more space than original + // only expand \\\n[ws]* -> "" + // since everything else should be handled by C++ + char *read = contents; + char *write = contents; + while (*read) + { + if (read[0] == '\\' && read[1] == '\n') + { + read += 2; + while (1) + { + switch (*read) + { + case '\t': + case '\n': + case '\r': + case ' ': + read++; + continue; + } + break; + } + } + else + { + *(write++) = *(read++); + } + } + *write = '\0'; +} + %} %x INSIDE COMMENT @@ -38,15 +72,17 @@ declare_features! BEGIN (INSIDE); <INSIDE>Some return K_SOME; <INSIDE>None return K_NONE; <INSIDE>active return K_ACTIVE; +<INSIDE>incomplete return K_INCOMPLETE; <INSIDE>accepted return K_ACCEPTED; <INSIDE>removed return K_REMOVED; <INSIDE>stable_removed return K_STABLE_REMOVED; <INSIDE>Edition return K_E_START; <INSIDE>Edition2018 return K_E_2018; +<INSIDE>__status_to_bool return K_STATUS_TO_BOOL; -<INSIDE>[A-Za-z_][A-Za-z0-9_]* yylval.str = strdup (yytext); return IDENT; +<INSIDE>$?[A-Za-z_][A-Za-z0-9_]* yylval.str = strdup (yytext); return IDENT; <INSIDE>[1-9][0-9]* yylval.str = strdup (yytext); return NUM; -<INSIDE>\"[^"]+\" yylval.str = strdup (yytext); return STR; +<INSIDE>\"([^"\\]|\\\"|\\\n)*\" yylval.str = strdup (yytext); expand_char_lit (yylval.str); return STR; <INSIDE>"/""/" BEGIN (COMMENT); <INSIDE>[ \n] /* ignore */ <INSIDE>. { fprintf (stderr, "unrecognized character %u\n", (unsigned int) yytext[0]); exit (1); }
