RADE

C++ Source Checker

mkCheckSource Forbidden Constructions

Testing source code in the CAA V5 environment

Technical Article

Abstract

This article describes the checks identified by UACS, STRTOK, UADC, PCOM, DOKM, PUCE, IDGP, VISI.


Problematic

Migrations lead to existence of deprecated constructions (call to a method, use of class or interface ...). Furthermore, some C++ constructions are prohibited with Object Modeler (identifier, call to delete on some kinds of pointers). CSC checks the uses of C++ entities, methods, constructions or identifiers which are declared as forbidden.

[Top]

Checks

Principle

UACS:

Some identifiers or keywords are forbidden when programming with CAA architecture. When CSC sees one of these keywords, an error is reported.

STRTOK:

This check is a particular case of the previous one as its aim is to prevent the usage of strtok function. strtok is a standard C library function whose use is not safe. Indeed, the function is not thread-safe and not re-entrant and can induce unpredictable run-time errors. That is why it may be safe to use a substitute.

UADC:

The Lifecycle of the instances of some classes (like dialog objects) must not be managed by the user, but by the infrastructure itself. These objects are automatically and recursively deleted by the infrastructure when useless. The user must not delete these instances himself.

For example, to delete a dialog object in a dialog window while the dialog window remains active, you can use the RequestDelayedDestruction ; the delete operation is then delayed. See Deleting Dialog Objects in [1].

CSC looks, for each pointer of these types, if the pointer is deleted. In that case, an error is reported, and a message specifies the correct method to use.

PCOM:

Some methods are defined for a class (by inheritance for example) but must not be called on the class instances. When an object calls a method prohibited for its class (or for a parent class), an error is reported.

DOKM:

Overloading certain C++ keywords via a macro definition is not recommended, as it can transgress the encapsulation principle. An error is reported for each macro definition with a prohibited name.

PUCE:

Some C++ entities (classes, interfaces) have deprecated, or prohibited, uses. When one of these entities is used in a not allowed way, an error is reported.

IDGP:

To prevent dead-lock on multi-processor machines, the graphic primitives aggregated within a composite graphic primitive should not be destroyed during the destruction of the composite. Then, the check controls that no call to Destroy on a graphic primitive is done in the destructor of a CATGraphicPrimitive derived class.

VISI:

To prevent access to SpecsModeler internals, uses of some identifiers and the corresponding strings report an error.

[Top]

UACS

UACS stands for UnAuthorized Construction.

An error of type UACS is reported when:

Example UACS-1

"assert" is forbidden in CAA.

The following code will report an error:

...
assert( iCKEFactory != NULL_var );
...

To correct the error, use the CAA error management [2].

[Top]

STRTOK

An error of type STRTOK is reported when:

Example STRTOK-1

The following code will report an error:

...
char* input = ...;
char* token = strtok( input, "\t");
...

To correct the error, use other standard library calls or system services.

[Top]

UADC

UADC stands for UnAuthorized Delete Class.

An error of type UADC is reported when:

If the user deletes the pointer himself, the application will try to delete the pointer again, implying a Freeing Freed Memory error.

One can specify in ReplaceDeleteMethods section of setting files which method should be used instead of delete.

Example UADC-1

The CATDialog object pointers must not be deleted by the user, but by the application itself. Method RequestDelayedDestruction() should be used instead of delete. The class CATDialogAgent inherits from class CATDialog:

Let's imagine a class CATTestImportCmd containing a data member _dialogAgentDlgOK of type CATDialogAgent:

...
class CATTestImportCmd : public CATStateCommand
{
  ...
  CATDialogAgent* _dialogAgentDlgOK;
  ...
};
...

The following code will report an error:

...
CATTestImportCmd::~CATTestImportCmd
{
  if( _dialogAgentDlgOK!=NULL ) 
  {
    delete _dialogAgentDlgOK;
    _dialogAgentDlgOK= NULL;
  }
  ...
}
...

To correct the error, replace the delete as follow:

...
CATTestImportCmd::~CATTestImportCmd
{
  if( _dialogAgentDlgOK!=NULL ) 
  {
    _dialogAgentDlgOK->RequestDelayedDestruction();
    _dialogAgentDlgOK= NULL;
  }
  ...
}
...

[Top]

PCOM

PCOM stands for Prohibited Call Of Method.

Call of some methods are prohibited for the instances of specific classes. Only explicit calls are checked. The method signature is not taken into account for this check. The list of prohibited calls is provided in the setting files, see ProhibitedCalls section.

An error of type PCOM is reported when:

Example PCOM-1

Instances of class CATRep and of all the inherited classes must not call the Release method, therefore the following code will report an error:

CATRep* rep = new CATRep();
...
rep->Release();
...

To correct the code, replace the call to Release() by a call to Destroy() method:

CATRep* rep = new CATRep();
...
rep->Destroy();
...

[Top]

DOKM

DOKM stands for Dangerous Overloading of C++ Keyword via MacroDefinition.

Overloading certain C++ keywords via a macro definition leads to transgress the encapsulation principle. For example, defining a macro called "class" to expand in "struct" would give access to all class members with default private access.

An error of type PCOM is reported when:

Example DOKM-1

The following code will report an error:

#define class struct

[Top]

PUCE

PUCE stands for Prohibited Use of C++ Entity.

For a class, a prohibited use can be one of the following:

For an interface, the possible prohibited uses are the same as above, except the creation of an instance by new, which means nothing for an interface. On the other hand, an additional interface use is the possibility to adhere to the interface using TIE_xxx or TIEchain_xxx macros.

The list of the prohibited / deprecated uses for each class concerned is provided in the ClassDetection section of the setting files. The list of the prohibited / deprecated uses for each interface concerned is provided in the InterfaceDetection section of the setting files.

An error of type PUCE is reported when:

To correct the error, see the C++ API documentation in CAA V5 Encyclopedia.

Example PUCE-1

Let's assume that deriving class CATDlgFile is a deprecated use. The following code will report a PUCE error:

class CATFrmFile : public CATDlgFile{
...
}

Example PUCE-2

Let's assume that use of a CATDlgFile as method or function argument type is a deprecated use. The following code will report a PUCE error:

class CATScriptEditor : public CATDlgDialog {
  ...
  HRESULT SetFilterStrings(CATDlgFile * iDlgFile);
}

Example PUCE-3

Let's assume that defining CATDlgFile data members is a deprecated use of CATDlgFile. The following code will report a PUCE error:

class CATMCVBBox : public CATFrmDialog {
CATDlgFile * _fileDialog;
...
}

Example PUCE-4

Let's assume that casting into CATDlgFile is a deprecated use of CATDlgFile. The following code will report a PUCE error:

CATDlgFile *dlgFile = (CATDlgFile *)iSendingCommand;

Example PUCE-5

Let's assume that the inclusion of the header of class CATDocument is a deprecated use of CATDocument. The following code will report a PUCE error:

#include "CATDlgFile.h"
...

Example PUCE-6

Let's assume that creating a CATDlgFile instance with the operator new is a deprecated use. The following code will report a PUCE error:

CATDlgFile * dlgFile = new CATDlgFile(this, "OpenDlgFile", CATDlgWndModal);

Example PUCE-7

Let's assume that adhesion to CATIPersistent interface is a deprecated use of CATIPersistent. The following code, implementation of class CATImplementPersistent, will report a PUCE error:

CATImplementClass( CATImplementPersistent,
                   Implementation, 
                   CATBaseUnknown,
                   CATNull );
#include "CATIPersistent.h"
TIE_CATIPersistent(CATImplementPersistent);
....

[Top]

IDGP

IDGP stands for Invalid Destructor of a Graphic Primitive.

To prevent dead-lock on multi-processor machines, the graphic primitives aggregated within a composite graphic primitive should not be destroyed during the destruction of the composite.

Then, an error of type IDGP is reported when:

Example IDGP-1

Let's assume that CATMyShapeGP class derives (indirectly) from CATGraphicPrimitive class and that its data member _pGroundGP points to an instance of CAT3DPlanarFaceGPclass. Finally, let's assume that CAT3DPlanarFaceGP is also a sub-class of CATGraphicPrimitive class.

class CATMyShapeGP : public CATMyGeneralShapeGP {
public:
    ~CATMyShape();
    ...
private:
    CAT3DPlanarFaceGP* _pGroundGP;
}

The following implementation of CATMyShapeGP::~CATMyShapeGP will report a IDGP error:

CATMyShapeGP::~CATMyShapeGP(){
    if (_pGroundGP){
        CATGraphicPrimitive::Destroy(_pGroundGP);
        _pGroundGP = NULL;
    }
}

 

To correct the code, destruction of the face should not occur during the destruction of the main graphic primitive.

[Top]

VISI

VISI stands for Virtual Instances : SpecsModeler Impacts.

To prevent access to SpecsModeler internals, any use of

CATSpecRoot, CATSpecNamed, CATSpecObject, CATSpecValRoot, CATSpecValArray, CATSpecLiteral identifiers
CATListPtr<type> and CATListVal<type> identifiers, where <type> belongs to the previous list
strings corresponding to these identifiers ("CATSpecRoot", "CATListPtrCATSpecObject"...)

is prohibited.

An error of type VISI is reported when:

Example VISI-1

The following code  will report 2 VISI errors:

CATListPtrCATSpecRoot lpSR_AllVisuPrd;
CATProdListAllInstances(lpSR_AllVisuPrd, (CATSpecObject*)(iProd->GetImpl()));

[Top]

Relative sections in setting files

For a more complete description of Setting Files, see [3].

UnauthorizedIdentifiers

This section is located in: SettingsSet > OptionLists > Various_OptionLists

This section contains a list of Word. Each Word describes an unauthorized identifier.

Example:

Word     assert

This means that the C++ keyword "assert" is not authorized.

[Top]

UnauthorizedClassDelete

This section is located in: SettingsSet > OptionLists > Various_OptionLists

This section contains a list of ClassName. Each ClassName describes a class one can not delete directly.

Be careful:

Example:

ClassName  CATCommand

This means that no pointer of type CATCommand can be deleted directly. It also means that no pointer of an inheriting type can be deleted directly.

[Top]

ReplaceDeleteMethods

This section is located in: SettingsSet > OptionLists > Various_OptionLists

This section contains a list of Call.

ClassName
The name of the class.
MethodOrFunctionSign
The signature of the method which must replace delete for this class and its children, if declared as non-deletable (see above, section UnauthorizedClassDelete)

Be careful:

Example:

ClassName  		CATBaseUnknown
MethodOrFunctionSign 	Release()

ClassName  		CATRep
MethodOrFunctionSign 	Destroy()

This means that a pointer of type CATBaseUnknown must be deleted by a call to Release and a pointer of type CATRep, although it inherits from CATBaseUnknown, by a call to Destroy. A pointer of type CATNotification, which inherits from CATBaseUnknown but not from CATRep, must be deleted by a call to Release ; a pointer of type CAT2DLineRep, which inherits from CATRep, must be deleted by a call to Destroy.

[Top]

ProhibitedCalls

This section is located in: SettingsSet > OptionLists > Various_OptionLists

This section contains a list of Call. Each Call describes a prohibited call:

ClassName
The name of the class
MethodOrFunctionSign
The name of the method that instances of the class are not authorized to call. No argument can be provided.

Be careful:

Example 1:

ClassName            CATRep
MethodOrFunctionSign Release

means that CATRep instances, and instances of classes inheriting from CATRep, must not call Release method.

[Top]

ClassDetection

This section is located in: SettingsSet > OptionLists > EntityDetection_OptionLists

This section contains a list of ClassDetection. Each ClassDetection is composed of

ClassName
Name of the class
ClassUseSet
Set of prohibited uses for the class (prohibited = true means that the use is prohibited)
Replacement
Optional message helping to correct the error

The possible values of use attribute are: "Derivation", "MethodOrFunctionArgument", "DataMemberOrLocalVar", "CastInto", "IncludeOfHeader" and "New".

Example 1:

ClassName   :     	CATDlgFile
ClassUseSet : 	Derivation 		prohibited
		MethodOrFunctionArgument 	prohibited
		DataMemberOrLocalVar 	prohibited
		CastInto			prohibited
		IncludeOfHeader		prohibited
		New			prohibited
Replacement : 	nothing specified

means that class CATDlgFile cannot be inherited or used as formal argument, data member or local variable type. Casting into CATDlgFile is also prohibited, as well as the inclusion of the CATDlgFile.h file and the call to new CATDlgFile(...) to create new CATDlgFile instances.

Be careful:

[Top]

InterfaceDetection

This section is located in: SettingsSet > OptionLists > EntityDetection_OptionLists

This section is quite similar to the previous one. The only difference is in the possible values of use attribute, which are: "Derivation", "MethodOrFunctionArgument", "DataMemberOrLocalVar", "CastInto", "IncludeOfHeader" and "TIE".

Example 1:

ClassName   :     	CATIFactoryOfContainers
ClassUseSet : 	Derivation 		prohibited
		MethodOrFunctionArgument 	prohibited
		DataMemberOrLocalVar 	prohibited
		CastInto			prohibited
		IncludeOfHeader		prohibited
		TIE 		prohibited
Replacement : 	CATCreateApplicativeContainer (in CATAppliContServices)

means that interface CATIFactoryOfContainers cannot be inherited or implemented directly, or used as formal argument, data member or local variable type. Casting into CATIFactoryOfContainers is prohibited, like the inclusion of the CATIFactoryOfContainers.h file

Be careful:

[Top]


In Short

UACS prevents from using unauthorized identifiers.
UADC prevents from using memory that has been de-allocated. These errors can, in some cases, be fatal.
PCOM prevents prohibited calls of methods.
PUCE prevents deprecated or prohibited uses of classes or interfaces.

[Top]


References

[1] Creating Dialog Objects
[2] Managing Errors
[3] Setting Files
[Top]

History

Version: 1 [May 2001] Document created
[Top]

Copyright © 2000, Dassault Systèmes. All rights reserved.