about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorDeadbeef <ent3rm4n@gmail.com>2023-03-10 14:18:58 +0000
committerDeadbeef <ent3rm4n@gmail.com>2023-05-02 10:32:08 +0000
commitabb181dfd9b9df22908ab08d7cfb46509295e2e6 (patch)
tree3872f7b6250f2b217082481899f4de183d12a3c7 /compiler
parentbf3ca5979e47774802e95623c11e71fb303e5ff3 (diff)
downloadrust-abb181dfd9b9df22908ab08d7cfb46509295e2e6.tar.gz
rust-abb181dfd9b9df22908ab08d7cfb46509295e2e6.zip
make it semantic error
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast/src/util/literal.rs2
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs1
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs3
-rw-r--r--compiler/rustc_session/messages.ftl2
-rw-r--r--compiler/rustc_session/src/errors.rs15
5 files changed, 22 insertions, 1 deletions
diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index cd3b163e3ac..15a54fe13d0 100644
--- a/compiler/rustc_ast/src/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
@@ -8,6 +8,7 @@ use rustc_lexer::unescape::{
 };
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::Span;
+use std::ops::Range;
 use std::{ascii, fmt, str};
 
 // Escapes a string, represented as a symbol. Reuses the original symbol,
@@ -38,6 +39,7 @@ pub enum LitError {
     InvalidFloatSuffix,
     NonDecimalFloat(u32),
     IntTooLarge(u32),
+    NulInCStr(Range<usize>),
 }
 
 impl LitKind {
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 17bcd24ee39..c4578ec4af1 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -572,6 +572,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
             }
         };
     }
+    gate_all!(c_str_literals, "`c\"..\"` literals are experimental");
     gate_all!(
         if_let_guard,
         "`if let` guards are experimental",
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index b2050780309..050f1898615 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -204,6 +204,9 @@ impl<'a> StringReader<'a> {
                 rustc_lexer::TokenKind::Literal { kind, suffix_start } => {
                     let suffix_start = start + BytePos(suffix_start);
                     let (kind, symbol) = self.cook_lexer_literal(start, suffix_start, kind);
+                    if let token::LitKind::CStr | token::LitKind::CStrRaw(_) = kind {
+                        self.sess.gated_spans.gate(sym::c_str_literals, self.mk_sp(start, self.pos));
+                    }
                     let suffix = if suffix_start < self.pos {
                         let string = self.str_from(suffix_start);
                         if string == "_" {
diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl
index ff53f22d43f..2420857e739 100644
--- a/compiler/rustc_session/messages.ftl
+++ b/compiler/rustc_session/messages.ftl
@@ -93,3 +93,5 @@ session_invalid_int_literal_width = invalid width `{$width}` for integer literal
     .help = valid widths are 8, 16, 32, 64 and 128
 
 session_optimization_fuel_exhausted = optimization-fuel-exhausted: {$msg}
+
+session_nul_in_c_str = null characters in C string literals are not supported
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index bd32adbbdbb..22af74eb1d9 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -6,7 +6,7 @@ use rustc_ast::token;
 use rustc_ast::util::literal::LitError;
 use rustc_errors::{error_code, DiagnosticMessage, EmissionGuarantee, IntoDiagnostic, MultiSpan};
 use rustc_macros::Diagnostic;
-use rustc_span::{Span, Symbol};
+use rustc_span::{BytePos, Span, Symbol};
 use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
 
 #[derive(Diagnostic)]
@@ -307,6 +307,13 @@ pub(crate) struct BinaryFloatLiteralNotSupported {
     pub span: Span,
 }
 
+#[derive(Diagnostic)]
+#[diag(session_nul_in_c_str)]
+pub(crate) struct NulInCStr {
+    #[primary_span]
+    pub span: Span,
+}
+
 pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: Span) {
     // Checks if `s` looks like i32 or u1234 etc.
     fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
@@ -385,6 +392,12 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
             };
             sess.emit_err(IntLiteralTooLarge { span, limit });
         }
+        LitError::NulInCStr(range) => {
+            let lo = BytePos(span.lo().0 + range.start as u32 + 2);
+            let hi = BytePos(span.lo().0 + range.end as u32 + 2);
+            let span = span.with_lo(lo).with_hi(hi);
+            sess.emit_err(NulInCStr { span });
+        }
     }
 }