Propagation constante
Avec le CODESYS Static Analysis version V5.0.0.0, l'analyse du code est basée sur une propagation constante. Les résultats de propagation constante sont utilisés pour divers contrôles. Par exemple, il vérifie si les pointeurs ne sont pas égaux à 0 ou si les indices de tableau sont hors plage valide.
Vous pouvez prendre en charge efficacement l'analyse statique simplement en sachant comment cette analyse fonctionne et quelles sont ses limites.
Propagation constante
L'analyse statique tente de déterminer la valeur d'une variable en fonction de son utilisation.
PROGRAM PLC_PRG //Declaration VAR x: INT; bTest: BOOL; END_VAR
//Implementation x := 99; IF x < 100 THEN bTest := TRUE; END_IF
Dans l'implémentation de la ligne 1, la propagation constante enregistre la valeur 99
pour la variable x
pour utiliser cette valeur pour une analyse plus approfondie. L’analyse reconnaît alors que l’expression suivante IF
-Constante de déclaration TRUE
est.
Propagation constante effectuée localement
Une valeur est déterminée uniquement localement dans le bloc fonctionnel. La manière dont une entrée est transmise n'a pas d'importance. Les résultats des appels de fonction ne sont pas non plus pertinents.
FUNCTION Func : BOOL //Declaration VAR_INPUT bText : BOOL; END_VAR
//Implementation IF bTest THEN Func := OtherFunc(TRUE); END_IF
Même si le paramètre bTest
est réglé sur TRUE
à chaque appel, cela n'a aucun effet sur la propagation constante. Même si OtherFunc(TRUE)
revient toujours TRUE
, cela n'a aucun effet sur la propagation constante.
Seules les variables temporaires ont des valeurs initiales.
Les variables locales statiques dans les programmes et les blocs fonctionnels n'ont pas de valeur initiale supposée. Les variables conservent leurs valeurs du dernier appel et peuvent donc en principe être "n'importe quoi".
Les variables locales dans les fonctions et les variables temporaires ont une valeur initiale à chaque appel. La propagation constante est calculée avec cette valeur initiale.
PROGRAM PLC_PRG //Declaration VAR x: INT := 6; bTest: BOOL; END_VAR VAR_TEMP y : INT := 8; END_VAR
bText := x < y;
La variable y
est exécuté à chaque fois PLC_PRG
ont la valeur 8. La variable x
mais pas nécessairement. Par conséquent, la propagation constante n’est utilisée que pour y
prendre une valeur, mais pas pour x
.
Il est recommandé de déclarer des variables qui sont toujours écrites en premier puis lues comme variables temporaires.
La propagation constante détermine des plages de valeurs pour les types de données numériques.
Pour réduire la complexité, une plage de valeurs avec des limites supérieure et inférieure est déterminée pour chaque variable.
PROGRAM PLC_PRG VAR x: INT := 6; bTest: BOOL; y : INT; END_VAR
//Implementation IF bTest THEN x := 1; ELSSE x := 100; END_IF IF x = 77 THEN y := 13; END_IF
Ici la plage de valeurs [1..100]
est déterminé pour la variable x
. En conséquence, à la ligne 7, la comparaison x = 77
n'est pas reconnu comme une expression constante car 77
est dans la plage de valeurs.
Les expressions complexes récurrentes ne sont pas reconnues comme la même variable.
Les expressions complexes ne peuvent pas avoir de valeur attribuée. Si de telles expressions apparaissent plusieurs fois, il est alors utile d’introduire une variable auxiliaire.
PROGRAM PLC_PRG VAR x: DINT; py : POINTER TO INT; y : INT; testArray : ARRAY [0..4] OF DINT; END_VAR
//Implementation IF py^ >= 0 AND py^<= 4 THEN x := testArray[py^]; END_IF y := py^; IF y <= 0 AND y <=4 THEN x := testArray[y]; END_IF
A la ligne 2, une erreur est émise pour un éventuel accès via pointeur à une valeur, bien que la zone pointée par le pointeur soit vérifiée. Si la valeur est d'abord copiée dans une variable locale et que sa plage est vérifiée, alors la propagation constante peut déterminer la plage de valeurs pour cette variable et permettre l'accès au tableau sur la ligne 7.
Ramification
Pour le branchement, les branches individuelles sont calculées séparément. Les plages de valeurs des différentes plages sont ensuite combinées pour former une nouvelle plage de valeurs.
//Implementation IF func(TRUE) THEN x := 1; ELSE x := 10; END_IF IF func(FALSE) THEN y := x; ELSE Y := 2*x; END_IF
Sur la ligne 6, x
a la portée [1..10]
. Après la ligne 11, y
a la plage de valeurs [1..20]
; cela résulte de l'union des deux plages de valeurs [1..10]
et [2..20]
.
Conditions
Les conditions peuvent restreindre la plage de valeurs d'une variable dans un bloc de code. Plusieurs conditions peuvent être combinées. Des conditions mutuellement exclusives peuvent également donner lieu à une plage de valeurs vide.
IF y > 0 AND y < 10 THEN x := y; ELSE x:= 0; END_IF IF x < 0 THEN i := 99; END_IF
y a la plage de valeurs [1..9]
à la ligne 2. Cela donne la plage de valeurs [0..9]
pour x
à la ligne 6. Combiné avec la condition x < 0
, cela donne un ensemble vide de valeurs possibles pour x
à la ligne 8. Le code n'est pas accessible. L'analyse statique indiquera que la condition x < 0
revient toujours FALSE
à ce point.
Boucle
Une propagation constante bouclera le code jusqu'à ce que les valeurs des variables dans la boucle ne changent plus. On suppose qu’une boucle peut être exécutée un nombre illimité de fois. Les valeurs déterminées jusqu'à présent sont combinées avec les valeurs précédentes. Les variables modifiées dans la boucle ont une plage croissante. Ici, la propagation constante ne prend pas toutes les valeurs possibles pour les plages, mais utilise uniquement les limites qui apparaissent dans le code ainsi que les valeurs 0, 1, 2, 3 et 10 car celles-ci sont souvent pertinentes.
La façon la plus simple de décrire la procédure est de prendre un exemple :
PROGRAM PLC_PRG VAR x: DINT; i : DINT; y : DINT; END_VAR
//Implementation x := 0; y := 0; FOR i := 0 TO 5 DO x := x + 1; y := i; END_FOR
La propagation constante connaît les éléments suivants à propos de la boucle :
i
, x
, et y
valent 0 au début de la première exécution de la boucle. La condition i <= 5
s'applique au code dans la boucle. La condition i > 5
s'applique au code après la boucle.
Pour les valeurs des variables dans la boucle, la propagation constante détermine les valeurs suivantes :
|
|
| ||
---|---|---|---|---|
|
|
|
Dans le détail, les étapes intermédiaires suivantes sont parcourues :
Passer |
|
|
| |
---|---|---|---|---|
1 | 0 |
|
|
|
2 |
|
|
| |
6 |
|
|
| Tout d'abord, la gamme |
7 |
|
|
| |
10 |
|
|
|
|
11 |
|
|
|
|
Dès le 11 | A partir du 11ème passage, les valeurs dans la boucle ne changeront pas. La propagation est terminée. |
En outre, i = 6
s'applique au code suivant cette boucle. La gamme [0..6]
est déterminé dans la boucle et ceci est combiné avec la condition i > 5
, ce qui donne exactement la valeur 6.