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 } }
