通常、PVS-Studioアナライザーの新しいバージョンのリリースに関するメモは書きません。 ただし、新しいリリースには、CおよびC ++コードの分析に関する多くの興味深い変更が含まれています。これについては、ユーザーに伝えたいと思います。
近日公開予定のJava
正直に言うと、PVS-Studioの最新かつ最も興味深いイノベーションはまだ隠されています。 Java言語アナライザーのサポートを意味します。 Java用PVS-Studioのパブリックベータ版はまだありませんが、まもなく利用可能になります。 テストに参加したい場合は、 サポートに連絡してください(Javaのアナライザーが必要です)。
CおよびC ++の新しい診断
新しいバージョンでは、少し夢中になり、すぐにCおよびC ++(V1021-V1035)の15の汎用診断を追加しました。 マイナーリリースでは、非常に多くの診断が一度に追加されたことはありません。 各診断の詳細については、 ドキュメントを参照してください。 私の意見では、新しい診断の中で最も興味深いのは次のとおりです。
- V1026。 変数はループ内でインクリメントされます。 符号付き整数オーバーフローの場合、未定義の動作が発生します。
- V1033。 変数はCでautoとして宣言されています。デフォルトの型はintです。
linux.org.ruフォーラムでの議論に基づいて作成されたDiagnostics V1026 。 プログラマーはGCC 8コンパイラーの不具合について不満を漏らしましたが、後で判明したように、障害は不正確なコードであり、未定義の動作を引き起こしました。 このケースを見てみましょう。
ご注意 最初の議論では、変数sはconst char * s型です。 さらに、ターゲットプラットフォームでは、 char型は符号なしです。 したがって、わかりやすくするために、この例では、ポインターの型はconst unsigned char *であるとすぐに書きました。
int foo(const unsigned char *s) { int r = 0; while(*s) { r += ((r * 20891 + *s *200) | *s ^ 4 | *s ^ 3) ^ (r >> 1); s++; } return r & 0x7fffffff; }
コンパイラは、ビット単位のAND演算子(&)のコードを生成しません。 このため、関数は負の値を返しますが、プログラマが意図したとおりに発生することはありません。
開発者は、これがコンパイラの不具合だと考えています。 しかし、そのようなコードを書いたプログラマーは実際には間違っています。 未定義の動作が発生するため、関数は正しく機能しません。
コンパイラーは、変数rで特定の量が考慮されることを確認します。 変数rのオーバーフローは発生しません。 それ以外の場合、これは未定義の動作であり、コンパイラは考慮および考慮すべきではありません。 したがって、コンパイラーは、サイクルの終了後の変数rの値が負になることはないため、符号ビットをリセットする操作r&0x7fffffffは不要であり、コンパイラーは関数から変数rの値を返すだけであると考えています。
Diagnostics V1026は、このようなエラーを検出するように設計されています。 コードを修正するには、符号なし変数を使用してハッシュを読み取るだけで十分です。 コードの修正バージョン:
int foo(const unsigned char *s) { unsigned r = 0; while(*s) { r += ((r * 20891 + *s *200) | *s ^ 4 | *s ^ 3) ^ (r >> 1); s++; } return (int)(r & 0x7fffffff); }
ここで、別のV1033診断を見てみましょう。 可能性のあるエラーの原因が、C ++ 11に登場した新しいキーワードautoであったという点で興味深いです。 そして、有罪なのはC ++ 11言語自体の革新ではなく、心理的計画の微妙な違いです:)。 今から説明します。 このコードを見てください:
float d = 3.14f; int i = 1; auto sum = d + i;
間違いだと思いますか? 考えてみてください。 以下に画像を示しますので、すぐにテキストを読む必要はありません。
何が間違っていると思いますか? そうでない場合は、さらに興味深い情報があります。 sum変数は4.14ではなく4になります。 なんで?
今、読者はそれが不正ななぞなぞだと言うでしょう! 問題は、これがC ++ではなく、Cであることです。
プロジェクトではC ++と古き良きCの両方を使用することがあります。プログラマはC ++でautoを使用することに慣れ、誤ってCでこの単語を使用することができます。
オート
ローカル変数をローカルライフタイムを持つものとして定義します。 キーワードautoは次の構文を使用します。
[auto] data-definition;
ローカルライフタイムはローカル変数のデフォルトであるため、autoキーワードはほとんど使用されません。
変数sumの型はintであるため、その値は4になります。
実際、CとC ++ファイルの混合を使用するプロジェクトでは、このエラーは異様に見えるかもしれませんが、非常に簡単に作成できます。 したがって、C-ファイルを分析するとき、PVS-Studioはそのような疑わしい構造について警告します。
その他の革新
Wafビルドシステムのプロジェクトをチェックする機能が追加されました。
組み込みシステム向けのアナライザーの開発を続けています。 このバージョンは、GNU Arm Embedded Toolchain、Arm Embedded GCCコンパイラのプロジェクト検証サポートを追加します。
Visual C ++コンパイラ(cl.exe、Visual Studio / Standaloneのvcxprojプロジェクト)のプロジェクトを分析するとき、アナライザレポートはチェックされたファイルへのパスにレジスタを保存するようになりました。 横からの改良は、実際よりも簡単に見えます。 ファイルを前処理するとき、cl.exeコンパイラはファイル名の大文字と小文字を区別します。 そして、それらをアナライザーに復元する必要があります。
WindowsのCLMonitor /スタンドアロンからpvsconfigファイルを使用する機能が追加されました。
pvs-studio-analzyer / CMakeモジュールにインクリメンタル分析モードが追加されました。 PVS-Studio CMakeモジュールは、Visual C ++コンパイラ(cl.exe)を使用するプロジェクトでWindowsで使用できるようになりました。
.NET Core / .NET Standard Visual Studioプロジェクトの増分分析のサポートが追加されました。
サイトリンク
- PVS-Studio。 バージョン履歴 。
- アンドレイ・カルポフ。 未定義の振る舞いは、あなたが考えるよりも近いです 。
- Will Dietz、Peng Li、John Regehr、Vikram Adve。 C / C ++の整数オーバーフローを理解する 。
- エゴール・ブレディキン。 新しい静的アナライザーPVS-Studio Javaの開発 。