scispace - formally typeset
Search or ask a question
Proceedings ArticleDOI

A type system for safe memory management and its proof of correctness

TL;DR: It is proved that, in spite of sharing and of the use of implicit and explicit memory deallocation operations, all well-typed programs will be free of dangling pointers at runtime.
Abstract: We present a destruction-aware type system for the functional language Safe, which is a first-order eager language with facilities for programmer controlled destruction and copying of data structures. It provides also regions, i.e. disjoint parts of the heap, where the program allocates data structures. The runtime system does not need a garbage collector and all allocation/deallocation actions are done in constant time. The language is equipped with several analyses and inference algorithms so that regions, sharing information and types are automatically inferred by the compiler. Here, we concentrate on the correctness of the type system with respect to the operational semantics of the language. In particular, we prove that, in spite of sharing and of the use of implicit and explicit memory deallocation operations, all well-typed programs will be free of dangling pointers at runtime. The paper ends up with some examples of well-typed programs.

Summary (2 min read)

1 Introduction

  • Most functional languages abstract the programmer from the memory management done by programs at run time.
  • Well known problems are dangling references, undesired sharing with complex side effects, and polluting memory with garbage.
  • A small difference with these approaches is that, in Safe, region allocation and deallocation are synchronized with function calls instead of being introduced by a special language construct.
  • Inside the function, data structures may be built but they can also be destroyed by using a destructive pattern matching denoted by !.
  • The type system shown in this paper copes with all these features to avoid dangling pointers.

3 Operational Semantics

  • In Figure 2 the authors show the big-step operational semantics of the core language expressions.
  • This action may create dangling pointers in the live heap, as some cells may contain free occurrences of p. Rule App shows when a new region is allocated.
  • In functional types returning a DS, where there may be several region arguments ρl, these are a subset of the result’s regions ρm.
  • Inside a condemned type, type variables may be instatiated with safe or condemned types.
  • The operators on type environments used in the typing rules are shown in Fig.

5.1 Absence of Dangling Pointers due to Cell Destruction

  • The intuitive idea of a variable x being typed with a safe type s is that all the cells in h reachable from E(x) are also safe and they should be disjoint of unsafe cells.
  • The idea behind a condemned variable x is that all variables (including itself) and all live cells sharing any of its recursive descendants are unsafe.
  • The correctness of the sharing analysis mentioned in Section 4 has been proved elsewhere and it is not the subject of this paper, but the authors need it in order to prove the correctness of the whole type system.
  • By analogy, a final configuration (s, v, h′) is good whenever closed(v, h′) holds.
  • The authors conclude then that all well-typed Safe program never produce dangling pointers at runtime.

5.2 Correctness of Region Deallocation

  • This section proves that the structure returned by the function call does not reside in self .
  • The union of region instantiations (denoted by ∪) is defined only if they bind common type region variables to the same region, that is, they do not contradict each other.
  • Dangling pointers are never accessed by a program (Sec 5.1).
  • Now the authors define a notion of consistency between the variables belonging to a variable environment E. Intuitively it means that the correspondences between region type variables and concrete regions of each element of dom(E) do not contradict each other.
  • Since the type system (see rule [FUNB] in Fig. 5) enforces that the variable ρself does not occur in the type of the function result, then every data structure returned by the function call does not have cells in self .

6 Examples

  • Now the authors shall consider the concatD , treesort and treesortD functions defined in Sec. 2.
  • The desugared versions of their definitions are shown in Fig.
  • The first column is the result of the region inference phase, which inserts the @r annotations into the code.
  • Temporary structures are assigned the working region self .
  • To type its body, rule [LET2] is now applied, since xs′ is destroyed in the treesortD call.

Did you find this useful? Give us your feedback

Content maybe subject to copyright    Report

A Type System for Safe Memory Management
and its Proof of Correctness
?
(Technical report SIC-5-08)
Manuel Montenegro Ricardo Pe˜na Clara Segura
montenegro@fdi.ucm.es {ricardo,csegura}@sip.ucm.es
Universidad Complutense de Madrid, Spain
Abstract. We present a destruction-aware type system for the func-
tional language Safe, which is a first-order eager language with facilities
for programmer controlled destruction and copying of data structures.
It provides also regions, i.e. disjoint parts of the heap, where the pro-
gram allocates data structures. The runtime system does not need a
garbage collector and all allocation/deallocation actions are done in con-
stant time. This research is targeted to mobile code applications with
limited resources in a Proof Carrying Code framework.
The type system guarantees that, in spite of sharing and of the use of im-
plicit and explicit memory deallocation operations, well-typed programs
will be free of dangling pointers at runtime. We also prove its correctness
with respect to the operational semantics of the language.
1 Introduction
Most functional languages abstract the programmer from the memory manage-
ment done by programs at run time. The runtime support system usually allo-
cates fresh heap memory while program expressions are being evaluated as long
as there is enough free memory available. Should the memory be exhausted, the
garbage collector will copy the live part of the heap to a different space and will
consider the rest as free. This normally implies the suspension of program exe-
cution for some time. Occasionally, not enough free memory has been recovered
and the program simply aborts. This model is acceptable in most situations,
being its main advantage that programmers are not bored, and programs are
not obscured, with low level details about memory management. But, in some
other contexts, this scheme may not be acceptable:
1. The time delay introduced by garbage collection prevents the program from
providing an answer in a required reaction time.
2. Memory exhaustion abortion may provoke unacceptable personal or eco-
nomic damage to program users.
3. The programmer wishes to reason about memory consumption.
?
Work supported by the projects TIN2004-07943-C04, S-0505/TIC/0407 (PROME-
SAS) and the MEC FPU grant AP2006-02154.

On the other hand, many imperative languages offer low level mechanisms to
allocate and free heap memory. These mechanisms give programmers a complete
control over memory usage but are very error prone. Well known problems are
dangling references, undesired sharing with complex side effects, and polluting
memory with garbage.
In our functional language Safe, we have chosen a semi-explicit approach to
memory control in which programmers may cooperate with the memory man-
agement system by providing some information about the intended use of data
structures (in what follows, abbreviated as DS). For instance, they may indicate
that some particular DS will not be needed in the future and that it should be
destroyed by the runtime system and its memory recovered. Programmers may
also launch copies of a DS and control the degree of sharing between DSs. In
order to use these facilities in safe way, we have developed a type system which
guarantees that dangling pointers will never arise at runtime in the living heap.
The proposed approach overcomes the above mentioned shortcomings: (1)
A garbage collector is not needed because the heap is structured into disjoint
regions which are dynamically allocated and deallocated; (2) as we will see below,
we will be able to reason about memory consumption. It will even be possible
to show that an algorithm runs in constant heap space, independently of input
size; and (3), as an ultimate goal regions will allow us to statically infer sizes for
them and eventually an upper bound to the memory consumed by the program.
The language is targeted to mobile code applications with limited resources
in a Proof Carrying Code framework [Nec97,NL98]. The final aim is to endow
programs with formal certificates proving the above properties. This aspect, as
well as region size inference, are however beyond the scope of the current paper.
The Safe language and a sharing analysis for it were published in [PSM07a].
The use of regions in functional languages to avoid garbage collection is not
new. Tofte and Talpin [TT97] introduced in ML-Kit —a variant of ML— the
use of nested regions by means of a letregion construct. A lot of work has been
done on this system [AFL95,BTV96,HMN01,TBE
+
06]. Their main contribution
is a region inference algorithm adding region annotations at the intermediate
language level. Hughes and Pareto [HP99] incorporate regions in Embedded-
ML. This language uses a sized-types system in which the programmer annotates
heap and stack sizes and these annotations can be type-checked. So, regions can
be proved to be bounded. A small difference with these approaches is that,
in Safe, region allocation and deallocation are synchronized with function calls
instead of being introduced by a special language construct. A more relevant
difference is that Safe has an additional mechanism allowing the programmer to
selectively destroy data structures inside a region. More recently, Hofmann and
Jost [HJ03] have developed a type system to infer heap consumption. Theirs is
also a first-order eager functional language with a construct match
0
that destroys
constructor cells. Its operational behaviour is similar to that of Safe case!. The
main difference is that they lack a compile time analysis guaranteeing the safe use
of this dangerous feature. Also, their language do not use regions. In [PSM07a]
a more detailed comparison with all these works can be found.
Our safety type system has some characteristics of linear types (see [Wad90]
as a basic reference). A number of variants of linear types have been developed
2

for years for coping with the related problems of achieving safe updates in place
in functional languages [Ode92] or detecting program sites where values could be
safely deallocated [Kob99]. The work closest to our system is [AH02], which pro-
poses a type system for a language explicitly reusing heap cells. They prove that
well-typed programs can be safely translated into an imperative language with
an explicit deallocation/reusing mechanism. We summarise here the differences
and similarities with our work.
There are non-essential differences such as: (1) they only admit algorithms
running in constant heap space, i.e. for each allocation there must exist a previous
deallocation; (2) they use at the source level an explicit parameter d representing
a pointer to the cell being reused; and (3) they distinguish two different carte-
sian products depending on whether there is sharing or not between the tuple
components. But, in our view, the following more essential differences makes our
type-system more powerful than theirs:
1. Their uses 2 and 3 (read-only and shared, or just read-only) could be roughly
assimilated to our use s (read-only), and their use 1 (destructive), to our use
d (condemned), both defined in Section 4. We add a third use r (in-danger)
arising from a sharing analysis based on abstract interpretation [PSM07a].
This use allows us to know more precisely which variables are in danger when
some other one is destroyed.
2. Their uses form a total order 1 < 2 < 3. A type assumption can always
be worsened without destroying the well-typedness. Our marks s, r, d do not
form a total order. Only in some expressions (case and x@r) we allow the
partial order s r and s d. It is not clear whether that order gives or not
more power to the system. In principle it will allow diferent uses of a variable
in different branches of a conditional being the use of the whole conditional
the worst one. For the moment our system does not allow this.
3. Their system forbids non-linear applications such as f (x, x). We allow them
for s-type arguments.
4. Our typing rules for let x
1
= e
1
in e
2
allow more use combinations than
theirs. Let i {1, 2, 3} the use assigned to x
1
, j the use of a variable z in e
1
,
and k the use of the variable z in e
2
. We allow the following combinations
(i, j, k) that they forbid: (1, 2, 2), (1, 2, 3), (2, 2, 2), (2, 2, 3). The deep reason
is our more precise sharing information and the new in-danger type.
5. They need explicit declaration of uses while we infer them [PSM07b].
The plan of the paper is as follows; In Section 2 we informally introduce
and motivate the language features. Section 3 formally defines its operational
semantics. The kernel of the paper are sections 4 and 5 where respectively the
destruction-aware type system is presented and proved correct. By lack of space,
the detailed proofs are included in a separate appendix. Finally, Section 6 shows
examples of successful type derivations and Section 7 concludes.
2 Summary of Safe
Safe is a first-order polymorphic functional language similar to (first-order)
Haskell or ML with some facilities to manage memory. The memory model is
3

based in heap regions where data structures are built. However, in Full-Safe in
which programs are written, regions are implicit. These are inferred when Full-
Safe is desugared into Core-Safe, where they are explicit. As all the analyses
mentioned in this paper happen at Core-Safe level, later in this section we will
describe it in detail.
The allocation and deallocation of regions is bound to function calls: a work-
ing region is allocated when entering the call and deallocated when exiting it.
Inside the function, data structures may be built but they can also be destroyed
by using a destructive pattern matching denoted by ! or a case! expression,
which deallocates the cell corresponding to the outermost constructor. Using re-
cursion the recursive spine of the whole data structure may be deallocated. We
say that it is condemned. As an example, we show an append function destroying
the first list’s spine, while keeping its elements in order to build the result:
concatD []! ys = ys
concatD (x:xs)! ys = x : concatD xs ys
As a consequence, the concatenation needs constant heap space, while the usual
version needs linear heap space. The fact that the first list is lost is reflected in
the type of the function: concatD :: [a]! -> [a] -> [a].
The data structures which are not part of function’s result are built in the lo-
cal working region, which we call self, and they die when the function terminates.
As an example we show a destructive version of the treesort algorithm:
treesortD :: [Int]! -> [Int]
treesortD xs = inorder (mkTreeD xs)
First, the original list xs is used to build a search tree by applying function
mkTreeD (defined below). This tree is then traversed in inorder to produce the
sorted list. The tree is not part of the result of the function, so it will be built
in the working region and will die when the treesortD function returns (in
Core-Safe where regions are explicit this will be apparent). The original list is
destroyed and the destructive appending function is used in the traversal so that
constant heap space is consumed.
Function mkTreeD inserts each element of the list in the binary search tree.
mkTreeD :: [Int]! -> BSTree Int
mkTreeD []! = Empty
mkTreeD (x:xs)! = insertD x (mkTreeD xs)
The function insertD is the destructive version of insertion in a binary search
tree. Then mkTreeD exactly consumes in the heap the space occupied by the list.
Otherwise, in the worst case the function would consume quadratic heap space.
insertD :: Int -> BSTree Int! -> BSTree Int
insertD x Empty! = Node Empty x Empty
insertD x (Node lt y rt)! | x == y = Node lt! y rt!
| x > y = Node lt! y (insertD x rt)
| x < y = Node (insertD x lt) y rt!
4

prog dec
1
; . . . ; dec
n
; e
dec f x
i
n
@ r
j
l
= e {recursive, polymorphic function}
e a {atom: literal c or variable x}
| x@r {copy}
| x! {reuse}
| f a
i
n
@ r
j
l
{function application}
| let x
1
= be in e {non-recursive, monomorphic}
| case x of alt
i
n
{read-only case}
| case! x of alt
i
n
{destructive case}
alt C x
i
n
e
be C a
i
n
@ r {constructor application}
| e
Fig. 1. Core-Safe language definition
Notice in the first guard, that the cell just destroyed must be built again. When a
data structure is condemned its recursive children may subsequently be destroyed
or they may be reused as part of the result of the function. We denote the latter
with a !, as shown in this function insertD. This is due to safety reasons: a
condemned data structure cannot be returned as the result of a function, as
it potentially may contain dangling pointers. Reusing turns a condemned data
structure into a safe one. The original reference is not accessible any more. The
type system shown in this paper copes with all these features to avoid dangling
pointers. So, in the example lt and rt are condemned and they must be reused
in order to be part of the result.
Data structures may also be copied using @ notation. Only the recursive
spine of the structure is copied, while the elements are shared with the old one.
This is useful when we want non-destructive versions of functions based on the
destructive ones. For example, we can define treesort xs = treesortD (xs@).
In Fig. 1 we show the syntax of Core-Safe. A program prog is a sequence of
possibly recursive polymorphic function definitions followed by a main expression
e, calling them, whose value is the program result. The abbreviation x
i
n
stands
for x
1
· · · x
n
. Destructive pattern matching is desugared into case! expressions.
Constructions are only allowed in let bindings, and atoms are used in function
applications, case/case! discriminant, copy and reuse. Regions are explicit in
constructor application and the copy expression. Function definitions building
a new data structure will have additional parameters r
j
, which are the output
regions, where the resulting data structure is to be constructed. In the right hand
side expression only the r
j
and its own working region, written self , may be used.
Consequently, as we will see later, functional types include region parameter
types.
Polymorphic algebraic data types definitions are defined separately through
data declarations. Algebraic types declarations have additional parameters in-
dicating the regions where the constructed values of that type are allocated. For
example, trees are represented as follows:
data Tree a @ rho = Empty@rho | Node (Tree a@rho) a (Tree a@rho) @ rho
There may be several region parameters when nested types are used: different
components of the data structure may live in different regions. In that case the
5

Citations
More filters
Proceedings ArticleDOI
07 Sep 2017
TL;DR: This work shows how to compile high-level functional array-processing programs, drawn from image processing and machine learning, into C code that runs as fast as hand-written C.
Abstract: We show how to compile high-level functional array-processing programs, drawn from image processing and machine learning, into C code that runs as fast as hand-written C. The key idea is to transform the program to destination-passing style, which in turn enables a highly-efficient stack-like memory allocation discipline.

21 citations


Cites methods from "A type system for safe memory manag..."

  • ...Safe [25, 26] suggests a simpler region inference algorithm by restricting the language to a first-order functional language....

    [...]

Book ChapterDOI
28 Jun 2009
TL;DR: This paper presents an inference algorithm for annotating programs with regions which is both simpler to understand and more efficient than other related algorithms.
Abstract: Safe is a first-order eager language with facilities for programmer controlled destruction and copying of data structures. It provides also regions, i.e. disjoint parts of the heap, where the program allocates data structures. The runtime system does not need a garbage collector and all allocation/deallocation actions are done in constant time. The language is aimed at inferring and certifying upper bounds for memory consumption in a Proof Carrying Code environment. Some of its analyses have been presented elsewhere [7,8]. In this paper we present an inference algorithm for annotating programs with regions which is both simpler to understand and more efficient than other related algorithms. Programmers are assumed to write programs and to declare datatypes without any reference to regions. The algorithm decides the regions needed by every function. It also allows polymorphic recursion with respect to regions. We show convincing examples of programs before and after region annotation, prove the correctness and optimality of the algorithm, and give its asymptotic cost.

20 citations


Cites background from "A type system for safe memory manag..."

  • ...More interesting is the definition of a type system [6, 7] guaranteeing that destruction facilities can be used in a safe way....

    [...]

  • ...The main correctness requirement is that the annotated type of each function can be assigned to the corresponding annotated function in the type system defined in [6]....

    [...]

  • ...Some of its analyses have been presented elsewhere [4, 6, 7]....

    [...]

  • ...This feature and the type system allowing to use it in a safe way have been explained in previous papers [6, 7]....

    [...]

  • ...Intuitively, it means that the correspondences between region type variables and concrete regions of each element of dom(E) do not contradict each other, that is, the results of each build(h,E(x),Γ (x)), where x ∈ dom(E) are well-defined, and also is their union, which we call the witness of this consistency relation (see [6] for a formal definition)....

    [...]

Book ChapterDOI
04 Mar 2009
TL;DR: This paper presents a type inference algorithm, proves its correctness w.r.t. the type system, describes its implementation and gives a number of successfully typed examples.
Abstract: Safe is a first-order eager functional language with destructive pattern matching controlled by the programmer A previously presented type system is used to avoid dangling pointers arising from the inadequate usage of this facility In this paper we present a type inference algorithm, prove its correctness wrt the type system, describe its implementation and give a number of successfully typed examples

15 citations

Dissertation
16 Sep 2010
TL;DR: The main result is the formal soundness proof of the proposed analysis for a functional language, based on the manual amortised complexity analysis, that automatically infers formally guaranteed upper bounds on the use of compositional quantitative resources.
Abstract: Steffen Jost researched a novel static program analysis that automatically infers formally guaranteed upper bounds on the use of compositional quantitative resources The technique is based on the manual amortised complexity analysis Inference is achieved through a type system annotated with linear constraints Any solution to the collected constraints yields the coefficients of a formula, that expresses an upper bound on the resource consumption of a program through the sizes of its various inputs The main result is the formal soundness proof of the proposed analysis for a functional language The strictly evaluated language features higher-order types, full mutual recursion, nested data types, suspension of evaluation, and can deal with aliased data The presentation focuses on heap space bounds Extensions allowing the inference of bounds on stack space usage and worst-case execution time are demonstrated for several realistic program examples These bounds were inferred by the created generic implementation of the technique The implementation is highly efficient, and solves even large examples within seconds

14 citations

Book ChapterDOI
06 Nov 2009
TL;DR: This paper presents a new analysis aimed at inferring upper bounds for heap and stack consumption in Safe, based on abstract interpretation, and explains the abstract domain and some correctness properties of the interpretation rules with respect to the language semantics.
Abstract: Safe is a first-order functional language with an implicit region-based memory system and explicit destruction of heap cells. Its static analysis for inferring regions, and a type system guaranteeing the absence of dangling pointers have been presented elsewhere. In this paper we present a new analysis aimed at inferring upper bounds for heap and stack consumption. It is based on abstract interpretation, being the abstract domain the set of all n-ary monotonic functions from real non-negative numbers to a real non-negative result. This domain turns out to be a complete lattice under the usual ⊆ relation on functions. Our interpretation is monotonic in this domain and the solution we seek is the least fixpoint of the interpretation. We first explain the abstract domain and some correctness properties of the interpretation rules with respect to the language semantics, then present the inference algorithms for recursive functions, and finally illustrate the approach with the upper bounds obtained by our implementation for some case studies.

13 citations

References
More filters
Book
01 Jan 2002
TL;DR: This presentation discusses Functional Programming in HOL, which aims to provide students with an understanding of the programming language through the lens of Haskell.
Abstract: Elementary Techniques.- 1. The Basics.- 2. Functional Programming in HOL.- 3. More Functional Programming.- 4. Presenting Theories.- Logic and Sets.- 5. The Rules of the Game.- 6. Sets, Functions, and Relations.- 7. Inductively Defined Sets.- Advanced Material.- 8. More about Types.- 9. Advanced Simplification, Recursion, and Induction.- 10. Case Study: Verifying a Security Protocol.

2,964 citations


"A type system for safe memory manag..." refers methods in this paper

  • ...Isabelle/HOL....

    [...]

  • ...We are also working in the code generation and certification phases, trying to express the correctness proofs of our analyses as certificates which could be mechanically proof-checked by the proof assistant Isabelle [16]....

    [...]

  • ...We are also working in the code generation and certi.cation phases, trying to express the correctness proofs of our analyses as certi.cates which could be mechanically proof-checked by the proof assistant Isabelle [16]....

    [...]

Proceedings ArticleDOI
01 Jan 1997
TL;DR: It is shown in this paper how proof-carrying code might be used to develop safe assembly-language extensions of ML programs and the adequacy of concrete representations for the safety policy, the safety proofs, and the proof validation is proved.
Abstract: This paper describes proof-carrying code (PCC), a mechanism by which a host system can determine with certainty that it is safe to execute a program supplied (possibly in binary form) by an untrusted source. For this to be possible, the untrusted code producer must supply with the code a safety proof that attests to the code's adherence to a previously defined safety policy. The host can then easily and quickly validate the proof without using cryptography and without consulting any external agents.In order to gain preliminary experience with PCC, we have performed several case studies. We show in this paper how proof-carrying code might be used to develop safe assembly-language extensions of ML programs. In the context of this case study, we present and prove the adequacy of concrete representations for the safety policy, the safety proofs, and the proof validation. Finally, we briefly discuss how we use proof-carrying code to develop network packet filters that are faster than similar filters developed using other techniques and are formally guaranteed to be safe with respect to a given operating system safety policy.

1,799 citations


"A type system for safe memory manag..." refers background in this paper

  • ...The language is targeted to mobile code applications with limited resources in a Proof Carrying Code framework [14, 15]....

    [...]

Journal ArticleDOI
TL;DR: A region-based dynamic semantics for a skeletal programming language extracted from Standard ML is defined and the inference system which specifies where regions can be allocated and de-allocated is presented and a detailed proof that the system is sound with respect to a standard semantics is presented.
Abstract: This paper describes a memory management discipline for programs that perform dynamic memory allocation and de-allocation. At runtime, all values are put intoregions. The store consists of a stack of regions. All points of region allocation and de-allocation are inferred automatically, using a type and effect based program analysis. The scheme does not assume the presence of a garbage collector. The scheme was first presented in 1994 (M. Tofte and J.-P. Talpin,in“Proceedings of the 21st ACM SIGPLAN?SIGACT Symposium on Principles of Programming Languages,” pp. 188?201); subsequently, it has been tested in The ML Kit with Regions, a region-based, garbage-collection free implementation of the Standard ML Core language, which includes recursive datatypes, higher-order functions and updatable references L. Birkedal, M. Tofte, and M. Vejlstrup, (1996),in“Proceedings of the 23 rd ACM SIGPLAN?SIGACT Symposium on Principles of Programming Languages,” pp. 171?183. This paper defines a region-based dynamic semantics for a skeletal programming language extracted from Standard ML. We present the inference system which specifies where regions can be allocated and de-allocated and a detailed proof that the system is sound with respect to a standard semantics. We conclude by giving some advice on how to write programs that run well on a stack of regions, based on practical experience with the ML Kit.

640 citations


Additional excerpts

  • ...Tofte and Talpin [20] introduced in ML-Kit a variant of ML the use of nested regions by means of a letregion construct....

    [...]

  • ...Tofte and Talpin [20] introduced in ML-Kit —a variant of ML— the use of nested regions by means of a letregion construct....

    [...]

  • ...A dif.culty with the original Tofte and Talpin s system is the fact that regions have nested lifetimes....

    [...]

  • ...[20] M. Tofte and J.-P. Talpin....

    [...]

01 Jan 1990
TL;DR: Linear types extend Schmidt's notion of single threading; provide an alternative to Hudak and Bloss' update analysis; and provide a practical complement to Lafont and Holmstrr om's elegant linear languages.

519 citations


"A type system for safe memory manag..." refers background in this paper

  • ...Our safety type system has some characteristics of linear types (see [21] as a basic reference)....

    [...]

Proceedings ArticleDOI
01 May 1998
TL;DR: The design and implementation of a compiler that translates programs written in a type-safe subset of the C programming language into highly optimized DEC Alpha assembly language programs, and a certifier that automatically checks the type safety and memory safety of any assembly language program produced by the compiler are presented.
Abstract: This paper presents the design and implementation of a compiler that translates programs written in a type-safe subset of the C programming language into highly optimized DEC Alpha assembly language programs, and a certifier that automatically checks the type safety and memory safety of any assembly language program produced by the compiler. The result of the certifier is either a formal proof of type safety or a counterexample pointing to a potential violation of the type system by the target program. The ensemble of the compiler and the certifier is called a certifying compiler.Several advantages of certifying compilation over previous approaches can be claimed. The notion of a certifying compiler is significantly easier to employ than a formal compiler verification, in part because it is generally easier to verify the correctness of the result of a computation than to prove the correctness of the computation itself. Also, the approach can be applied even to highly optimizing compilers, as demonstrated by the fact that our compiler generates target code, for a range of realistic C programs, which is competitive with both the cc and gcc compilers with all optimizations enabled. The certifier also drastically improves the effectiveness of compiler testing because, for each test case, it statically signals compilation errors that might otherwise require many executions to detect. Finally, this approach is a practical way to produce the safety proofs for a Proof-Carrying Code system, and thus may be useful in a system for safe mobile code.

397 citations


"A type system for safe memory manag..." refers background in this paper

  • ...The language is targeted to mobile code applications with limited resources in a Proof Carrying Code framework [14, 15]....

    [...]