-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
Append missing padding after last field of struct #13271
Conversation
cc @jld |
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
// Issue #13186 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you please prefix the filename with trans
and add a description of what this test does ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By reading the test case, it's not obvious what the test is since default_instance
is never called, nor the value is used, etc.
It'd be nice if you could also explain why this succeeds to compile and how this test verifies the right alignment.
Thanks
@flaper87 done |
I came up with slighly different and slightly better approach. At startup compiler iterates over known integer types (i8, i16, i32, i64 and i8*) and populates map See updated patch. |
]; | ||
for &aligner_base in aligner_bases.iter() { | ||
let align = machine::llalign_of_min(&ccx, aligner_base); | ||
ccx.aligner_by_align.find_or_insert_with(align, |_| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless I'm missing something, you could just do ccx.aligner_by_align.find_or_insert(align, Type::array(&aligner_base, 0))
(or even just insert
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@flaper87 both insert
and find_or_insert
compute second parameter which may be unused. For instance, both i8p
and i64
might use same alignment, so only one of them can be inserted into map.
It looks like microoptimization, but I did it to emphasizes that not all aligner_bases
are used in map.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using find_or_insert
is fine, TBH. Like you said, current code is a micro-optimization. I'm fine either way but I don find find_or_insert
more readable in this case and this micro-optimization is probably not needed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@flaper87 OK, changed to find_or_insert
. Any change pull requested will be approved or rejected?
@alexcrichton @jld any final comments here? |
I am not familiar enough with the layout of enums to r+ this. It makes sense to me, but there's clearly a lot of subtle things going on here. |
I think there's a simpler solution: The problem, if I understand correctly, is that it's not fixing the padding after the last element, so the sizes don't match, which is why we get the assertion seen in #13186. (Also, I don't know offhand if we're passing the alignment to LLVM when creating the global, but that seems to not be the problem here.) |
@jld thanks, I'll do it (patch |
Updated the patch with padding after last field instead of aligner magic. |
@stepancheg Travis' failure seems legit. Mind taking a look? |
@flaper87 yes, thanks. |
@flaper87 funny thing is that this commit revealed another bug:
(when compiler with rust/master, it crashes at runtime). I think I have to fix it too. Sorry, I didn't run |
@stepancheg no worries. You know you can run tests just for stage1 rpass, right? You can do that with: I'm not a real expert in this part of the code but it would be amazing if you can fix that as part of this PR too. |
I thought that was fixed by #9832 ? (Or are you saying that you caused it?) |
This patch fixes issue rust-lang#13186. When generating constant expression for enum, it is possible that alignment of expression may be not equal to alignment of type. In that case space after last struct field must be padded to match size of value and size of struct. This commit adds that padding. See detailed explanation in src/test/run-pass/trans-tag-static-padding.rs
Fixed a patch. Previously, I checked it with |
let target_offset = *target_offsets.get(i); | ||
if !st.packed { | ||
let val_align = machine::llalign_of_min(ccx, val_ty(val)) | ||
/*bad*/as u64; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mind putting this in a single line and explain in a comment why this is bad for future readers? Also, it'd be nice to have a FIXME
with an issue filed if there's no other way to do this right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@flaper87 I have no idea, why it is bad. It was here before me. I guess it is a joke.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is because using u64
is not necessarily correct on all target platforms. (The thing to do would be check the git history.)
@stepancheg Thanks a lot for working on this. Great job. I left some minor comments there. Also, it'd be nice to have a separate test for the latest fix. Thanks again! |
@flaper87 there's nothing to test: offsets were computed incorrectly, but computed offsets did not affect result of |
Updated the patch, minor changes requested by @flaper87. |
Ping, is this waiting on anything other than a re-review? |
This patch fixes issue #13186. When generating constant expression for enum, it is possible that alignment of expression may be not equal to alignment of type. In that case space after last struct field must be padded to match size of value and size of struct. This commit adds that padding. See detailed explanation in src/test/run-pass/trans-tag-static-padding.rs
…t_n()` (rust-lang#13858) close rust-lang#13271 changelog: add new `manual_repeat_n` lint
This patch fixes issue #13186.
When generating constant expression for enum, it is possible that
alignment of expression may be not equal to alignment of type. In that
case space after last struct field must be padded to match size of value
and size of struct. This commit adds that padding.
See detailed explanation in src/test/run-pass/trans-tag-static-padding.rs