8
votes

Analyse de flux de contrôle déroutant du test parasoft C ++

Nous utilisons Test parasoft C ++ pour analyser statiquement notre code. Il a des problèmes avec le code comme ce qui suit: xxx

Il avertit sur le * x; ligne qui:

La mémoire libérée ne doit pas être accessible ultérieurement en aucune circonstance

Il est conclu que le flux de contrôle peut passer dans le bloc Catch (...) Bloc, Supprimer x , passez au-delà du lancer ; , et faites-le à * x; . J'ai essayé lancer std :: exception (""); et quelques autres personnes et ont eu la même chose. Parasoft connaît certainement des exceptions et les incorpore dans son flux de contrôle, car de nombreux autres tests impliquent une vérification des exceptions. Est-il juste confondu dans ce cas ou existe-t-il en fait une manière pour l'exécution de ce programme de frapper à la fois Supprimer x; et * x; < / p>


11 commentaires

Il me ressemble comme ça va être confus.


Je dirais que c'est confus - mais vous devriez demander à Parasoft. Je dirais aussi que si vous avez du vrai code comme celui-ci, vous vous trompez mal.


Pouvez-vous extraire le Supprimer x; dans une méthode inline? Ou parasoft sait-il regarder là-bas aussi?


@unapersson c'était juste un extrait qui a démontré le problème


Vous pouvez essayer d'ajouter un avortement () juste après le lancer . Mais qui sait, peut-être que cela sera diagnostiqué comme code mort ...


Cela pourrait inspecter la barre (); Si la barre () est connue pour libérer X (ou X est statiquement connue pour être libérée avant d'entrer dans FOO), cela ne serait pas faux. Dans tous les autres cas, l'analyse de flux est confuse :)


@Peterg Ouais, le compilateur est plus intelligent et le drapeaux. Ce qui, viens y penser, est une assez bonne indication que Parasoft a tort. Il est possible de #Ifdef sur le Abort () Seulement seulement parasoft le voit, mais je préfère simplement supprimer le message d'erreur tant que je sais que c'est invalide.


@sehe bar () est en fait vide et la suppression de l'appel ne change pas l'analyse (je ne l'ai pas simplement inclus pour essayer de détecter que le attrape n'arriverait jamais , mais je suppose que ça ne vérifie pas ça)


Juste la pêche maintenant, mais avez-vous essayé de jeter une autre exception dans le bloc de capture? Comme peut-être un lancer std :: exception ("hi"); peut-être que cela ne sait pas comment traiter de nouveau?


En fait, pour l'humour, avez-vous examiné le site Web de Parasoft? Cool Buzzwordword Madness! Je suppose qu'ils ne vendent plus à des techniciens,


@Chris je l'ai fait, j'ai eu une ligne à ce sujet ("J'ai essayé jet std :: exception (" "); et quelques autres personnes et ont eu la même chose"). J'ai essayé std :: exception , std :: runtime_error , une classe personnalisée et juste jette 0; ; Ils se sont tous comportés de la même manière. On sonne comme ça juste des bâches lancer en général; Je l'ai essayé à l'extérieur d'un block (juste Supprimer x; lancer 0; * x; ) et il s'est toujours plaint que * x était libéré mémoire, sans se rendre compte qu'il était mort


3 Réponses :


0
votes

Peut-être ceci est une suggestion de Dafts, mais qu'est-ce que Parasoft dit si vous laissez la prise pour la fin? IE

void foo(int* x) 
  {
  try 
    {
    bar();
    *x;
    } 
  catch(...) 
    {
    delete x;
    throw;
    }      
  }


2 commentaires

Si cela fonctionne autour du problème, ce n'est pas vraiment à côté du point - bien que j'ai tendance à favoriser simplement l'ignorance de la conclusion manifestement erronée de l'outil d'analyse de parasoft.


Je seconde le commentaire. Si vous commencez à travailler autour de fausses alarmes en modifiant le code, vous introduisez des bugs. Cela peut être une fois en 50 ou juste une fois en 200 ans. Peu importe: vous passez du temps à introduire des bugs.



2
votes

L'outil est donc faux (cela a déjà été dit auparavant, je sais), et je suppose que vous ne voulez pas swith de l'avertissement.

Je suis d'accord avec le commentaire de @ Pascal qu'il est un peu dangereux de réécrire le code juste pour le travail juste pour travailler autour des limitations de certains outils. Ce que vous pouvez faire est de désactiver cette prévenue pour simplement les fichiers où vous avez actuellement ce problème. p>

Ensuite, vous avez une construite sans avertissement pour commencer avec, sans qu'un outil ne raconte de réécrire le code valide existant. P>

pour le nouveau code strong>, vous aurez adopter un style compris par l'outil. Ceci est moins en cause car ce sera le code que vous travaillez actuellement, il serait donc moins de problème si vous avez besoin de vous réécrire légèrement pour vous débarrasser des avertissements. P>

Bien que correct, le style existant est loin d'être idéal. P>

Je recommanderais de stocker des pointeurs comme x code> dans Auto_PTR. Cela supprimera automatiquement le contenu de l'auto_ptr s'il passe hors de portée - sauf si vous ne le prenez explicitement de l'auto_ptr. C'est beaucoup plus facile sur les yeux et aussi joliment que cette fonction s'appuie sur le pointeur. P>

void foo(auto_ptr<int> x)
{
    bar();
    *x;
}


0 commentaires

0
votes

Mise à jour rapide:

1) La règle mentionnée ci-dessus n'est pas une règle d'analyse de flux du tout. Cela étant dit, la règle (ID MRM-31) a été améliorée dans le test C ++ 9.2.0 et ultérieure. Il existe également une règle d'analyse de flux correspondante pour cela dans le test C ++ (ID: BD-RES-FREE) qui devrait faire ce que vous voulez.


0 commentaires