diff options
author | Marc Poulhiès <dkm@kataplop.net> | 2023-07-12 19:00:10 +0200 |
---|---|---|
committer | Arthur Cohen <arthur.cohen@embecosm.com> | 2024-01-16 19:00:26 +0100 |
commit | 8b1e1faa7f2eec13df511fa76d181337efb14f4d (patch) | |
tree | b27afcc750e989da83dcf0a659d2e4cf23eb2b54 | |
parent | 3b0a200eb8c986f17c550b902d5f7ab832b716e2 (diff) | |
download | gcc-8b1e1faa7f2eec13df511fa76d181337efb14f4d.zip gcc-8b1e1faa7f2eec13df511fa76d181337efb14f4d.tar.gz gcc-8b1e1faa7f2eec13df511fa76d181337efb14f4d.tar.bz2 |
gccrs: better handling of incorrect file loading in include_* builtin macros
When the load_file_bytes() fails to open the file, it emits an error but
returns an empty vector (as if the file is empty).
Instead, return a tl::optional nullopt in case of error and an empty
vector in case of an empty file.
fixes #2421
gcc/rust/ChangeLog:
* expand/rust-macro-builtins.cc
(load_file_bytes): Return a tl::optional.
(MacroBuiltin::include_byte_handler): Adjust and check file was
correctly opened.
(MacroBuiltin::include_str_handler): Likewise.
gcc/testsuite/ChangeLog:
* rust/compile/empty_file: New file.
* rust/compile/issue-2421_str.rs: New test.
Signed-off-by: Marc Poulhiès <dkm@kataplop.net>
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins.cc | 26 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/empty_file | 0 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-2421_str.rs | 10 |
3 files changed, 28 insertions, 8 deletions
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc index 20c207e..718d740 100644 --- a/gcc/rust/expand/rust-macro-builtins.cc +++ b/gcc/rust/expand/rust-macro-builtins.cc @@ -370,14 +370,14 @@ source_relative_path (std::string path, location_t locus) /* Read the full contents of the file FILENAME and return them in a vector. FIXME: platform specific. */ -std::vector<uint8_t> +tl::optional<std::vector<uint8_t>> load_file_bytes (location_t invoc_locus, const char *filename) { RAIIFile file_wrap (filename); if (file_wrap.get_raw () == nullptr) { rust_error_at (invoc_locus, "cannot open filename %s: %m", filename); - return std::vector<uint8_t> (); + return tl::nullopt; } FILE *f = file_wrap.get_raw (); @@ -387,7 +387,7 @@ load_file_bytes (location_t invoc_locus, const char *filename) std::vector<uint8_t> buf (fsize); - if (fread (&buf[0], fsize, 1, f) != 1) + if (fsize > 0 && fread (&buf[0], fsize, 1, f) != 1) { rust_error_at (invoc_locus, "error reading file %s: %m", filename); return std::vector<uint8_t> (); @@ -453,8 +453,12 @@ MacroBuiltin::include_bytes_handler (location_t invoc_locus, std::string target_filename = source_relative_path (lit_expr->as_string (), invoc_locus); - std::vector<uint8_t> bytes - = load_file_bytes (invoc_locus, target_filename.c_str ()); + auto maybe_bytes = load_file_bytes (invoc_locus, target_filename.c_str ()); + + if (!maybe_bytes.has_value ()) + return AST::Fragment::create_error (); + + std::vector<uint8_t> bytes = maybe_bytes.value (); /* Is there a more efficient way to do this? */ std::vector<std::unique_ptr<AST::Expr>> elts; @@ -518,8 +522,12 @@ MacroBuiltin::include_str_handler (location_t invoc_locus, std::string target_filename = source_relative_path (lit_expr->as_string (), invoc_locus); - std::vector<uint8_t> bytes - = load_file_bytes (invoc_locus, target_filename.c_str ()); + auto maybe_bytes = load_file_bytes (invoc_locus, target_filename.c_str ()); + + if (!maybe_bytes.has_value ()) + return AST::Fragment::create_error (); + + std::vector<uint8_t> bytes = maybe_bytes.value (); /* FIXME: reuse lexer */ int expect_single = 0; @@ -568,8 +576,10 @@ MacroBuiltin::include_str_handler (location_t invoc_locus, if (expect_single) rust_error_at (invoc_locus, "%s was not a valid utf-8 file", target_filename.c_str ()); - else + else if (!bytes.empty ()) str = std::string ((const char *) &bytes[0], bytes.size ()); + else + return tl::nullopt; auto node = AST::SingleASTNode (make_string (invoc_locus, str)); auto str_tok = make_token (Token::make_string (invoc_locus, std::move (str))); diff --git a/gcc/testsuite/rust/compile/empty_file b/gcc/testsuite/rust/compile/empty_file new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/gcc/testsuite/rust/compile/empty_file diff --git a/gcc/testsuite/rust/compile/issue-2421_str.rs b/gcc/testsuite/rust/compile/issue-2421_str.rs new file mode 100644 index 0000000..2616ccb --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2421_str.rs @@ -0,0 +1,10 @@ +#![feature(rustc_attrs)] + +#[rustc_builtin_macro] +macro_rules! include_str { + () => {{}}; +} + +fn main() { + include_str!("empty_file"); +} |