Commercial users with current maintenance contracts will be notified
immediately whenever a category A issue is confirmed.
Generally, only category A and B issues will be listed here. Category C
issues will be listed where they potentially affect a large number of users.
  
    | Ref. | Class | Category | Description | 
  
    | 485 | B | Verification | The prover will sometimes assume that an object of some class declared
    by the user can be constructed (e.g. "exists x: T :- true"
    will be assumed). If this is not the case (for example, if the class has an
    invariant that can never be satisfied), this is not true. However, in this
    case the prover should fail to validate the constructors for the
    class. | 
  
    | 538 | B | Verification | If a loop statement declares local variables, the system fails to ensure
    they their values are not used before they are initialized. However, the
    implementation would normally fail to validate, unless the code that uses
    the uninitialised variable is redundant. | 
  
    | 585 | B | Runtime | When deserializing data of an enumeration type, no check is made that
    the value read is in range. This could lead to a problem if an old version
    of a program is reading data written by a new version in which an
    enumeration has been extended and the developer omitted to increment the
    serialization version. | 
  
    | 593 | A | Verification | Within a constructor implementation, no check is made that we do not use
    members of self before they are initialised. It is possible to
    construct an example that will pass validation but fail at runtime. Example: 
    class A ^=abstract
 var v: B;   // class B is assumed to have a member
    called f
 interface
 build{x: B} post change v satisfy v'.f = x.f
 via ([v.f = x.f]: pass, []: v'= x)
 end;
 end
 | 
  
    | 625 | C | Code generation
    (C# and Java only) | C# or Java code generated by Perfect Developer sometimes fails to ensure that
    local variables are "definitely assigned" according to the C# or Java rules,
    because Perfect requires only the weaker condition that all variables are
    assigned before use. The result is an error message when the Java is
    compiled. Workaround: add a dummy initialisation of the variable
    concerned. | 
  
    | 629 | B | Code generation
    (C# and Java only) | If the expression following inherits in a constructor declaration
    is not a constructor call, the generated C# or Java code will not compile unless a
    "copy" constructor has been declared in the parent class. Workaround:
    declare a copy constructor in the parent class. | 
  
    | 635 | B | Library | The 'normalizeFile(..)' function sometimes produces incorrect results
    for invalid arguments, as follows: 
 Input:
 argument#1 (default path) = '\\MONSTER\!PublicReadOnly\'
 argument#2 (filename) = '..\Temp\Win32InstallWorkaround.txt'
 Output:
 path = '\\MONSTER\!PublicReadOnly\Temp\'
 file='Win32InstallWorkaround.txt'
 Correct output should be:
 <ERROR> because an attempt has been made to go down a level from level 0
    (the UNC descriptor '\\MONSTER\!PublicReadOnly' is the root)
 
 Input:
 argument#1 (default path) = '\'
 argument#2 (filename) ='..\Temp\Win32InstallWorkaround.txt'
 Output:
 path = 'C:\Temp\'
 file = 'Win32InstallWorkaround.txt'
 Correct output should be:
 <ERROR> because an attempt has been made to go down a level from level 0
 
 Input:
 argument#1 (default path) = 'C:\'
 argument#2 (filename) = '..\Temp\Win32InstallWorkaround.txt'
 Output:
 path = 'C:\Temp\'
 file = 'Win32InstallWorkaround.txt'
 Correct output should be:
 <ERROR> because an attempt has been made to go down a level from level 0
 
 Input:
 argument #1: '::\'
 argument #2: ''
 Output:
 path: '::\'
 file: ''
 Correct output should be:
 <ERROR> because this is not a valid filename
 | 
  
    | 644 | B | Compiler | The precondition of a method declared early should not be allowed
    to refer to other non-early methods of the same class. However, if the
    method is declared as a define or redefine of an inherited
    method and the precondition is inherited, no checks are made. | 
  
    | 649 | A | Code generation (C# and Java only)
 | When generating C# or Java for a schema that modifies self, it is
    possible for aliasing to occur between self and a variable that has
    been copied from an earlier instance of self. Example: class
    A ^=abstract
 var v: int;
 interface
 // The following schema will result in v having a final value of 1
    instead of being the same as the initial value
 schema !buggy post (let temp ^= self; v! = 1
    then v! = temp.v);
 end
 | 
  
    | 666 | B | Compiler | The compiler does not permit explicit use of the type 'from anything'
    due to memory management issues when generating C++. | 
  
    | 687 | C | Runtime | If the system runs out of memory while deserializing data (e.g. because
    the file is corrupt but the corruption has not been detected, or because
    more memory was available when the data was serialized), instead of
    returning failure from the deserialization call, the program is terminated. | 
  
    | 796 | B | Compiler | The compiler does not correctly process require-parts of templates that
    declare a requirement for a constructor of a template parameter; instead it
    generates a warning that the feature is unimplemented and the requirement
    will be ignored. | 
  
    | 804 | A | Verification | The system does not check for illegal direct recursion. An example would
    be a method precondition that contains a call to the method. | 
  
    | 805 | A | Verification | The system does not detect indirect recursion whether illegal (e.g. a
    recursive precondition) or legal (in which case appropriate variants must be
    declared and the corresponding proof obligations generated). | 
  
    | 890 | A | Verification | The prover assumes that unbounded integers can be stored and
    manipulated by the generated code. No allowance is currently made for the fact that the code
    generator and run-time library map Perfect integers to bounded
    integers in the target language. | 
  
    | 1074 | A | Code generation | If a 'forall' postcondition modifies individual elements of a sequence, and the new value depends on earlier elements of the
    same sequence, the code generator fails to capture the orignal values before they are changed. | 
  
    | 1136 | A | Verification | The verifier uses rules for idealised real numbers, but the code generator maps reals to standard floating-point types.
    Therefore verification is unsound with respect to the generated code when reals are used. | 
  
    | 1137 | A | Verification | The verifier folds constant expressions involving reals using floating-point arithmetic.
    Due to rounding errors, this may lead to incorrect verification of specifications that use reals. | 
  
    | 1138 | A | Verification | In specifications that use ref types, it is possible that a heap object A of some type T may directly or indirectly hold a reference to
    another object of B also of type T. When S calls members of object B via the reference, it will be assumed that the invariant of B holds.
    However, if B is the same object as A (i.e. there is a circular chain of references), that may not be true. | 
  
    | 1139 | A | Code generation (C++ only) | If a specification uses ref types and causes circular chains of references to be created, the reference-counting garbage collection
    in the generated C++ code will not collect the associated storage when such a chain becomes inaccessible, unless the chain is broken first. | 
  
    | 1185 | B | Code generation | The generated code uses the ASCII character set, therefore Unicode characters that are not also
    ASCII characters cannot be used in character and string literals. | 
  
    | 1186 | B | Compiler | The compiler assumes that the input file is ASCII and fails to interpret UTF-8, UTF-16 and UTF-32 files correctly. | 
  
    | 1231 | A | Verification | When proving that the predicate of an exists-expression over a collection is well-formed, the prover rightly assumes the current
    element is in the collection, and may infer that the collection is not empty. However, this inference may get exported to the surrounding
    context, which may lead the prover to incorrectly infer that the collection is not empty when trying to prove that the exists-expression
    is true, leading to a false proof. | 
  
    | 1245 | A | Verification | A small number of prover rules that involve instantiating bound variables have incorrect quantifier depths on the right hand side,
    because the mechanism used to detect inconsistencies in quantifier depths did not function for those rules.
    Where a term contains nested bound variable declarations, this can lead to use of the incorrect bound variable after the rule is applied.
    Typically, this leads to failed proofs or to prover termination due to type inconsistency; however it might be that
    it could also lead to false proofs. |