Abstract
Type systems are useful not just for the safety guarantees they provide, but also for helping compilers generate more efficient code by simplifying important program analyses. In Rust, the type system imposes a strict discipline on pointer aliasing, and it is an express goal of the Rust compiler developers to make use of that alias information for the purpose of program optimizations that reorder memory accesses. The problem is that Rust also supports unsafe code, and programmers can write unsafe code that bypasses the usual compiler checks to violate the aliasing discipline. To strike a balance between optimizations and unsafe code, the language needs to provide a set of rules such that unsafe code authors can be sure, if they are following these rules, that the compiler will preserve the semantics of their code despite all the optimizations it is doing.
In this work, we propose Stacked Borrows, an operational semantics for memory accesses in Rust. Stacked Borrows defines an aliasing discipline and declares programs violating it to have undefined behavior, meaning the compiler does not have to consider such programs when performing optimizations. We give formal proofs (mechanized in Coq) showing that this rules out enough programs to enable optimizations that reorder memory accesses around unknown code and function calls, based solely on intraprocedural reasoning. We also implemented this operational model in an interpreter for Rust and ran large parts of the Rust standard library test suite in the interpreter to validate that the model permits enough real-world unsafe Rust code.
Supplemental Material
- ANSI. 1978. Programming Language FORTRAN. ANSI X3.9-1978.Google Scholar
- Ulrich Drepper. 2007. Memory part 5: What programmers can do. LWN article. https://lwn.net/Articles/255364/ .Google Scholar
- Bruno De Fraine. 2014. Wrong results with union and strict-aliasing. LLVM issue #21725. https://bugs.llvm.org/show_bug. cgi?id=21725 .Google Scholar
- Rakesh Ghiya, Daniel M. Lavery, and David C. Sehr. 2001. On the importance of points-to analysis and other memory disambiguation methods for C programs. In PLDI. 47–58. Google Scholar
Digital Library
- Dan Gohman. 2015. Incorrect liveness in DeadStoreElimination. LLVM issue #25422. https://bugs.llvm.org/show_bug.cgi? id=25422 .Google Scholar
- Chris Hathhorn, Chucky Ellison, and Grigore Rosu. 2015. Defining the undefinedness of C. In Proceedings of the 36th ACM SIGPLAN Conference on Programming Language Design and Implementation, Portland, OR, USA, June 15-17, 2015. 336–345. Google Scholar
Digital Library
- Dara Hazeghi. 2013. Store motion causes wrong code for union access at -O3. GCC issue #57359. https://gcc.gnu.org/ bugzilla/show_bug.cgi?id=57359 .Google Scholar
- Susan Horwitz. 1997. Precise flow-insensitive may-alias analysis is NP-hard. TOPLAS 19, 1 (1997), 1–6. Google Scholar
Digital Library
- Chung-Kil Hur, Derek Dreyer, Georg Neis, and Viktor Vafeiadis. 2012. The marriage of bisimulations and Kripke logical relations. In POPL. Google Scholar
Digital Library
- ISO. 2017. C17 Standard. ISO/IEC 9899:2018.Google Scholar
- Ralf Jung. 2018a. Fix futures creating aliasing mutable and shared ref. Rust pull request #56319. https://github.com/rustlang/rust/pull/56319 .Google Scholar
- Ralf Jung. 2018b. VecDeque: fix for stacked borrows. Rust pull request #56161. https://github.com/rust-lang/rust/pull/56161 .Google Scholar
- Ralf Jung. 2019a. Fix LinkedList invalidating mutable references. Rust pull request #60072. https://github.com/rustlang/rust/pull/60072 .Google Scholar
- Ralf Jung. 2019b. Fix overlapping references in BTree. Rust pull request #58431. https://github.com/rust-lang/rust/pull/58431 .Google Scholar
- Ralf Jung. 2019c. Fix str mutating through a ptr derived from &self. Rust pull request #58200. https://github.com/rustlang/rust/pull/58200 .Google Scholar
- Ralf Jung. 2019d. VecDeque’s Drain::drop writes to memory that a shared reference points to. Rust issue #60076. https://github.com/rust-lang/rust/issues/60076 .Google Scholar
- Ralf Jung. 2019e. Vec::push invalidates interior references even when it does not reallocate. Rust issue #60847. https: //github.com/rust-lang/rust/issues/60847 .Google Scholar
- Ralf Jung, Hoang-Hai Dang, Jeehoon Kang, and Derek Dreyer. 2019. Stacked borrows: An aliasing model for Rust – Artifact. Google Scholar
Digital Library
- Ralf Jung, Jacques-Henri Jourdan, Robbert Krebbers, and Derek Dreyer. 2018. RustBelt: Securing the foundations of the Rust programming language. PACMPL 2, POPL, Article 66 (2018).Google Scholar
Digital Library
- Jeehoon Kang, Chung-Kil Hur, William Mansky, Dmitri Garbuzov, Steve Zdancewic, and Viktor Vafeiadis. 2015. A formal C memory model supporting integer-pointer casts. In PLDI. 326–335. Google Scholar
Digital Library
- Steve Klabnik and Carol Nichols. 2018. The Rust Programming Language. https://doc.rust-lang.org/stable/book/2018-edition/Google Scholar
- Felix S. Klock. 2019. Breaking news: Non-lexical lifetimes arrives for everyone. Blog post. http://blog.pnkfx.org/blog/2019/ 06/26/breaking-news-non-lexical-lifetimes-arrives-for-everyone/ .Google Scholar
- Robbert Krebbers. 2013. Aliasing restrictions of C11 formalized in Coq. In Certified Programs and Proofs - Third International Conference, CPP 2013, Melbourne, VIC, Australia, December 11-13, 2013, Proceedings. 50–65. Google Scholar
Digital Library
- Robbert Krebbers. 2015. The C standard formalized in Coq. Ph.D. Dissertation. Radboud University.Google Scholar
- Juneyoung Lee, Chung-Kil Hur, Ralf Jung, Zhengyang Liu, John Regehr, and Nuno P. Lopes. 2018. Reconciling high-level optimizations and low-level code in LLVM. PACMPL 2, OOPSLA (2018), 125:1–125:28. Google Scholar
Digital Library
- Xavier Leroy, Andrew Appel, Sandrine Blazy, and Gordon Stewart. 2012. The CompCert memory model, version 2. Technical Report RR-7987. Inria.Google Scholar
- Xavier Leroy and Sandrine Blazy. 2008. Formal verification of a C-like memory model and its uses for verifying program transformations. JAR 41, 1 (2008), 1–31. Google Scholar
Digital Library
- Niko Matsakis. 2018. An alias-based formulation of the borrow checker. Blog post. http://smallcultfollowing.com/babysteps/ blog/2018/04/27/an-alias-based-formulation-of-the-borrow-checker/ .Google Scholar
- Kayvan Memarian, Victor B. F. Gomes, Brooks Davis, Stephen Kell, Alexander Richardson, Robert N. M. Watson, and Peter Sewell. 2019. Exploring C semantics and pointer provenance. PACMPL 3, POPL (2019), 67:1–67:32. Google Scholar
Digital Library
- Kayvan Memarian and Peter Sewell. 2016. N2014: What is C in practice? (Cerberus survey v2): Analysis of Responses. ISO SC22 WG14 N2014, http://www.cl.cam.ac.uk/~pes20/cerberus/notes50-survey-discussion.html .Google Scholar
- Thi Viet Nga Nguyen and François Irigoin. 2003. Alias verification for Fortran code optimization. J. UCS 9, 3 (2003), 270. Google Scholar
Cross Ref
- Michael Norrish. 1998. C formalised in HOL. Ph.D. Dissertation. University of Cambridge.Google Scholar
- Nikita Popov. 2018. Loop unrolling incorrectly duplicates noalias metadata. LLVM issue #39282. https://bugs.llvm.org/ show_bug.cgi?id=39282 .Google Scholar
- John Regehr. 2017. Undefined behavior in 2017. Blog post. https://blog.regehr.org/archives/1520 .Google Scholar
- Valentin Robert and Xavier Leroy. 2012. A formally-verified alias analysis. In CPP. 11–26. Google Scholar
Digital Library
- Robert P. Wilson and Monica S. Lam. 1995. Efficient context-sensitive pointer analysis for C programs. In PLDI. 1. Google Scholar
Digital Library
Index Terms
Stacked borrows: an aliasing model for Rust
Recommendations
How do programmers use unsafe rust?
Rust’s ownership type system enforces a strict discipline on how memory locations are accessed and shared. This discipline allows the compiler to statically prevent memory errors, data races, inadvertent side effects through aliasing, and other errors ...
Understanding memory and thread safety practices and issues in real-world Rust programs
PLDI 2020: Proceedings of the 41st ACM SIGPLAN Conference on Programming Language Design and ImplementationRust is a young programming language designed for systems software development. It aims to provide safety guarantees like high-level languages and performance efficiency like low-level languages. The core design of Rust is a set of strict safety rules ...
The undecidability of aliasing
Alias analysis is a prerequisite for performing most of the common program analyses such as reaching-definitions analysis or live-variables analysis. Landi [1992] recently established that it is impossible to compute statically precise alias information—...






Comments