From: Owen Avery <[email protected]>
"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]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github:
https://github.com/Rust-GCC/gccrs/commit/7a19dd777450d4dd8b6156e66addc943d4c13195
The commit has NOT been mentioned in any issue.
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4936
.../checks/errors/feature/contrib/Makefile | 3 +-
.../errors/feature/contrib/copyright-stub.h | 2 +-
.../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 036236166..15344e171 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 662bad37b..9164dc944 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 175721f4b..02d9e38f4 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 e2778b63b..4c3ba0bcf 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); }
base-commit: accca202ed122cb1e1af1988c144f9a889ee9103
--
2.55.0