]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Add new compiler flag for parsing & compiling C-style string literals
authorYap Zhi Heng <yapzhhg@gmail.com>
Tue, 2 Jun 2026 03:07:27 +0000 (11:07 +0800)
committerArthur Cohen <arthur.cohen@embecosm.com>
Wed, 8 Jul 2026 15:22:47 +0000 (17:22 +0200)
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 <yapzhhg@gmail.com>
gcc/rust/lang.opt
gcc/rust/parse/rust-parse-impl-expr.hxx
gcc/rust/parse/rust-parse.h
gcc/testsuite/rust/compile/c_string_null_byte_check.rs
gcc/testsuite/rust/execute/torture/c_string.rs

index 2fe63fa70935130a527d2b40e41c73bc490573e6..1d38fec8635a18b39414a1c4cfdb930ebddb1c9e 100644 (file)
@@ -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.
index cc5c40f715a3a5583f1f4253e4cd1a873b9e0de2..127b2c7a2fd73542c6e740caf1e7400333ae4ff7 100644 (file)
@@ -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,
index 84f7d17435e9d9376169a9a635db1d8abf5fe3a3..ee27e9674ef4af4ab5a27f798b4aa7246a148dce 100644 (file)
@@ -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 {
 
index 6d31e0a4e96ea327d15994e493acbc227ed08fc1..ac464bb2828c7a3147179d8c103af8da42e1da6c 100644 (file)
@@ -1,3 +1,4 @@
+// { dg-additional-options "-frust-c-style-string-literals" }
 #![feature(no_core)]
 #![no_core]
 
index 58b481198bfa9270eac70e0cb40c61f759668bdd..af96d05915a0ca61f1b840a94074e60002990000 100644 (file)
@@ -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
     }
 }