aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/expand/rust-macro-builtins.cc26
-rw-r--r--gcc/testsuite/rust/compile/empty_file0
-rw-r--r--gcc/testsuite/rust/compile/issue-2421_str.rs10
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");
+}