886 research outputs found
Modular Construction of Shape-Numeric Analyzers
The aim of static analysis is to infer invariants about programs that are
precise enough to establish semantic properties, such as the absence of
run-time errors. Broadly speaking, there are two major branches of static
analysis for imperative programs. Pointer and shape analyses focus on inferring
properties of pointers, dynamically-allocated memory, and recursive data
structures, while numeric analyses seek to derive invariants on numeric values.
Although simultaneous inference of shape-numeric invariants is often needed,
this case is especially challenging and is not particularly well explored.
Notably, simultaneous shape-numeric inference raises complex issues in the
design of the static analyzer itself.
In this paper, we study the construction of such shape-numeric, static
analyzers. We set up an abstract interpretation framework that allows us to
reason about simultaneous shape-numeric properties by combining shape and
numeric abstractions into a modular, expressive abstract domain. Such a modular
structure is highly desirable to make its formalization and implementation
easier to do and get correct. To achieve this, we choose a concrete semantics
that can be abstracted step-by-step, while preserving a high level of
expressiveness. The structure of abstract operations (i.e., transfer, join, and
comparison) follows the structure of this semantics. The advantage of this
construction is to divide the analyzer in modules and functors that implement
abstractions of distinct features.Comment: In Proceedings Festschrift for Dave Schmidt, arXiv:1309.455
Combining Forward and Backward Abstract Interpretation of Horn Clauses
Alternation of forward and backward analyses is a standard technique in
abstract interpretation of programs, which is in particular useful when we wish
to prove unreachability of some undesired program states. The current
state-of-the-art technique for combining forward (bottom-up, in logic
programming terms) and backward (top-down) abstract interpretation of Horn
clauses is query-answer transformation. It transforms a system of Horn clauses,
such that standard forward analysis can propagate constraints both forward, and
backward from a goal. Query-answer transformation is effective, but has issues
that we wish to address. For that, we introduce a new backward collecting
semantics, which is suitable for alternating forward and backward abstract
interpretation of Horn clauses. We show how the alternation can be used to
prove unreachability of the goal and how every subsequent run of an analysis
yields a refined model of the system. Experimentally, we observe that combining
forward and backward analyses is important for analysing systems that encode
questions about reachability in C programs. In particular, the combination that
follows our new semantics improves the precision of our own abstract
interpreter, including when compared to a forward analysis of a
query-answer-transformed system.Comment: Francesco Ranzato. 24th International Static Analysis Symposium
(SAS), Aug 2017, New York City, United States. Springer, Static Analysi
On Verifying Complex Properties using Symbolic Shape Analysis
One of the main challenges in the verification of software systems is the
analysis of unbounded data structures with dynamic memory allocation, such as
linked data structures and arrays. We describe Bohne, a new analysis for
verifying data structures. Bohne verifies data structure operations and shows
that 1) the operations preserve data structure invariants and 2) the operations
satisfy their specifications expressed in terms of changes to the set of
objects stored in the data structure. During the analysis, Bohne infers loop
invariants in the form of disjunctions of universally quantified Boolean
combinations of formulas. To synthesize loop invariants of this form, Bohne
uses a combination of decision procedures for Monadic Second-Order Logic over
trees, SMT-LIB decision procedures (currently CVC Lite), and an automated
reasoner within the Isabelle interactive theorem prover. This architecture
shows that synthesized loop invariants can serve as a useful communication
mechanism between different decision procedures. Using Bohne, we have verified
operations on data structures such as linked lists with iterators and back
pointers, trees with and without parent pointers, two-level skip lists, array
data structures, and sorted lists. We have deployed Bohne in the Hob and Jahob
data structure analysis systems, enabling us to combine Bohne with analyses of
data structure clients and apply it in the context of larger programs. This
report describes the Bohne algorithm as well as techniques that Bohne uses to
reduce the ammount of annotations and the running time of the analysis
A Static Analyzer for Large Safety-Critical Software
We show that abstract interpretation-based static program analysis can be
made efficient and precise enough to formally verify a class of properties for
a family of large programs with few or no false alarms. This is achieved by
refinement of a general purpose static analyzer and later adaptation to
particular programs of the family by the end-user through parametrization. This
is applied to the proof of soundness of data manipulation operations at the
machine level for periodic synchronous safety critical embedded software. The
main novelties are the design principle of static analyzers by refinement and
adaptation through parametrization, the symbolic manipulation of expressions to
improve the precision of abstract transfer functions, the octagon, ellipsoid,
and decision tree abstract domains, all with sound handling of rounding errors
in floating point computations, widening strategies (with thresholds, delayed)
and the automatic determination of the parameters (parametrized packing)
A simple abstraction of arrays and maps by program translation
We present an approach for the static analysis of programs handling arrays,
with a Galois connection between the semantics of the array program and
semantics of purely scalar operations. The simplest way to implement it is by
automatic, syntactic transformation of the array program into a scalar program
followed analysis of the scalar program with any static analysis technique
(abstract interpretation, acceleration, predicate abstraction,.. .). The
scalars invariants thus obtained are translated back onto the original program
as universally quantified array invariants. We illustrate our approach on a
variety of examples, leading to the " Dutch flag " algorithm
Program Analysis in A Combined Abstract Domain
Automated verification of heap-manipulating programs is a challenging task due to the complexity of aliasing and mutability of data structures used in these programs. The properties of a number of important data structures do not only relate to one domain, but to combined multiple domains, such as sorted list, priority queues, height-balanced trees and so on. The safety and sometimes efficiency of programs do rely on the properties of those data structures. This
thesis focuses on developing a verification system for both functional correctness and memory safety of such programs which involve heap-based data structures.
Two automated inference mechanisms are presented for heap-manipulating programs in this thesis. Firstly, an abstract interpretation based approach is proposed to synthesise program invariants in a combined pure and shape domain. Newly designed abstraction, join and widening
operators have been defined for the combined domain. Furthermore, a compositional analysis approach is described to discover both pre-/post-conditions of programs with a bi-abduction technique in the combined domain.
As results of my thesis, both inference approaches have been
implemented and the obtained results validate the feasibility and precision of proposed approaches. The outcomes of the thesis confirm that it is possible and practical to analyse heap-manipulating programs automatically and precisely by using abstract interpretation
in a sophisticated combined domain
Non-polynomial Worst-Case Analysis of Recursive Programs
We study the problem of developing efficient approaches for proving
worst-case bounds of non-deterministic recursive programs. Ranking functions
are sound and complete for proving termination and worst-case bounds of
nonrecursive programs. First, we apply ranking functions to recursion,
resulting in measure functions. We show that measure functions provide a sound
and complete approach to prove worst-case bounds of non-deterministic recursive
programs. Our second contribution is the synthesis of measure functions in
nonpolynomial forms. We show that non-polynomial measure functions with
logarithm and exponentiation can be synthesized through abstraction of
logarithmic or exponentiation terms, Farkas' Lemma, and Handelman's Theorem
using linear programming. While previous methods obtain worst-case polynomial
bounds, our approach can synthesize bounds of the form
as well as where is not an integer. We present
experimental results to demonstrate that our approach can obtain efficiently
worst-case bounds of classical recursive algorithms such as (i) Merge-Sort, the
divide-and-conquer algorithm for the Closest-Pair problem, where we obtain
worst-case bound, and (ii) Karatsuba's algorithm for
polynomial multiplication and Strassen's algorithm for matrix multiplication,
where we obtain bound such that is not an integer and
close to the best-known bounds for the respective algorithms.Comment: 54 Pages, Full Version to CAV 201
A Simple and Scalable Static Analysis for Bound Analysis and Amortized Complexity Analysis
We present the first scalable bound analysis that achieves amortized
complexity analysis. In contrast to earlier work, our bound analysis is not
based on general purpose reasoners such as abstract interpreters, software
model checkers or computer algebra tools. Rather, we derive bounds directly
from abstract program models, which we obtain from programs by comparatively
simple invariant generation and symbolic execution techniques. As a result, we
obtain an analysis that is more predictable and more scalable than earlier
approaches. Our experiments demonstrate that our analysis is fast and at the
same time able to compute bounds for challenging loops in a large real-world
benchmark. Technically, our approach is based on lossy vector addition systems
(VASS). Our bound analysis first computes a lexicographic ranking function that
proves the termination of a VASS, and then derives a bound from this ranking
function. Our methodology achieves amortized analysis based on a new insight
how lexicographic ranking functions can be used for bound analysis
- …