What's new in version 9 (April 2017, updated November 2023)?

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, Delphi 11 Alexandria and Delphi 12 Athens 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, latest update 11.3 in February 2023), including the new OSX ARM 64-bits compiler target. Plus the current Delphi 12 Athens major version.

 

 

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:

 

 

clip0182

 

If the code had instead been written as "Arr[553]" (an explicit value), the compiler would have halted on this line. But for a variable, it does not.

 

clip0187

 

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.

 

Example:

 

clip0181

 

clip0188

 

clip0189

 

 

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.

 

clip0183

 

 

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.

 

clip0191

 

 

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:

 

clip0207

 

 

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.

 

clip0208

 

 

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:

 

.clip0209

 

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.

 

 

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.

 

clip0192

 

 

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.

 

 

Example:

 

clip0172

 

 

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.

 

Example:

 

clip0173

 

 

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.

 

Example:

 

clip0174

 

 

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.

 

Example:

 

clip0170

 

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

 

Example:

 

clip0171

 

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.

 

Example:

 

clip0169

 

In the example above, use instead SameValue function from System.Math unit.

 

 

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.

 

 

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.

 

Example:

 

clip0206

 

 

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.

 

clip0200

 

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.

 

clip0198

 

 

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.

 

Example:

 

clip0178

 

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.

 

Example:

 

clip0179

 

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.

 

Example:

 

clip0176

 

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.

 

Example:

 

clip0185

 

 

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.

 

 

clip0210

 

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

 

 

Added in 9.10:

 

New section in Warnings: "Mismatch parameter value (32/64-bits)" (WARN63)

 

This section reports locations where 32-bits variables are passed as 64-bits parameters (or vice versa).

 

 

Added in 9.11:

 

New sections in Convention Compliance Report:

 

"Class fields that do not start with 'F'" (CONV23)

 

This section lists class fields with a name not starting with "F". It complements the CONV6 report section which only lists fields exposed as properties.

 

"Value parameters that do not start with selected prefix" (CONV24)

 

This section lists value parameters that do not start with selected prefix.

 

"Const parameters that do not start with selected prefix" (CONV25)

 

This section lists const parameters that do not start with selected prefix.

 

"Out parameters that do not start with selected prefix" (CONV26)

 

This section lists out parameters that do not start with selected prefix.

 

"Var parameters that do not start with selected prefix" (CONV27)

 

This section lists var parameters that do not start with selected prefix.

 

"Old-style function result" (CONV28)

 

This section lists functions where instead of "Result", the function name is used as the result variable.

 

"With statements" (CONV29)

 

This section lists locations where "with" is used.

 

"Private can be changed to strict private" (CONV30)

 

This section lists class members that can be strict private instead of private.

 

"Protected can be changed to strict protected" (CONV31)

 

This section lists class members that can be strict protected instead of protected.

 

 

New section in Identifiers Report:

 

"Inlined variables and constants" (IDEN4)

 

This section lists variables and constants that are declared inline.

 

 

Added in 9.12.2:

 

New section in Strong Warnings: "Interface lacks GUID" (STWA10)

 

This section reports interface types without a GUID.

 

 

 

Relative paths

 

Now relative paths for folders can be specified. This applies to the main file folder, output folder, searched folders, excluded report folders and excluded search folders. The relative path should be relative to the folder where the project file (PAP-file) is located.

 

In the dialog where paths are selected, just write the relative path manually and add it to the selected folders.

 

 

See also:

 

What's new in version 8?

What's new in version 7?

What's new in version 5?

What's new in version 4?