Precise Null Pointer Analysis Through Global Value Numbering

Total Page:16

File Type:pdf, Size:1020Kb

Precise Null Pointer Analysis Through Global Value Numbering Precise Null Pointer Analysis Through Global Value Numbering Ankush Das1 and Akash Lal2 1 Carnegie Mellon University, Pittsburgh, PA, USA 2 Microsoft Research, Bangalore, India Abstract. Precise analysis of pointer information plays an important role in many static analysis tools. The precision, however, must be bal- anced against the scalability of the analysis. This paper focusses on improving the precision of standard context and flow insensitive alias analysis algorithms at a low scalability cost. In particular, we present a semantics-preserving program transformation that drastically improves the precision of existing analyses when deciding if a pointer can alias Null. Our program transformation is based on Global Value Number- ing, a scheme inspired from compiler optimization literature. It allows even a flow-insensitive analysis to make use of branch conditions such as checking if a pointer is Null and gain precision. We perform experiments on real-world code and show that the transformation improves precision (in terms of the number of dereferences proved safe) from 86.56% to 98.05%, while incurring a small overhead in the running time. Keywords: Alias Analysis, Global Value Numbering, Static Single As- signment, Null Pointer Analysis 1 Introduction Detecting and eliminating null-pointer exceptions is an important step towards developing reliable systems. Static analysis tools that look for null-pointer ex- ceptions typically employ techniques based on alias analysis to detect possible aliasing between pointers. Two pointer-valued variables are said to alias if they hold the same memory location during runtime. Statically, aliasing can be de- cided in two ways: (a) may-alias [1], where two pointers are said to may-alias if they can point to the same memory location under some possible execution, and (b) must-alias [27], where two pointers are said to must-alias if they always point to the same memory location under all possible executions. Because a precise alias analysis is undecidable [24] and even a flow-insensitive pointer analysis is NP-hard [14], much of the research in the area plays on the precision-efficiency trade-off of alias analysis. For example, practical algorithms for may-alias anal- ysis lose precision (but retain soundness) by over-approximating: a verdict that two pointer may-alias does not imply that there is some execution in which they actually hold the same value. Whereas, a verdict that two pointers cannot may-alias must imply that there is no execution in which they hold the same value. We use a sound may-alias analysis in an attempt to prove the safety of a program with respect to null-pointer exceptions. For each pointer dereference, we ask the analysis if the pointer can may-alias Null just before the dereference. If the answer is that it cannot may-alias Null, then the pointer cannot hold a Null value under all possible executions, hence the dereference is safe. The more precise the analysis, the more dereferences it can prove safe. This paper demonstrates a technique that improves the precision of may-alias analysis at a little cost when answering aliasing queries of pointers with the Null value. The Null value is special because programmers tend to be defensive against null-pointer exceptions. If there is doubt that a pointer, say x, can be Null or not, the programmer uses a check \if (x 6= Null)" before dereferencing x. Exist- ing alias analysis techniques, especially flow insensitive techniques for may-alias analysis, ignore all branch conditions. As we demonstrate in this paper, exploit- ing these defensive checks can significantly increase the precision of alias analysis. Our technique is based around a semantics-preserving program transformation and requires only a minor change to the alias analysis algorithm itself. Program transformations have been used previously to improve the precision for alias analysis. For instance, it is common to use a Static Single Assignment (SSA) conversion [5] before running flow-insensitive analyses. The use of SSA automatically adds some level of flow sensitivity to the analysis [12]. SSA, while useful, is still limited in the amount of precision that it adds, and in particular, it does not help with using branch conditions. We present a program transforma- tion based on Global Value Numbering (GVN) [16] that adds significantly more precision on top of SSA by leveraging branch conditions. The transformation works by first inserting an assignment v := e on the then branch of a check if (e 6= Null), where v is a fresh program variable. This gives us the global invariant that v can never hold the Null value. However, this invariant will be of no use unless the program uses v. Our transformation then searches locally, in the same procedure, for program expressions e0 that are equivalent to e, that is, at runtime they both hold the same value. The transformation then replaces e0 with v. The search for equivalent expressions is done by adapting the GVN algorithm (originally designed for compiler optimizations [10]). Our transformation can be followed up with a standard alias analysis to infer the points-to set for each variable, with a slight change that the new vari- ables introduced by our transformation (such as v above) cannot be Null. This change stops spurious propagation of Null and makes the analysis more precise. We perform extensive experiments on real-world code. The results show that the precision of the alias analysis (measured in terms of the number of pointer deref- erences proved safe) goes from 86.56% to 98.05%. This work is used in Microsoft's Static Driver Verifier tool [22] for finding null-pointer bugs in device drivers3. The rest of the paper is organized as follows: Section 2 provides background on flow-insensitive alias analysis and how SSA can improve its precision. Section 3 illustrates our program transformation via an example and Section 4 presents 3 https://msdn.microsoft.com/en-us/library/windows/hardware/mt779102(v= vs.85).aspx var x : int procedure f(var y : int) returns u : int procedure main() f f var z : int var a : int; L1: var b : int; x := y.f; L1: assume (x 6= Null); a := new(); goto L2; b := call f(a); L2: goto L2; z.g := y; L2: assert (x 6= Null); return; u := x; g return; g Fig. 1. An example program in our language it formally. Section 5 presents experimental results, Section 6 describes some of the related work in the area and Section 7 concludes. 2 Background 2.1 Programming Language We introduce a simplistic language to demonstrate the alias analysis and how program transformations can be used to increase its precision. As is standard, we concern ourselves only with statements that manipulate pointers. All other statements are ignored (i.e., abstracted away) by the alias analysis. Our language has assignments with one of the following forms: pointer assignments x := y, dereferencing via field writes x:f := y and reads x := y:f, creating new memory locations x := new(), or assigning Null as x := Null. The language also has assume and assert statements: { assume B checks the Boolean condition B and continues execution only if the condition evaluates to true. The assume statement is a convenient way of modeling branching in most existing source languages. For instance, a branch \if (B)" can be modeled using two basic blocks, one beginning with assume B and the other with assume :B. { assert B checks the Boolean condition B and continues execution if it holds. If B does not hold, then it raises an assertion failure and stops program execution. A program in our language begins with global variable declarations followed by one or more procedures. Each procedure starts with declarations of local variables, followed by a sequence of basic blocks. Each basic block starts with a label, followed by a list of statements, and ends with a control transfer, which is either a goto or a return.A goto in our language can take multiple labels. The choice between which label to jump is non-deterministic. Finally, we disallow loops in the control-flow of a procedure; they can instead be encoded using Statement Constraint Algorithm 1 Algorithm for computing i : x := new() aSi 2 pt(x) points-to sets x := Null aS0 2 pt(x) 1: For each program variable x, let pt(x) = ; 2: repeat x := y pt(y) ⊆ pt(x) 3: opt := pt aSi 2 pt(y) 4: for all program statements st do x := y:f pt(aSi:f) ⊆ pt(x) 5: if st is i : x := new() then 6: pt(x) := pt(x) [ faSig aSi 2 pt(x) 7: if st is x := Null then x:f := y pt(y) ⊆ pt(aSi:f) 8: pt(x) := pt(x) [ faS0g Fig. 2. Program statements and 9: if st is x := y then corresponding points-to set 10: pt(x) := pt(x) [ pt(y) constraints 11: if st is x := y:f then 12: for all aSi 2 pt(y) do 13: pt(x) := pt(x) [ pt(aSi:f) 14: if st is x:f := y then 15: for all aSi 2 pt(x) do 16: pt(aSi:f) := pt(aSi:f) [ pt(y) 17: for all tagged(x) do 18: pt(x) := pt(x) − faS0g 19: until opt = pt procedures with recursion. This restriction simplifies the presentation of our algorithms. Figure 1 shows an illustrative example in our language. 2.2 Alias Analysis This section describes Andersen's may-alias analysis [1]. The analysis is context and flow-insensitive, which means that it completely abstracts away the control of the program. But the analysis is field-sensitive, which means that a value can be obtained by reading a field f only if it was previously written to the same field f.
Recommended publications
  • Enabling RUST for UEFI Firmware
    presented by Enabling RUST for UEFI Firmware UEFI 2020 Virtual Plugfest August 20, 2020 Jiewen Yao & Vincent Zimmer, Intel Corporation www.uefi.org 1 Jiewen Yao • Jiewen Yao is a principal engineer in the Intel Architecture, Graphics, and Software Group. He has been engaged as a firmware developer for over 15 years. He is a member of the UEFI Security sub team, and the TCG PC Client sub working group. www.uefi.org 2 Vincent Zimmer • Vincent Zimmer is a senior principal engineer in the Intel Architecture, Graphics, and Software Group. He has been engaged as a firmware developer for over 25 years and leads the UEFI Security sub team. www.uefi.org 3 Agenda • EDKII Security Summary • RUST Language • Enabling RUST for EDKII • Summary / Call to Action www.uefi.org 4 EDKII Security Summary www.uefi.org 5 BIOS Memory Issue in Hack Conf www.uefi.org 6 BIOS Security Bug Top Issue Open Source Close Source Buffer Overflow/ 50% 38% Integer Overflow SMM 7% 18% Variable 8% 5% Register Lock 3% 10% www.uefi.org 7 Vulnerabilities in C/C++ Source: Trends, challenges, and strategic shifts in the software vulnerability mitigation landscape – Microsoft, Bluehat IL 2019 www.uefi.org 8 Firmware as Software • Many software issues are also firmware issues. – Buffer Overflow – Integer Overflow – Uninitialized Variable • Software mitigation can be used for firmware mitigation. – (See next page) www.uefi.org 9 3 Levels of Prevention Prevention Method EDKII Open Source Example Eliminate Reduce Attack Surface SMI Handler Profile Vulnerability Static Analysis / Dynamic
    [Show full text]
  • Beyond BIOS Developing with the Unified Extensible Firmware Interface
    Digital Edition Digital Editions of selected Intel Press books are in addition to and complement the printed books. Click the icon to access information on other essential books for Developers and IT Professionals Visit our website at www.intel.com/intelpress Beyond BIOS Developing with the Unified Extensible Firmware Interface Second Edition Vincent Zimmer Michael Rothman Suresh Marisetty Copyright © 2010 Intel Corporation. All rights reserved. ISBN 13 978-1-934053-29-4 This publication is designed to provide accurate and authoritative information in regard to the subject matter covered. It is sold with the understanding that the publisher is not engaged in professional services. If professional advice or other expert assistance is required, the services of a competent professional person should be sought. Intel Corporation may have patents or pending patent applications, trademarks, copyrights, or other intellectual property rights that relate to the presented subject matter. The furnishing of documents and other materials and information does not provide any license, express or implied, by estoppel or otherwise, to any such patents, trademarks, copyrights, or other intellectual property rights. Intel may make changes to specifications, product descriptions, and plans at any time, without notice. Fictitious names of companies, products, people, characters, and/or data mentioned herein are not intended to represent any real individual, company, product, or event. Intel products are not intended for use in medical, life saving, life sustaining, critical control or safety systems, or in nuclear facility applications. Intel, the Intel logo, Celeron, Intel Centrino, Intel NetBurst, Intel Xeon, Itanium, Pentium, MMX, and VTune are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries.
    [Show full text]
  • Efficient Run Time Optimization with Static Single Assignment
    i Jason W. Kim and Terrance E. Boult EECS Dept. Lehigh University Room 304 Packard Lab. 19 Memorial Dr. W. Bethlehem, PA. 18015 USA ¢ jwk2 ¡ tboult @eecs.lehigh.edu Abstract We introduce a novel optimization engine for META4, a new object oriented language currently under development. It uses Static Single Assignment (henceforth SSA) form coupled with certain reasonable, albeit very uncommon language features not usually found in existing systems. This reduces the code footprint and increased the optimizer’s “reuse” factor. This engine performs the following optimizations; Dead Code Elimination (DCE), Common Subexpression Elimination (CSE) and Constant Propagation (CP) at both runtime and compile time with linear complexity time requirement. CP is essentially free, whether the values are really source-code constants or specific values generated at runtime. CP runs along side with the other optimization passes, thus allowing the efficient runtime specialization of the code during any point of the program’s lifetime. 1. Introduction A recurring theme in this work is that powerful expensive analysis and optimization facilities are not necessary for generating good code. Rather, by using information ignored by previous work, we have built a facility that produces good code with simple linear time algorithms. This report will focus on the optimization parts of the system. More detailed reports on META4?; ? as well as the compiler are under development. Section 0.2 will introduce the scope of the optimization algorithms presented in this work. Section 1. will dicuss some of the important definitions and concepts related to the META4 programming language and the optimizer used by the algorithms presented herein.
    [Show full text]
  • CS153: Compilers Lecture 19: Optimization
    CS153: Compilers Lecture 19: Optimization Stephen Chong https://www.seas.harvard.edu/courses/cs153 Contains content from lecture notes by Steve Zdancewic and Greg Morrisett Announcements •HW5: Oat v.2 out •Due in 2 weeks •HW6 will be released next week •Implementing optimizations! (and more) Stephen Chong, Harvard University 2 Today •Optimizations •Safety •Constant folding •Algebraic simplification • Strength reduction •Constant propagation •Copy propagation •Dead code elimination •Inlining and specialization • Recursive function inlining •Tail call elimination •Common subexpression elimination Stephen Chong, Harvard University 3 Optimizations •The code generated by our OAT compiler so far is pretty inefficient. •Lots of redundant moves. •Lots of unnecessary arithmetic instructions. •Consider this OAT program: int foo(int w) { var x = 3 + 5; var y = x * w; var z = y - 0; return z * 4; } Stephen Chong, Harvard University 4 Unoptimized vs. Optimized Output .globl _foo _foo: •Hand optimized code: pushl %ebp movl %esp, %ebp _foo: subl $64, %esp shlq $5, %rdi __fresh2: movq %rdi, %rax leal -64(%ebp), %eax ret movl %eax, -48(%ebp) movl 8(%ebp), %eax •Function foo may be movl %eax, %ecx movl -48(%ebp), %eax inlined by the compiler, movl %ecx, (%eax) movl $3, %eax so it can be implemented movl %eax, -44(%ebp) movl $5, %eax by just one instruction! movl %eax, %ecx addl %ecx, -44(%ebp) leal -60(%ebp), %eax movl %eax, -40(%ebp) movl -44(%ebp), %eax Stephen Chong,movl Harvard %eax,University %ecx 5 Why do we need optimizations? •To help programmers… •They write modular, clean, high-level programs •Compiler generates efficient, high-performance assembly •Programmers don’t write optimal code •High-level languages make avoiding redundant computation inconvenient or impossible •e.g.
    [Show full text]
  • A Formally-Verified Alias Analysis
    A Formally-Verified Alias Analysis Valentin Robert1;2 and Xavier Leroy1 1 INRIA Paris-Rocquencourt 2 University of California, San Diego [email protected], [email protected] Abstract. This paper reports on the formalization and proof of sound- ness, using the Coq proof assistant, of an alias analysis: a static analysis that approximates the flow of pointer values. The alias analysis con- sidered is of the points-to kind and is intraprocedural, flow-sensitive, field-sensitive, and untyped. Its soundness proof follows the general style of abstract interpretation. The analysis is designed to fit in the Comp- Cert C verified compiler, supporting future aggressive optimizations over memory accesses. 1 Introduction Alias analysis. Most imperative programming languages feature pointers, or object references, as first-class values. With pointers and object references comes the possibility of aliasing: two syntactically-distinct program variables, or two semantically-distinct object fields can contain identical pointers referencing the same shared piece of data. The possibility of aliasing increases the expressiveness of the language, en- abling programmers to implement mutable data structures with sharing; how- ever, it also complicates tremendously formal reasoning about programs, as well as optimizing compilation. In this paper, we focus on optimizing compilation in the presence of pointers and aliasing. Consider, for example, the following C program fragment: ... *p = 1; *q = 2; x = *p + 3; ... Performance would be increased if the compiler propagates the constant 1 stored in p to its use in *p + 3, obtaining ... *p = 1; *q = 2; x = 4; ... This optimization, however, is unsound if p and q can alias.
    [Show full text]
  • Value Numbering
    SOFTWARE—PRACTICE AND EXPERIENCE, VOL. 0(0), 1–18 (MONTH 1900) Value Numbering PRESTON BRIGGS Tera Computer Company, 2815 Eastlake Avenue East, Seattle, WA 98102 AND KEITH D. COOPER L. TAYLOR SIMPSON Rice University, 6100 Main Street, Mail Stop 41, Houston, TX 77005 SUMMARY Value numbering is a compiler-based program analysis method that allows redundant computations to be removed. This paper compares hash-based approaches derived from the classic local algorithm1 with partitioning approaches based on the work of Alpern, Wegman, and Zadeck2. Historically, the hash-based algorithm has been applied to single basic blocks or extended basic blocks. We have improved the technique to operate over the routine’s dominator tree. The partitioning approach partitions the values in the routine into congruence classes and removes computations when one congruent value dominates another. We have extended this technique to remove computations that define a value in the set of available expressions (AVA IL )3. Also, we are able to apply a version of Morel and Renvoise’s partial redundancy elimination4 to remove even more redundancies. The paper presents a series of hash-based algorithms and a series of refinements to the partitioning technique. Within each series, it can be proved that each method discovers at least as many redundancies as its predecessors. Unfortunately, no such relationship exists between the hash-based and global techniques. On some programs, the hash-based techniques eliminate more redundancies than the partitioning techniques, while on others, partitioning wins. We experimentally compare the improvements made by these techniques when applied to real programs. These results will be useful for commercial compiler writers who wish to assess the potential impact of each technique before implementation.
    [Show full text]
  • Practical C/C++ Programming Part II
    Practical C/C++ programming Part II Wei Feinstein HPC User Services Louisiana State University 7/11/18 Practical C/C++ programming II 1 Topics • Pointers in C • Use in functions • Use in arrays • Use in dynamic memory allocation • Introduction to C++ • Changes from C to C++ • C++ classes and objects • Polymorphism • Templates • Inheritance • Introduction to Standard Template Library (STL) 7/11/18 Practical C/C++ programming II 2 What is a pointer? • A pointer is essentially a variable whose value is the address of another variable. • Pointer “points” to a specific part of the memory. • Important concept in C programming language. Not recommended in C++, yet understanding of pointer is necessary in Object Oriented Programming • How to define pointers? int *i_ptr; /* pointer to an integer */ double *d_ptr; /* pointer to a double */ float *f_ptr; /* pointer to a float */ char *ch_ptr; /* pointer to a character */ int **p_ptr; /* pointer to an integer pointer */ 7/11/18 Practical C/C++ programming II 3 Pointer Operations (a) Define a pointer variable. (b) Assign the address of a variable to a pointer. & /* "address of" operator */ (c) Access the value pointed by the pointer by dereferencing * /* “dereferencing" operator */ Examples: int a = 6; int *ptr; ptr = &a; /* pointer p point to a */ *ptr = 10; /* dereference pointer p reassign a value*/ var_name var_address var_value ptr 0x22aac0 0xXXXX a 0xXXXX 6 7/11/18 Practical C/C++ programming II 4 Pointer Example int b = 17; int *p; /* initialize pointer p */ p = &b; /*pointed addr and value,
    [Show full text]
  • Coverity Static Analysis
    Coverity Static Analysis Quickly find and fix Overview critical security and Coverity® gives you the speed, ease of use, accuracy, industry standards compliance, and quality issues as you scalability that you need to develop high-quality, secure applications. Coverity identifies code critical software quality defects and security vulnerabilities in code as it’s written, early in the development process when it’s least costly and easiest to fix. Precise actionable remediation advice and context-specific eLearning help your developers understand how to fix their prioritized issues quickly, without having to become security experts. Coverity Benefits seamlessly integrates automated security testing into your CI/CD pipelines and supports your existing development tools and workflows. Choose where and how to do your • Get improved visibility into development: on-premises or in the cloud with the Polaris Software Integrity Platform™ security risk. Cross-product (SaaS), a highly scalable, cloud-based application security platform. Coverity supports 22 reporting provides a holistic, more languages and over 70 frameworks and templates. complete view of a project’s risk using best-in-class AppSec tools. Coverity includes Rapid Scan, a fast, lightweight static analysis engine optimized • Deployment flexibility. You for cloud-native applications and Infrastructure-as-Code (IaC). Rapid Scan runs decide which set of projects to do automatically, without additional configuration, with every Coverity scan and can also AppSec testing for: on-premises be run as part of full CI builds with conventional scan completion times. Rapid Scan can or in the cloud. also be deployed as a standalone scan engine in Code Sight™ or via the command line • Shift security testing left.
    [Show full text]
  • Aliases, Intro. to Optimization
    Aliasing Two variables are aliased if they can refer to the same storage location. Possible Sources:pointers, parameter passing, storage overlap... Ex. address of a passed x and y are aliased! Pointer Analysis, Alias Analysis to get less conservative info Needed for correct, aggressive optimization Procedures: terminology a, e global b,c formal arguments d local call site with actual arguments At procedure call, formals bound to actuals, may be aliased Ex. (b,a) , (c, d) Globals, actuals may be modified, used Ex. a, b Call Graphs Determines possible flow of control, interprocedurally G = (N, LE, s) N set of nodes LE set of labelled edges n m s start node Qu: Why need call site labels? Why list? Example Call Graph 1,2 3 4 5 6 7 Interprocedural Dataflow Analysis Based on call graph: forward, backward Gen, Kill: Need to summarize procedures per call Flow sensitive: take procedure's control flow into account Flow insensitive: ignore procedure's control flow Difficulties: Hard, complex Flow sensitive alias analysis intractable Separate compilation? Scale compiler can do both flow sensitive and insensitive Most compilers ultraconservative, or flow insensitive Scalar Replacement of Aggregates Use scalar temporary instead of aggregate variable Compiler may limit optimization to such scalars Can do better register allocation, constant propagation,... Particulary useful when small number of constant values Can use constant propagation, dead code elimination to specialize code Value Numbering of Basic Blocks Eliminates computations whose values are already computed in BB value needn't be constant Method: Value Number Hash Table Global Copy Propagation Given A:=B, replace later uses of A by B, as long as A,B not redefined (with dead code elim) Global Copy Propagation Ex.
    [Show full text]
  • Declare Property Class Accept Null C
    Declare Property Class Accept Null C Woesome and nontechnical Joshuah planned inveterately and pull-outs his frontiers sourly and daftly. Unquiet Bernard fly-by very instructively while Rick remains ectotrophic and chastened. Sometimes stereoscopic Addie unnaturalizes her acorns proportionally, but unlidded Cat invert heinously or orientalizes rancorously. Even experts are accepted types and positional parameters and references, and assigns to. Use HasValue property to check has value is assigned to nullable type sometimes not Static Nullable class is a. Thank you declare more freely, declare property class accept null c is useful to provide only one dispiriting aspect of. Here we're defining a suggest that extracts all non-nullable property keys from plant type. By disabling cookies to accept all? The car variable inside counter Person class shouldn't be declared type grass and. Use JSDoc type. Any class property name, null safe code token stream of properties and corresponds to accept a class! Why death concept of properties came into C The decline because not two reasons If the members of a class are private then select another class in C. JavaScript Properties of variables with null or undefined. Type cup type as should pickle the null value variable the pastry of the variable to which null. CS31 Intro to C Structs and Pointers. Using the New Null Conditional Operator in C 6 InformIT. Your extra bet is to get themselves the good group of initializing all variables when you disabled them. This class that null values can declare variables declared inside an exception handling is nullable context switches a varargs in.
    [Show full text]
  • Global Value Numbering Using Random Interpretation
    Global Value Numbering using Random Interpretation Sumit Gulwani George C. Necula [email protected] [email protected] Department of Electrical Engineering and Computer Science University of California, Berkeley Berkeley, CA 94720-1776 Abstract General Terms We present a polynomial time randomized algorithm for global Algorithms, Theory, Verification value numbering. Our algorithm is complete when conditionals are treated as non-deterministic and all operators are treated as uninter- Keywords preted functions. We are not aware of any complete polynomial- time deterministic algorithm for the same problem. The algorithm Global Value Numbering, Herbrand Equivalences, Random Inter- does not require symbolic manipulations and hence is simpler to pretation, Randomized Algorithm, Uninterpreted Functions implement than the deterministic symbolic algorithms. The price for these benefits is that there is a probability that the algorithm can report a false equality. We prove that this probability can be made 1 Introduction arbitrarily small by controlling various parameters of the algorithm. Detecting equivalence of expressions in a program is a prerequi- Our algorithm is based on the idea of random interpretation, which site for many important optimizations like constant and copy prop- relies on executing a program on a number of random inputs and agation [18], common sub-expression elimination, invariant code discovering relationships from the computed values. The computa- motion [3, 13], induction variable elimination, branch elimination, tions are done by giving random linear interpretations to the opera- branch fusion, and loop jamming [10]. It is also important for dis- tors in the program. Both branches of a conditional are executed. At covering equivalent computations in different programs, for exam- join points, the program states are combined using a random affine ple, plagiarism detection and translation validation [12, 11], where combination.
    [Show full text]
  • Automated Techniques for Creation and Maintenance of Typescript Declaration Files
    Automated Techniques for Creation and Maintenance of TypeScript Declaration Files Erik Krogh Kristensen PhD Dissertation Department of Computer Science Aarhus University Denmark Automated Techniques for Creation and Maintenance of TypeScript Declaration Files A Dissertation Presented to the Faculty of Science and Technology of Aarhus University in Partial Fulfillment of the Requirements for the PhD Degree by Erik Krogh Kristensen August 8, 2019 Abstract JavaScript was initially a scripting language for creating small interactive web pages. However, massive applications, both web pages and server ap- plications, are increasingly being developed using JavaScript. The dynamic nature of the JavaScript language makes it hard to create proper tooling with features such as auto-completion and code-navigation. TypeScript is a JavaScript superset that adds, on top of JavaScript, an optional static type system, which facilitates features such as auto-completion, code navigation, and detection of type errors. However, many TypeScript applications still use untyped libraries written in JavaScript. Developers or users of these JavaScript libraries can choose to write TypeScript declaration files, which provide API models of the libraries and are used to type-check TypeScript applications. These declaration files are, however, written manually and of- ten not by the original authors of the library, which leads to mistakes that can misguide TypeScript application developers and ultimately cause bugs. The goal of this thesis is to design automated techniques for assisting in the development of TypeScript declaration files. This thesis identifies several challenges faced by developers of TypeScript declaration files and tackles these challenges using techniques from programming language re- search. Type inference is used to create new, and update existing, decla- ration files.
    [Show full text]