]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Add early cfg strip step before feature collection
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
Thu, 5 Feb 2026 12:58:11 +0000 (13:58 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Fri, 20 Mar 2026 17:10:36 +0000 (18:10 +0100)
Features are now collected early rather than later during the feature
gating visitor. This requires the introduction of an early cfg strip
in order to collect #![cfg(xxxx), feature(yyyy)] correctly.

gcc/rust/ChangeLog:

* Make-lang.in: Add rust-early-cfg-strip object file.
* expand/rust-cfg-strip.h (expand_cfg_attrs): Declare function prototype.
* rust-session-manager.cc (Session::compile_crate): Reorder feature
collection and add early cfg strip.
* expand/rust-early-cfg-strip.cc: New file.
* expand/rust-early-cfg-strip.h: New file.

Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
gcc/rust/Make-lang.in
gcc/rust/expand/rust-cfg-strip.h
gcc/rust/expand/rust-early-cfg-strip.cc [new file with mode: 0644]
gcc/rust/expand/rust-early-cfg-strip.h [new file with mode: 0644]
gcc/rust/rust-session-manager.cc

index b5d837f4685a518f715ab056ca62b72bdaf7571b..bd5eb8654fc4b5ccea1f4aa093e447034e58dfbe 100644 (file)
@@ -94,6 +94,7 @@ GRS_OBJS = \
     rust/rust-compile-resolve-path.o \
     rust/rust-macro-expand.o \
     rust/rust-cfg-strip.o \
+    rust/rust-early-cfg-strip.o \
     rust/rust-expand-visitor.o \
     rust/rust-ast-builder.o \
     rust/rust-derive.o \
index dfe724a778fa2d9b4c751b9e9903f59cf0577b7d..e372744f62d9df72358a87141890d7d007886a24 100644 (file)
@@ -24,6 +24,8 @@
 
 namespace Rust {
 
+void expand_cfg_attrs (AST::AttrVec &attrs);
+
 // forward declare
 struct ExpansionCfg;
 
diff --git a/gcc/rust/expand/rust-early-cfg-strip.cc b/gcc/rust/expand/rust-early-cfg-strip.cc
new file mode 100644 (file)
index 0000000..bc0e4b5
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (C) 2026 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-early-cfg-strip.h"
+#include "rust-cfg-strip.h"
+
+namespace Rust {
+
+void
+EarlyCfgStrip::go (AST::Crate &crate)
+{
+  visit (crate);
+}
+
+void
+EarlyCfgStrip::visit (AST::Crate &crate)
+{
+  expand_cfg_attrs (crate.inner_attrs);
+
+  AST::DefaultASTVisitor::visit (crate);
+}
+
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-early-cfg-strip.h b/gcc/rust/expand/rust-early-cfg-strip.h
new file mode 100644 (file)
index 0000000..b342aee
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (C) 2026 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_EARLY_CFG_STRIP_H
+#define RUST_EARLY_CFG_STRIP_H
+
+#include "rust-ast-visitor.h"
+
+namespace Rust {
+
+/**
+ * Some parts cannot be stripped during the expansion passes
+ */
+class EarlyCfgStrip : AST::DefaultASTVisitor
+{
+public:
+  using DefaultASTVisitor::visit;
+
+  void go (AST::Crate &crate);
+
+  void visit (AST::Crate &crate) override;
+};
+
+} // namespace Rust
+
+#endif
index 67adb103cee082cd96986983f1d30829428ab375..cf3237ccd71162016d66d8fd6748d95d92c9e159 100644 (file)
@@ -52,6 +52,7 @@
 #include "rust-early-name-resolver-2.0.h"
 #include "rust-late-name-resolver-2.0.h"
 #include "rust-resolve-builtins.h"
+#include "rust-early-cfg-strip.h"
 #include "rust-cfg-strip.h"
 #include "rust-expand-visitor.h"
 #include "rust-unicode.h"
@@ -669,7 +670,15 @@ Session::compile_crate (const char *filename)
 
   Analysis::AttributeChecker ().go (parsed_crate);
 
-  if (!has_attribute (parsed_crate, std::string (Values::Attributes::NO_CORE)))
+  EarlyCfgStrip ().go (parsed_crate);
+
+  auto parsed_crate_features
+    = Features::FeatureCollector{}.collect (parsed_crate);
+
+  // Do not inject core if some errors were emitted
+  if (!saw_errors ()
+      && !has_attribute (parsed_crate,
+                        std::string (Values::Attributes::NO_CORE)))
     {
       parsed_crate.inject_extern_crate ("core");
     }
@@ -702,8 +711,7 @@ Session::compile_crate (const char *filename)
   // feature gating
   if (last_step == CompileOptions::CompileStep::FeatureGating)
     return;
-  auto parsed_crate_features
-    = Features::FeatureCollector{}.collect (parsed_crate);
+
   FeatureGate (parsed_crate_features).check (parsed_crate);
 
   if (last_step == CompileOptions::CompileStep::NameResolution)