littletree logo

Static Analysis of Ada Programs

Daniel H. Ehrenfried
Little Tree Consulting

Abstract

The upcoming standardization of the Ada Semantic Interface Specification (ASIS) makes possible the development of portable static analysis tools for Ada programs. This paper introduces this class of back-end CASE tools, lists their capabilities, and describes how they can be used during the software-development process to increase overall software quality. The description is based on one such tool: the Ada Analyzer developed by Little Tree Consulting.

Keywords: Ada, program analysis, quality, ASIS

The Promise of Stoneman

Along with the Steelman requirements for a new programming language, completed in 1978 and eventually named Ada, came a parallel set of requirements for software-development tools-Stoneman. Stoneman defined requirements for an Ada Programming Support Environment (APSE) that would complement and enhance the language's ability to support modern software-engineering practice. At the core of this environment concept were two key goals:

The inevitable march of UNIX has made the first goal both implausible as originally defined, yet ironically within reach today. But the real grail of Stoneman was to define information-exchange semantics so that tools could not only coexist through inward interaction with a common OS but also reach horizontally into the information generated by other tools along the circumference. In the following diagram, the inward-pointing arrows represent interaction with a common OS, and the curved arrows represent interchange of information between tools.

Common OS Services

There have been a few attempts to implement the Stoneman requirementsãfor example, the Portable Common Tool Environment (PCTE)-Ada in Europe and the Common APSE Interface Set (CAIS) in the United States. PCTE has had some success with the first goal, but both efforts unfortunately failed to provide any significant support for the sharing of information between tools. Individual vendors have naturally integrated their compiler with their own editor and debugger, but rarely has this interoperability extended outside the vendor's in-house toolset.

Ada Semantic Interface Specification

With the recent move toward standardization of the Ada Semantic Interface Specification (ASIS), a part of the information-sharing goal of Stoneman is closer to reality. ASIS provides a read-only programmatic interface to the structural and semantic information generated by the compiler and stored in the Ada library. One of the main goals of ASIS is to provide access to this information through an interface that is at the same semantic level as the definition of Ada itself. This interface offers clients the same terminology and definitions that are found in the Reference Manual for the Ada Programming Language (LRM). For example, if one has a procedure declaration element, one can ask for the identifier element of that declaration and/or a list of parameter specifications. Parameter specification can be further decomposed into identifier lists, mode, type mark, and initial value (if any). Semantic traversals to the corresponding body declaration are also possible. An interface at this level makes ASIS much easier to understand and thus much more likely to be used. Although DIANA and other intermediate Ada representations define more formal and perhaps complete semantics, experience has shown that they are far too detailed and cumbersome for the expression of back-end CASE tools. Compiler implementations may demand a DIANA-like representation for the rigors of semantic analysis and code generation, but back-end CASE tools do not. In addition, because ASIS is at a higher level than most intermediate representations, all vendors will probably be able to implement ASIS directly on top of their particular internal representation.

Static Analysis Tools

One domain that is ripe to take advantage of this emerging technology is that of static analysis tools. Static software analyzers traverse the ASIS representation of Ada programs and extract condensed information that can greatly assist in the software-development process. Analysis can be used to scan voluminous software programs and collect information that both catalogs and characterizes the content of that Ada program. Static analysis can also identify places in the software where quality is suspect and where improvements could be made. This section enumerates the categories of information that can be collected by static analysis tools and provides detailed examples for each category.

Design and Program Structure

The high-level structure of a program is often difficult to see when looking through each individual package of an Ada program. The static and dynamic dependencies between components of a program form a key part of a program's design. The following static analysis capabilities offer insight into the design structure of an Ada program:

Code Correctness

Code correctness clearly is one of the most important goals in programming. Even with the best development practice, it is all but impossible to avoid programming mistakes entirely. Although it is equally impossible to judge with certainty that a program construct is incorrect, constructs with a high likelihood for error can be identified for further inspection by the analyst. The following program characteristics can be used to find potential problems with code correctness:

Code Efficiency

Software efficiency is most negatively affected by the selection of inappropriate implementation algorithms. Such problems are identified most effectively through code reviews and are difficult to detect statically with tools. It is possible, however, to identify constructs that either generate large amounts of code or execute more slowly. It is also possible to locate redundancy in software as well as places where compiler directives such as pragma Inline or pragma Pack would positively or negatively affect software efficiency. The following information impacting program efficiency can be statically collected:

Conformance to Programming Standards and Readability

Almost every project has a set of programming guidelines. Sometimes these criteria are a fairly strict set of rules that must not be violated without explanation. Other rules are simply warnings. Static tools can be used to locate nonconformance to standards in the following categories:

Portability and Compatibility

Software developed on host development environments is often cross-compiled for another target. Developing software that is compatible with the target-dependent features of the cross-compiler can be checked, in part, with static analysis tools. More stringent portability requirements can also be checked with the following information:

Software Content

Tools in this category can be used to support any of the above analysis objectives or to generate status information for internal use or delivery to the customer:

Use of Analysis Tools

Several analysis methods are supported by static analysis tools. Online analysis is usually interactive, with users scanning tool reports and traversing to the actual code when more information or context is required. Code reviews are an extremely effective method for improving code quality and consistency, especially when supported by information generated by static analysis. A more formal quality-validation process is supported by tools that report coding-standard violations, target-compatibility problems, and/or potential programming errors. Hard-copy forms of the output can be used as general reference information for developers and project managers or delivered to the customer. This section describes each of these methods in more detail.

Online Analysis

The utility of static analysis information can be greatly enhanced when generated in hypertext form. The Ada Analyzer generates all reports in hypertext form to minimize the time required to perform analysis and affect quality improvements. Hypertext tables can be used to display condensed forms of information, with each row of the table containing a separate instance of an Ada construct that matches the analysis criteria. Table columns contain attributes of each construct and help to characterize details or provide the context in which each construct appears. In hypertext output forms, some columns are connected back to the construct or attribute in the software under analysis. In this way, tables can be scanned for a quick overview, with traversal used to gather more information when necessary. If a change is necessary, it can be made immediately in code, since traversal arrives at the exact point in the code where the construct was located.

Hypertable Report

Support for Code Reviews

Code reviews should be an essential part of any large-scale software-development process. In some studies, extensive use of peer review uncovered more programming defects than testing and debugging combined. Code reviews, when used at selective points in the development process, can provide a large return on the time invested. Early code reviews can ensure that a consistent design and structure is used throughout the program. This can reduce implementation costs and avoid the need to restructure in later development phases. Code reviews held after the code is implemented can find programming errors, ensure a consistent use of the Ada language and the application's meta-language interfaces, and improve the execution efficiency of the code.

One problem is that code reviews require a large time investment by a large number of project members. Information generated by static analysis tools can make the process of preparation for code review less expensive in several ways. Online analysis can be used by reviewers before the review meeting to prepare their comments. Reviewers usually have not written the code that they are reviewing and thus are likely to be unfamiliar with its detail before the review. Structural analysis can thus be used to locate key constructs and increase the reviewers' overall understanding of the code and its design.

Complexity analysis can be used to reduce the time required to find potential problems or areas in the code that deserve more attention. Information related to code correctness, portability, and readability can be used to identify additional areas for improvement. If general structural problems or inconsistencies are found through visual inspection, the analysis tools can assist in finding all occurrences of this pattern within the code.

As an example, the following report displays all exception declarations, handlers, and raise statements in a single hypertable. Exceptions often play a central role in a program's error-handling concept and thus are an important part of the structural analysis of a program. In this report, the first two columns contain the name of the exception and kind of use. The third column specifies whether the exception appears in a visible specification. The fourth and fifth columns specify the location of each construct. The table columns are sorted to highlight the handlers and raise statements that exist for each exception declaration. Declarations without handlers and/or raise statements might indicate a potential problem. Use of predefined exceptions or anonymous raises also may be of interest to code reviewers.

Exceptions:

Exception This Usage Visible? Unit Library
>>ANON<< raise Msg_Manager'B Communication
Bad_Input declaration Yes Input_Parser'S User_Interface
Bad_Input handler Keyboard_Mgr'B User_Interface
Bad_Input raise Input_Parser'B User_Interface
Constraint_Error raise Input_Parser'B User_Interface
Id_Not_Found declaration Yes Msg_Storage'S Database
Id_Not_Found raise Msg_Storage'B Database
Rxit_Search declaration No Msg_Storage'B Communication
Exit_Search handler Msg_Storage'B Communication
Numeric_Error raise Data_Storage'B System_State

Static analysis tools can also help with the correction and verification process. If items to be corrected are located in hypertext, the developer can use the built-in traversal to quickly locate the areas of the code requiring correction. Some part of the verification process can also be performed by reexecuting the analysis tools to rapidly verify that corrected problems are no longer present.

Validation of Coding Standards

Most software-development projects have a set of coding standards for developers to follow. These standards generally consist of a set of prohibited language constructs or specifications for the form in which a construct can be used. These standards may be motivated by any combination of style, consistency, or efficiency considerations. Use of host-based development of software for embedded targets may also involve compatibility issues between the two compilation systems used in that process.

The difficulty with such standards is that they often contain a long, complicated list of restrictions that are difficult to remember and follow during day-to-day development. This form of analysis attempts to verify that software does not contain any standards violations or compatibility errors. The existence of table entries implies that the code under analysis has violated one of these standards. Using the traversal built into hypertext output, the user can move to each reported violation and make the necessary changes to correct the problem.

Generation of Project Information

Information about Ada units and their interdependencies is one example of information that can be useful to all project members. Location of all key programming constructs and data-dictionary information is another. Cross-referenced lists of declarations and their dependencies constitute a third example. This information can be distributed internally to project members or be used to augment the documentation delivered to the customer.

Integration with the Development Process

Static analysis tools can be used throughout the development lifecycle by a variety of project personnel, each having different analysis objectives. This section describes the ways in which project members can use static analysis in various software lifecycle phases.

Actual Usage Experience

It is important to note that the capabilities defined in this paper are not just ideas about what could be done. The Ada Analyzer currently hosted on the Rational Environment exists today and supports all of the analysis options described in this paper. Initial experience with the use of these tools has been very positive. The following examples highlight this experience:

New opportunities for additional static analysis capabilities appear as each new project uses the Ada Analyzer. As clients become familiar with the concept of seeing condensed reports on the content of their software programs, they quickly begin to imagine other kinds of information that would be even more insightful. The Ada Analyzer and other static analysis tools like it are just beginning to discover the impact that this kind of analysis can have on software quality and software-engineering methods.

References

Ada Semantic Interface Specification, Version 1.1, maintained by ASISWG, Thomas E. Shields, chairman, Telnet address asis-info@Stars.Reston.Unisys.COM for information.

Department of Defense Requirements for an Ada Programming Support Environment, "Stoneman," Defense Advanced Research Project Agency, Arlington, Virginia, February 1980.

Goos, G., W. A. Wulf, A. Evans, and K. Butler, DIANA: An Intermediate Language for Ada, LNCS #161, Springer-Verlag, New York, 1983.

Munck, R., P. Oberndorf, E. Pledoereder, and R. Thall, "An Overview of DOD-STD-1838A (proposed): The Common APSE Interface Set," SIGPLAN Notices, 24, 2, February 1989, pp. 235‚247.

Pierce, R., "ECLIPSEãAn APSE Based on PCTE," Proceedings of the Ada-Europe Conference, Stockholm, May 26-28, 1987, S. Tafvelin (ed.), Cambridge University Press, pp. 32‚45.

Reference Manual for the Ada Programming Language, ANSI/MIL-STD-1815, ISO 8652-1987.

Software Productivity Consortium, "Ada Quality and Style: A Guide for Professional Programmers," SPC-91061-N, Version 02.00.02, 1991.


little tree home | about little tree | products | technical articles | email