NAME
Devel::TypeCheck - Identify type-unsafe usage in Perl programs
VERSION
Version 0.02
SYNOPSIS
This file exists as a placeholder for the documentation. To use, invoke the B::TypeCheck module as one normally would with any other compiler back-end module:
perl -MO=TypeCheck[,-verbose][,-main][,I<subroutine> ...] I<SCRIPTNAME>
OPTIONS
- -verbose
-
Print out the relevant parts of the opcode tree along with their inferred types. This can be useful for identifying where a type-inconsistant usage is in your program, and for debugging TypeCheck itself.
- -main
-
Type check the main body of the Perl program in question.
- subroutine
-
Type check a specific subroutine. In this release, TypeCheck does not do generalized interprocedural analysis. However, it does keep track of types for global variables.
EXAMPLES
Here is an example program that treats $foo in a type-consistent manner:
# pass
if (int(rand(2)) % 2) {
$foo = 1;
} else {
$foo = 2;
}
When we run the TypeChecker against this program, we get the following output:
Type checking CVs:
main::MAIN
Pad Table Types:
Name Type
----------------------------------------
Result type of main::MAIN is undefined
Return type of main::MAIN is undefined
Global Symbol Table Types:
Name Type
------------------------------------------------------------------------------
foo MH:...,MKN<IV>
Total opcodes processed: 24
2.pl syntax OK
The indented stanza indicates that there are no named local variables in MAIN.
The stanza at the bottom shows that we have a global variable named foo of the glob (MH:...
) type that contains an integer (MKN<IV>
) in its scalar value element.
Here is another that does not:
# fail
if (int(rand(2)) % 2) {
$foo = 1;
} else {
$foo = \1;
}
We get the following when we run TypeChecker against the project:
Type checking CVs:
main::MAIN
Could not unify MKPMKN<IV> and C<< MKN<IV> >> at line 5, file 3.pl
CHECK failed--call queue aborted.
This means that the type inference algorithm was not able to unify a reference to an integer type (MKPMKN<IV>
) with an integer type (MKN<IV>
). To get a better idea about how this works, we will look at the verbose output (with lines numbered and extraneous lines removed for clarity):
24 S:leave {
25 S:enter {
26 } = void
27 S:nextstate {
28 line 3, file 3.pl
29 } = void
30 S:sassign {
31 S:const {
32 } = MKN<IV>
33 S:null {
34 S:gvsv {
35 } = MKf
36 } = MKf
37 unify(MKN<IV>, MKf) = MKN<IV>
38 } = MKN<IV>
39 } = void
40 S:leave {
41 S:enter {
42 } = void
43 S:nextstate {
44 line 5, file 3.pl
45 } = void
46 S:sassign {
47 S:const {
48 } = MKPMKN<IV>
49 S:null {
50 S:gvsv {
51 } = MKN<IV>
52 } = MKN<IV>
53 unify(MKPMKN<IV>, MKN<IV>) = FAIL
54 Could not unify MKPMKN<IV> and MKN<IV> at line 5, file 3.pl
55 CHECK failed--call queue aborted.
56 Type checking CVs:
57 main::MAIN
Lines 30-38 represent the assignment that constitutes the first branch of the if statement. Here, an integer constant (MKN<IV>
, lines 31-32) is assigned to the variable represented by the gvsv operator (lines 34-35). The variable is brand new, so it is instantiated with a brand new unspecified scalar value type (MKf). This is unified with the constant (line 37), binding the type variable "f" with the concrete type <IV>
.
Lines 46-53 represent the assignment that consitutes the second branch of the if statement. Like the last assignment, we generate a type for our constant. Here, the type is a reference to an integer (MKPMKN<IV>
, lines 47-48). Since we have already inferred an integer type for the $foo variable, that is what we get when we access it with the gvsv operator (MKN<IV>
, lines 50-51). When we try to assign the constant to the variable, we get a failure in the unification since the types do not match and there is no free type variable to unify type components with.
REFERENCES
The author has written a paper explaining the need, operation, results, and future direction for this project. It is available at the following URL:
http://www.umiacs.umd.edu/~bargle/project2.pdf
This is suggested reading for this release. In future releases, we hope to have a proper manual.
AUTHOR
Gary Jackson, <bargle at umiacs.umd.edu>
BUGS
This version is specific to Perl 5.8.1. It may work with other versions that have the same opcode list and structure, but this is entirely untested. It definitely will not work if those parameters change.
Please report any bugs or feature requests to bug-devel-typecheck at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Devel-TypeCheck. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
COPYRIGHT & LICENSE
Copyright 2005 Gary Jackson, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.