https://gcc.gnu.org/g:ebdd571ddf4711320bb8628df1d4179d3f2e8e75

commit r17-2239-gebdd571ddf4711320bb8628df1d4179d3f2e8e75
Author: Yap Zhi Heng <[email protected]>
Date:   Tue Jun 2 11:07:27 2026 +0800

    gccrs: Add new compiler flag for parsing & compiling C-style string literals
    
    gcc/rust/ChangeLog:
            * lang.opt: Add new -frust-c-style-string-literals option.
            * parse/rust-parse.h: Import options.h for reading 
flag_c_style_string_literals.
            * parse/rust-parse-impl-expr.hxx 
(Parser<ManagedTokenSource>::parse_literal_expr):
            Abort parsing C-style string literals if 
flag_c_style_string_literals is not set.
            (Parser<ManagedTokenSource>::null_denotation_not_path): Ditto.
    
    gcc/testsuite/ChangeLog:
            * rust/execute/torture/c_string.rs: Set 
-frust-c-style-string-literals.
            * rust/compile/c_string_null_byte_check.rs: Set 
-frust-c-style-string-literals.
    
    Signed-off-by: Yap Zhi Heng <[email protected]>

Diff:
---
 gcc/rust/lang.opt                                  |  4 +++
 gcc/rust/parse/rust-parse-impl-expr.hxx            | 42 ++++++++++++++++++----
 gcc/rust/parse/rust-parse.h                        |  1 +
 .../rust/compile/c_string_null_byte_check.rs       |  1 +
 gcc/testsuite/rust/execute/torture/c_string.rs     |  3 +-
 5 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
index 2fe63fa70935..1d38fec8635a 100644
--- a/gcc/rust/lang.opt
+++ b/gcc/rust/lang.opt
@@ -237,4 +237,8 @@ frust-unused-check-2.0
 Rust Var(flag_unused_check_2_0)
 Use the new unused variable check implementation.
 
+frust-c-style-string-literals
+Rust Var(flag_c_style_string_literals)
+Enable parsing and compilation of C-styled string literals.
+
 ; This comment is to ensure we retain the blank line above.
diff --git a/gcc/rust/parse/rust-parse-impl-expr.hxx 
b/gcc/rust/parse/rust-parse-impl-expr.hxx
index cc5c40f715a3..127b2c7a2fd7 100644
--- a/gcc/rust/parse/rust-parse-impl-expr.hxx
+++ b/gcc/rust/parse/rust-parse-impl-expr.hxx
@@ -343,9 +343,26 @@ Parser<ManagedTokenSource>::parse_literal_expr 
(AST::AttrVec outer_attrs)
       lexer.skip_token ();
       break;
     case C_STRING_LITERAL:
-      type = AST::Literal::C_STRING;
-      literal_value = t->get_str ();
-      lexer.skip_token ();
+      {
+       if (flag_c_style_string_literals)
+         {
+           type = AST::Literal::C_STRING;
+           literal_value = t->get_str ();
+           lexer.skip_token ();
+         }
+       else
+         {
+           add_error (
+             Error (t->get_locus (),
+                    "unexpected token %qs when parsing literal expression - "
+                    "C-style string literals require "
+                    "%<-frust-c-style-string-literals%> to be enabled",
+                    t->get_token_description ()));
+           return tl::unexpected<Parse::Error::Node> (
+             Parse::Error::Node::MALFORMED);
+         }
+      }
+
       break;
     case INT_LITERAL:
       type = AST::Literal::INT;
@@ -2117,9 +2134,22 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
        new AST::LiteralExpr (tok->get_str (), AST::Literal::RAW_STRING,
                              tok->get_type_hint (), {}, tok->get_locus ()));
     case C_STRING_LITERAL:
-      return std::unique_ptr<AST::LiteralExpr> (
-       new AST::LiteralExpr (tok->get_str (), AST::Literal::C_STRING,
-                             tok->get_type_hint (), {}, tok->get_locus ()));
+      if (flag_c_style_string_literals)
+       {
+         return std::unique_ptr<AST::LiteralExpr> (
+           new AST::LiteralExpr (tok->get_str (), AST::Literal::C_STRING,
+                                 tok->get_type_hint (), {},
+                                 tok->get_locus ()));
+       }
+      else
+       {
+         Error error (tok->get_locus (),
+                      "C-style string literals require "
+                      "%<-frust-c-style-string-literals%> to be enabled");
+         add_error (std::move (error));
+         return tl::unexpected<Parse::Error::Expr> (
+           Parse::Error::Expr::MALFORMED);
+       }
     case CHAR_LITERAL:
       return std::unique_ptr<AST::LiteralExpr> (
        new AST::LiteralExpr (tok->get_str (), AST::Literal::CHAR,
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 84f7d17435e9..ee27e9674ef4 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "rust-feature-store.h"
 
 #include "expected.h"
+#include "options.h"
 
 namespace Rust {
 
diff --git a/gcc/testsuite/rust/compile/c_string_null_byte_check.rs 
b/gcc/testsuite/rust/compile/c_string_null_byte_check.rs
index 6d31e0a4e96e..ac464bb2828c 100644
--- a/gcc/testsuite/rust/compile/c_string_null_byte_check.rs
+++ b/gcc/testsuite/rust/compile/c_string_null_byte_check.rs
@@ -1,3 +1,4 @@
+// { dg-additional-options "-frust-c-style-string-literals" }
 #![feature(no_core)]
 #![no_core]
 
diff --git a/gcc/testsuite/rust/execute/torture/c_string.rs 
b/gcc/testsuite/rust/execute/torture/c_string.rs
index 58b481198bfa..af96d05915a0 100644
--- a/gcc/testsuite/rust/execute/torture/c_string.rs
+++ b/gcc/testsuite/rust/execute/torture/c_string.rs
@@ -1,3 +1,4 @@
+// { dg-additional-options "-frust-c-style-string-literals" }
 // { dg-output "gccrs\n" }
 #![feature(no_core)]
 #![no_core]
@@ -9,6 +10,6 @@ extern "C" {
 pub fn main() {
     let a = c"gccrs";
     unsafe {
-        printf(a as *const [u8] as *const i8); // TODO change *const [u8] to 
.as_ptr() when C strings are compiled to their own CStr type
+        printf(a as *const [u8] as *const i8); // TODO change `as *const [u8]` 
to `.as_ptr()` when C strings are compiled to their own CStr type
     }
 }

Reply via email to