What's new in version 9 (April 2017, updated September 2021)?
|Top Previous Next|
This article describes changes and new features in Pascal Analyzer version 9, compared to the previous version 8. The new version has been enhanced with a lot of smaller and greater features. As part of our continuing quality work, there are also numerous optimizations and error fixes.
There are in this version one new report, and 22 new report sections. The total number of sections is now 237. These sections are divided over 52 different reports.
Support for Delphi 10.2 Tokyo, Delphi 10.3 Rio, Delphi 10.4 Sydney and Delphi 11 Alexandria added
Pascal Analyzer now also understands code for Delphi 10.2 Tokyo (released March 2017), including the new Linux 64-bits compiler target. Also it supports Delphi 10.3.3 Rio (released November 2019), and Delphi 10.4.2 Sydney (released February 2021), and Delphi 11 (released September 2021), including the new OSX ARM 64-bits compiler target.
New report: Clone Report (CLON)
This new report detects code clones. It compares subprograms within the same module and across modules.
Use the results to refactor your code and eliminate duplicated code.
New section in Strong Warnings Report: "Index error" (STWA4)
This section reports locations in your code where index errors can occur. These are errors where an array index with an invalid value is accessed. Some examples:
If the code had instead been written as "Arr" (an explicit value), the compiler would have halted on this line. But for a variable, it does not.
These kind of errors will give an exception at runtime, and should of course be avoided as much as ever possible.
New section in Strong Warnings Report: "Possible bad pointer usage" (STWA5)
This section lists locations in your code where a pointer possibly is misused. It is for example a pointer that has been set to nil and further down in the code is dereferenced.
New section in Strong Warnings Report: "Possible bad typecast (consider using "as" for objects)" (STWA6)
This section lists locations in your code with a possibly bad typecast. These are typecasts that casts into a type other than what the variable itself has. If you use the "as" operator, an exception will instead be raised. Otherwise there may be access violations and errors in a totally different code location, which is awfully hard to track down.
In the example above, the last line could better be written (although still faulty!) as
Monkey := Banana as TAnimal;
This should result in an exception. But it is still preferable; instead of letting the code proceed resulting maybe in access violations later in a totally unrelated part of the code, which is not fun to debug.
Added in 9.2:
New section in Strong Warnings Report: "For-loop with possible bad condition" (STWA7)
This section lists locations in your code where for loop has any of these conditions:
Added in 9.2:
New section in Strong Warnings Report: "Bad parameter usage (same identifier passed for different parameters)" (STWA8)
This section lists locations in your code where a call to a subprogram is made with bad parameters. The situation occurs when the called subprogram has an "out" parameter plus at least one another parameter. The identifier passed is used for both these parameters. Because an "out"-parameter is cleared in the called subprogram this will give unexpected results for reference-counted variables like strings and dynamic arrays.
Added in 9.2:
New section in Strong Warnings Report: "Generic interface has GUID" (STWA9)
This section lists generic interface types that declare a GUID:
The problem with this is that all generic types created from this interface, like IMyInterface<Integer> and IMyInterface<string> will share the same GUID.
This will cause type casting to malfunction.
Added in 9.3:
New section in Strong Warnings Report: "Out parameter read before set" (STWA10)
This section lists out parameters that are read before set in the procedure.
Out parameters are not guaranteed to have a valid value when entering the function/procedure. They are just intended to be set.
New section in Warnings Report: "Mixing interface variables and objects" (WARN53)
This section reports locations in your code with assignments between objects and interface variables. Normally, unless you really know what you are doing, it is a bad idea to mix interfaces and objects. The reason is that the reference counting mechanism of interfaces can be disturbed, leading to access violations and/or memory leaks.
New section in Warnings Report: "Set before passed as out parameter" (WARN54)
This section reports locations in your code where a variable is set and then passed as an "out" parameter to a function.
Because the "out" parameter will be set in the called function without being read first, it is at least pointless to set it before it is passed. It may also indicate some misunderstanding about the code.
Consequently it is recommended to check if it is meaningful to set the variable before passing it. If not, remove the assignment, or else modify the signature of the called function from "out" to "var".
See also our blog article about out parameters.
New section in Warnings Report: "Redeclares ancestor member" (WARN55)
This section lists class fields or methods that redeclare ancestor members with the same name. This may lead to confusion about which member is referenced in a given situation. The recommendation is to refrain from reusing the same name, because this will only make your code harder to understand and maintain.
New section in Warnings Report: "Parameter to FreeAndNil is not an object" (WARN56)
This section reports locations in your code where FreeAndNil takes a parameter which is not an object, for example an interface variable. This may lead to access violations. Unlike Free, the compiler will not complain at compile-time.
New section in Warnings Report: "Enumerated constant missing in case structure" (WARN57)
This section lists locations in your code where a case statement does not list all possible values of an enumerated type. This is probably most often as intended, but it may also point out an error in the code.
In the code above, cpKing is missing from the case structure, and will trigger a warning.
If you want to suppress warnings for a case-structure where you know it is safe to exclude one or more enumerated constants, just use the PALOFF feature on the same line as the "case" keyword.
New section in Warnings Report: "Mixed operator precedence levels" (WARN58)
This section lists locations in your code where operators of different levels are mixed. Operators are in Object Pascal evaluated from left to right, unless parentheses are used to change the evaluation order. Operators of level 1 are evaluated before operators of level 2 etc.
Those are the operator precedence levels, as used in the Object Pascal language:
Level 1: @, not
Level 2: *, /, div, mod, and, shl, shr, as
Level 3: +, -, or, xor
Level 4: =, <>, <, >, <=, >=, in, is
Mixing operators is perfectly valid but you will find that your code is clearer and easier to understand if you insert parentheses. Then you do not have to think that much about operator precedence.
New section in Warnings Report: "Explicit float comparison" (WARN59)
This section lists locations in your code where floating point numbers (variables, constants, or explicit values) are directly compared. It is considered not secure to compare floating numbers directly. Instead use functions in Delphi's System.Math unit, like IsZero and SameValue.
In the example above, use instead SameValue function from System.Math unit.
Added in 9.1:
New section in Warnings Report: "Condition evaluates to constant value" (WARN60)
This section lists locations in your code where a condition evaluates to a constant value.
Added in 9.2:
New section in Warnings Report: Assigned to itself (WARN61)
This section lists locations in your code where a variable has been assigned to itself.
Even if this assignment is harmless, it makes no sense. It may indicate other problems with the code, so you should check the surrounding code.
Added in 9.3:
New section in Warnings Report: Possible orphan event handler (WARN62)
This section lists class procedures in your code that look like event handlers. But they are not connected to any control in the corresponding DFM-file.
New section in Code Reduction Report: "Consider using interface type" (REDU18)
This list contains objects which can be declared and implemented as an interface type, instead of as the class type implementing the interface. One major advantage is that interface reference counting can be used, so you will not have to explicitly free the object yourself.
In the code example above, consider instead declaring "Obj : IIntf" instead.
New section in Code Reduction Report: "Redundant parentheses" (REDU19)
This section lists locations in your code where superfluous parentheses can be removed, simplifying the code and making it easier to read.
New section in Code Reduction Report: "Common subexpression, consider elimination" (REDU20)
This section lists locations in your code with repeated common subexpressions. Those may be candidates to put into temporary variables in order to simplify and optimize the code.
In the code example above, consider putting the result of the expression "A+B+C" into a local temporary integer variable, If this really gives faster execution depends on how the compiler generates the machine code. But at least your code may become easier to read and understand.
If any of the variables involved in the repeated expressions would have been modified, between the locations, there should not be any warning.
New section in Code Reduction Report: "Default parameter values that can be omitted" (REDU21)
This list contains calls to functions or procedures that use default parameters, and where the parameter can be omitted at the call site. The reason is then that the value of the parameter passed is the same as the default parameter value. Removing the unneeded parameter value will make the code shorter and easier to read.
In the code example above, the call to ProcWithDefaultParam does not need to include the parameter P, because P is assured to have the value "nil".
New section in Code Reduction Report: "Inconsistent conditions" (REDU22)
This section reports locations with inconsistent conditions. These are places where a condition check is repeated, even if the outcome will be the same as in the previous location.
In the code example above, the expression "I = 1" has already been evaluated higher up in the code. Thus, the code is not optimal and needs work.
New section in Code Reduction Report: "Typecasts that possibly can be omitted" (REDU23)
This section reports locations with typecasts that possibly can be omitted. It is locations where the typecast casts the variable to the same type that it already has.
Added in 9.2:
New section in Code Reduction Report: "Local identifiers never used" (REDU24)
This section reports local identifiers that are declared but not used.
Added in 9.2:
New section in Optimization Report: "Inlined subprograms not inlined because not yet implemented" (OPTI9)
This section lists calls to inlined subprograms, where the subprogram will not be inlined. The reason is that the subprogram has not been implemented yet. It is implemented further down in the same module. There are a number of other conditions that also must be fulfilled for the subprogram to be inlined. But this one must always be fulfilled.
The solution is simple: If possible move the inlined subprogram further up in the code, so the compiler reaches it before the places where it is called.
Added in 9.8:
New section in Optimization Report: "Managed local variable that can be declared inline" (OPTI10)
This section reports local variables that can benefit from being declared inline instead of in the main var-section.
Added in 9.9:
New section in Optimization Report: "Managed local variable is inlined in loop" (OPTI11)
This section reports local managed variables that are declared inside a loop, which can decrease performance.
New section in Convention Compliance Report: "Class fields that are not declared in the private/protected sections" (CONV22)
This is a list of all class fields that are not declared in the private/protected sections of a class.
Fields should normally not be made "public". They should instead be accessed through properties
Continuous parser and report improvements
Numerous bug fixes and minor improvements have been added in this major new release. Often those fixes are for the parser and the evaluation of identifiers, like improving handling of generics and overloads. Also when it comes to performance, many parts of the program now execute even quicker than before.
Loading old PAL projects
When loading old (before version 9.x) projects, those now automatically select report sections that are new in version 9.x. The older handling was to not automatically add those new report sections. These had to be added manually.
Delphi project files (*.dproj) can now be loaded
These files can now directly be selected and loaded as the main file for a project. You can also select a main project file (*.dpr), with the same effect as in version 8.x, which was to implicitly also load the dproj file (when the setting "Use Delphi project options" was activated).
New command line parameter for PAL.EXE
You can now use an optional second parameter /AUTO in PAL.EXE (first parameter must as before give the path to the project) to automatically analyze the loaded project and then terminate the application. This parameter makes it easier to schedule (with Windows' Task Scheduler) analyses where PAL is automatically started and stopped.
Example of a command line:
PAL.EXE C:\proj\MyProj.pap /AUTO
Another option is of course to use the command line program PALCMD.EXE for these tasks.
Integration with Lattix
For the Uses Report, an additional file Lattix.xml is created in the report directory. You can use it to integrate with Lattix products.
New Defaults button when selecting report sections
When selecting report sections, there is a new button "Defaults". It selects the default sections when clicked. This is very convenient, for example when you have temporarily removed some sections, and want to reselect only the default ones.
Modified licensing model
Starting with this major version 9, Pascal Analyzer now uses a subscription based licensing model. Each license now includes a full year of updates and new releases. After that period, additional support plan periods can be bought. See the orders page at our web site for more details.