Skip to content

librustc_codegen_llvm: Pass bitflags as raw integral types for FFI (#61306) #61867

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

jrtc27
Copy link

@jrtc27 jrtc27 commented Jun 15, 2019

The C++ side uses enums with underlying integral types. However, Rust's bitflags types are a single-field struct containing an integral type, which are not always passed the same way in the C ABI. In particular, sparc64's ABI extends integral types to a full 64-bit value, but does not do the same for single-field structs. Thanks to Michael Karcher for finding this bug.

@rust-highfive
Copy link
Contributor

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @petrochenkov (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 15, 2019
@jrtc27
Copy link
Author

jrtc27 commented Jun 15, 2019

@psumbera / @glaubitz - could you please test whether this fixes the bug?

@glaubitz
Copy link
Contributor

I think you need to adjust the imports used:

error: unused import: `DISPFlags`=================================>    ] 14/15: rustc_codegen_llvm                                                                        
 --> src/librustc_codegen_llvm/llvm/ffi.rs:5:27
  |
5 |     DINameSpace, DIFlags, DISPFlags, DebugEmissionKind,
  |                           ^^^^^^^^^
  |
  = note: `-D unused-imports` implied by `-D warnings`

error: aborting due to previous error

error: Could not compile `rustc_codegen_llvm`.

Since you no longer use DISPFlags.

@rust-highfive
Copy link
Contributor

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:000511ae:start=1560603739665838614,finish=1560603740457916787,duration=792078173
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---
[00:26:09]    Compiling rustc-demangle v0.1.15
[00:26:13]    Compiling memmap v0.6.2
[00:26:14]    Compiling num_cpus v1.8.0
[00:26:17]    Compiling rustc_llvm v0.0.0 (/checkout/src/librustc_llvm)
[00:26:22] error: unused import: `DISPFlags`
[00:26:22]  --> src/librustc_codegen_llvm/llvm/ffi.rs:5:27
[00:26:22]   |
[00:26:22] 5 |     DINameSpace, DIFlags, DISPFlags, DebugEmissionKind,
[00:26:22]   |
[00:26:22]   = note: `-D unused-imports` implied by `-D warnings`
[00:26:22] 
[00:26:24] error: aborting due to previous error
---
travis_time:end:081a19c4:start=1560605336991578483,finish=1560605336996960140,duration=5381657
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:017311b1
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:20566ec

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

…ust-lang#61306)

The C++ side uses enums with underlying integral types. However, Rust's
bitflags types are a single-field struct containing an integral type,
which are not always passed the same way in the C ABI. In particular,
sparc64's ABI extends integral types to a full 64-bit value, but does
not do the same for single-field structs. Thanks to Michael Karcher for
finding this bug.
@jrtc27 jrtc27 force-pushed the sparc64-bitflags branch from bf07d6f to 3d5f11c Compare June 15, 2019 13:37
@jrtc27
Copy link
Author

jrtc27 commented Jun 15, 2019

@glaubitz Travis has now passed that error, could you please retry?

@glaubitz
Copy link
Contributor

Already working on it :).

@glaubitz
Copy link
Contributor

I can confirm that this patch fixes the problem for me. Will do a full rebuild now just to be sure there are no side effects.

@glaubitz
Copy link
Contributor

Oh, I just realized you changed the patch quite a lot. I used the first version of the patch and just removed the unused import.

@jrtc27 jrtc27 changed the title LLVMRustDIBuilderCreateFunction: Pass bitflags as raw integral type (#61306) librustc_codegen_llvm: Pass bitflags as raw integral types for FFI (#61306) Jun 15, 2019
@glaubitz
Copy link
Contributor

glaubitz commented Jun 15, 2019

I have just finished testing the latest version of the patch and I can confirm it fixes the problem for me.

I just cross-built rustc from git for sparc64, copied it over to a sparc64 machine and did a full successful native build of rustc from git on sparc64 with this patch applied to the sources.

@petrochenkov
Copy link
Contributor

I suspect that you may be able to put #[repr(transparent)] on the bitflag structures instead and it will fix the ABI automatically.
Could you check whether that works?

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 15, 2019
@glaubitz
Copy link
Contributor

Okay, testing this change now:

diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index a71243c7c8..5ef0e6246b 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -566,6 +566,7 @@ pub mod debuginfo {
     bitflags! {
         #[repr(C)]
         #[derive(Default)]
+        #[repr(transparent)]
         pub struct DIFlags: ::libc::uint32_t {
             const FlagZero                = 0;
             const FlagPrivate             = 1;
@@ -595,6 +596,7 @@ pub mod debuginfo {
     bitflags! {
         #[repr(C)]
         #[derive(Default)]
+        #[repr(transparent)]
         pub struct DISPFlags: ::libc::uint32_t {
             const SPFlagZero              = 0;
             const SPFlagVirtual           = 1;

@glaubitz
Copy link
Contributor

This seems to work:

diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index a71243c7c8..a5c295cd45 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -564,7 +564,7 @@ pub mod debuginfo {
 
     // These values **must** match with LLVMRustDIFlags!!
     bitflags! {
-        #[repr(C)]
+        #[repr(transparent)]
         #[derive(Default)]
         pub struct DIFlags: ::libc::uint32_t {
             const FlagZero                = 0;
@@ -593,7 +593,7 @@ pub mod debuginfo {
 
     // These values **must** match with LLVMRustDISPFlags!!
     bitflags! {
-        #[repr(C)]
+        #[repr(transparent)]
         #[derive(Default)]
         pub struct DISPFlags: ::libc::uint32_t {
             const SPFlagZero              = 0;

@glaubitz
Copy link
Contributor

I have created #61881 now.

@petrochenkov
Copy link
Contributor

Closing in favor of #61881

@jrtc27 jrtc27 deleted the sparc64-bitflags branch June 16, 2019 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants