diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-07-27 13:36:51 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-27 13:36:51 +0000 |
commit | f76ddb42f82c04baf6b14aef1b532ccb5a0425bb (patch) | |
tree | 5b2ddeb0e2c1839ff97d7aa78886345295ef607a /gcc/rust/rust-gcc.cc | |
parent | 9526e6d62167ff824814c7ac8c09b36316029262 (diff) | |
parent | 7f8adccb5056152edc4aacf08ce2ed040f076171 (diff) | |
download | gcc-f76ddb42f82c04baf6b14aef1b532ccb5a0425bb.zip gcc-f76ddb42f82c04baf6b14aef1b532ccb5a0425bb.tar.gz gcc-f76ddb42f82c04baf6b14aef1b532ccb5a0425bb.tar.bz2 |
Merge #598
598: Hello world r=philberty a=philberty
```rust
extern "C" {
fn puts(s: *const i8);
}
fn main() {
unsafe {
let a = "Hello World\0";
let b = a as *const str;
let c = b as *const i8;
puts(c);
}
}
```
Fixes #421
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc/rust/rust-gcc.cc')
-rw-r--r-- | gcc/rust/rust-gcc.cc | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc index 23a91ad..44617a6 100644 --- a/gcc/rust/rust-gcc.cc +++ b/gcc/rust/rust-gcc.cc @@ -256,6 +256,11 @@ public: const std::vector<Btyped_identifier> &, Btype *, const Location); + Btype *function_type_varadic (const Btyped_identifier &, + const std::vector<Btyped_identifier> &, + const std::vector<Btyped_identifier> &, Btype *, + const Location); + Btype *function_ptr_type (Btype *, const std::vector<Btype *> &, Location); Btype *struct_type (const std::vector<Btyped_identifier> &); @@ -1049,6 +1054,62 @@ Gcc_backend::function_type (const Btyped_identifier &receiver, } Btype * +Gcc_backend::function_type_varadic ( + const Btyped_identifier &receiver, + const std::vector<Btyped_identifier> ¶meters, + const std::vector<Btyped_identifier> &results, Btype *result_struct, Location) +{ + size_t n = parameters.size () + (receiver.btype != NULL ? 1 : 0); + tree *args = XALLOCAVEC (tree, n); + size_t offs = 0; + + if (receiver.btype != NULL) + { + tree t = receiver.btype->get_tree (); + if (t == error_mark_node) + return this->error_type (); + + args[offs++] = t; + } + + for (std::vector<Btyped_identifier>::const_iterator p = parameters.begin (); + p != parameters.end (); ++p) + { + tree t = p->btype->get_tree (); + if (t == error_mark_node) + return this->error_type (); + args[offs++] = t; + } + + tree result; + if (results.empty ()) + result = void_type_node; + else if (results.size () == 1) + result = results.front ().btype->get_tree (); + else + { + gcc_assert (result_struct != NULL); + result = result_struct->get_tree (); + } + if (result == error_mark_node) + return this->error_type (); + + // The libffi library cannot represent a zero-sized object. To + // avoid causing confusion on 32-bit SPARC, we treat a function that + // returns a zero-sized value as returning void. That should do no + // harm since there is no actual value to be returned. See + // https://gcc.gnu.org/PR72814 for details. + if (result != void_type_node && int_size_in_bytes (result) == 0) + result = void_type_node; + + tree fntype = build_varargs_function_type_array (result, n, args); + if (fntype == error_mark_node) + return this->error_type (); + + return this->make_type (build_pointer_type (fntype)); +} + +Btype * Gcc_backend::function_ptr_type (Btype *result_type, const std::vector<Btype *> ¶meters, Location /* locus */) |