-
Notifications
You must be signed in to change notification settings - Fork 246
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
transpile
: Make volatile post-increment assignment compile
#1135
base: master
Are you sure you want to change the base?
Conversation
GPHemsley
commented
Sep 21, 2024
•
edited by kkysen
Loading
edited by kkysen
- Fixes Missing semicolon after volatile pointer cast. #1049.
- Fixes In the while loop body using a volatile variable, the generated code will lack a semicolon. #1064.
transpile
: Make volatile post-increment assignment compile
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.
Thanks for fixing this! I'm still trying to understand what exactly is happening here and why the code was fine before for non-volatile writes, as I'm not too familiar with this part of the code. So still reviewing...
I also don't understand, but I've also added a test case to prove that non-volatile writes were indeed working before. |
I think it's simply rare that volatile writes like this occur, and so this scenario was not commonly hit. There isn't a comprehensive test suite for the operator code, so edge cases are not always being tested. |
As for why pub fn assign_expr(self, lhs: Box<Expr>, rhs: Box<Expr>) -> Box<Expr> {
Box::new(Expr::Assign(ExprAssign {
attrs: self.attrs,
eq_token: Token![=](self.span),
left: lhs,
right: rhs,
}))
} pub fn call_expr(self, func: Box<Expr>, args: Vec<Box<Expr>>) -> Box<Expr> {
let args = args.into_iter().map(|a| *a).collect();
Box::new(parenthesize_if_necessary(Expr::Call(ExprCall {
attrs: self.attrs,
paren_token: token::Paren(self.span),
func,
args,
})))
} pub fn expr_stmt(self, expr: Box<Expr>) -> Stmt {
Stmt::Expr(*expr)
}
pub fn semi_stmt(self, expr: Box<Expr>) -> Stmt {
Stmt::Semi(*expr, Token![;](self.span))
} #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
impl ToTokens for Stmt {
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
Stmt::Local(local) => local.to_tokens(tokens),
Stmt::Item(item) => item.to_tokens(tokens),
Stmt::Expr(expr) => expr.to_tokens(tokens),
Stmt::Semi(expr, semi) => {
expr.to_tokens(tokens);
semi.to_tokens(tokens);
}
}
}
} |
If it helps, this code: int i = 0;
i++;
int i2 = i++;
int i3 = i--;
i--;
volatile int vi = 0;
vi++;
volatile int vi2 = vi++;
volatile int vi3 = vi--;
vi--; generates this code: let mut i: libc::c_int = 0 as libc::c_int;
i += 1;
i;
let fresh0 = i;
i = i + 1;
let mut i2: libc::c_int = fresh0;
let fresh1 = i;
i = i - 1;
let mut i3: libc::c_int = fresh1;
i -= 1;
i;
let mut vi: libc::c_int = 0 as libc::c_int;
::core::ptr::write_volatile(
&mut vi as *mut libc::c_int,
::core::ptr::read_volatile::<libc::c_int>(&vi as *const libc::c_int) + 1,
);
::core::ptr::read_volatile::<libc::c_int>(&vi as *const libc::c_int);
let fresh2 = ::core::ptr::read_volatile::<libc::c_int>(&vi as *const libc::c_int);
::core::ptr::write_volatile(
&mut vi as *mut libc::c_int,
::core::ptr::read_volatile::<libc::c_int>(&vi as *const libc::c_int) + 1,
)
let mut vi2: libc::c_int = fresh2;
let fresh3 = ::core::ptr::read_volatile::<libc::c_int>(&vi as *const libc::c_int);
::core::ptr::write_volatile(
&mut vi as *mut libc::c_int,
::core::ptr::read_volatile::<libc::c_int>(&vi as *const libc::c_int) - 1,
)
let mut vi3: libc::c_int = fresh3;
::core::ptr::write_volatile(
&mut vi as *mut libc::c_int,
::core::ptr::read_volatile::<libc::c_int>(&vi as *const libc::c_int) - 1,
);
::core::ptr::read_volatile::<libc::c_int>(&vi as *const libc::c_int);
|