PVS-Studio 6.00新幎リリヌスRoslynの確認

PVS-Studio 6.00、C、C ++、C

埅望のむベントが到着したした。 CプロゞェクトのチェックをサポヌトするPVS-Studio 6.00静的コヌドアナラむザヌのリリヌスバヌゞョンをリリヌスしたした。 珟圚、コヌドはC、C ++、C ++ / CLI、C ++ / CX、Cの蚀語で蚘述されおいたす。 アナラむザヌの6番目のバヌゞョンのリリヌスでは、オヌプンRoslynプロゞェクトの怜蚌のタむミングを調敎したした。 CサポヌトがPVS-Studioアナラむザヌに登堎したのはRoslynのおかげであり、このプロゞェクトの実装ず開発に぀いおMicrosoftに非垞に感謝しおいたす。



PVS-Studio 6.00



PVS-Studioは、コヌドの䜜成段階での䜿いやすさず゚ラヌの怜玢に重点を眮いた静的コヌドアナラむザヌです。



C / C ++プログラムの新しいタむプの゚ラヌを怜玢するための蚺断ルヌルを垞に远加しおいたす。 たずえば、コンストラクタで初期化されおいないクラスメンバヌの怜玢を最近远加したしたが、これは非垞に難しいタスクでした。 ただし、蚺断の改善は、叀いバヌゞョンを倉曎する理由ではありたせん。 そしお、本圓に新しいものがアナラむザヌに远加されるのを埅ちたした。 そしお、そのような瞬間が来たした。 C蚀語をサポヌトするアナラむザヌの6番目のバヌゞョンを䞖界に玹介したす。



PVS-Studio 6.00の詊甚版は次から入手できたす。



http://www.viva64.com/en/pvs-studio-download/



アナラむザヌの6番目のバヌゞョンでは、Visual Studioの叀いバヌゞョンのサポヌトを拒吊したした。 珟圚、VS2005およびVS2008はサポヌトされおいたせん。 チヌムが匕き続きこれらのバヌゞョンのVisual Studioを䜿甚しおいる堎合は、以前のバヌゞョン5.31たたはそのアップグレヌド存圚する堎合を匕き続き䜿甚するこずをお勧めしたす。



デモ版には次の制限がありたす。 50回のコヌドゞャンプを実行できたす。 その埌、アナラむザヌはナヌザヌに自分自身に関する情報を送信するように指瀺したす。 圌が同意すれば、圌にはさらに50回の移行が䞎えられたす。



デモの制限は厳しいように思えるかもしれたせん。 しかし、圌には正圓な理由があり、倚くの実隓の埌に圌に来たした。



少数の「クリック」は、メヌルでの通信をより早く開始するのに圹立ちたす。 誰かが他のメッセヌゞを芋たい堎合は、たずえば1週間、登録キヌを枡す準備ができおいたす。 圌は私たちに手玙を曞くだけで十分です。 原則ずしお、通信の過皋で、私たちは人々が迅速にナビゲヌトできるよう支揎し、アナラむザヌを䜿甚するこずでどのように玠早く簡単に利益を埗るこずができるかを支揎したす。



ロズリン



プログラマヌは広告の圱響を受けたせん。 「ミッション」、「非の打ちどころのない」、「むノベヌションに焊点を圓おる」ずいう蚀葉で圌らを忘れるこずはできたせん。 プログラマは広告を読たず、Adblock Plusを䜿甚しおバナヌを無効にする方法を知っおいたす。



持ちこたえるこずができるのは、このツヌルたたはそのツヌルがどのように圹立぀かを瀺すこずだけです。 このようなパスを遞択し、開いおいるプロゞェクトをチェックするこずで静的解析ツヌルがどのように圹立぀かを瀺したした。



PVS-Studioは、CoreCLR、LibreOffice、Linux Kernel、Qt、Unreal Engine 4、Chromiumなどの有名なプロゞェクトで゚ラヌを芋぀けるこずができたす。 珟時点で、私たちのチヌムは230の開いおいるプロゞェクトをチェックし、それらに9355個の゚ラヌが芋぀かりたした。 はい、はい9355ぱラヌの数であり、蚺断メッセヌゞの数ではありたせん。 最も興味深いチェックは関連蚘事で芋぀けるこずができたす。



これで、Cプロゞェクトをチェックする番になりたした。 圓然のこずながら、最初の実蚌枈みプロゞェクトの1぀はRoslynでした。 最終的に、この特定のプロゞェクトのおかげで、PVS-StudioでCコヌドの分析をサポヌトするこずが可胜になりたした。



このオヌプン゜ヌスプロゞェクトを䜜成しおくれたMicrosoftに感謝したす。 Cむンフラストラクチャの開発に倧きな圱響を䞎えたす。 はい、圌はすでに圱響を䞎えおいたす たずえば、ReSharperやCodeRushなどの有名なプロゞェクトは、Rolsynベヌスに転送されたす。



Roslynプロゞェクト自䜓に぀いお少し説明したす。



コヌド名Roslynでよく知られおいる.NETコンパむラプラットフォヌムは、CおよびVisual Basic .NETの゜ヌスコヌドを分析するためのオヌプン゜ヌスコンパむラずAPIのセットです。 プラットフォヌムはMicrosoftによっお開発されおいたす。



このプラットフォヌムには、CおよびVB.NET甚の自己完結型コンパむラが含たれおいたす。 これらは、埓来のコマンドラむンアプリケヌションずしおだけでなく、.NETコヌドからアクセスできるネむティブAPIずしおも利甚できたす。 Roslynは、構文解析語圙コヌド分析、セマンティック分析、CILバむトコヌドの動的コンパむル、およびアセンブリ生成のためのモゞュヌルぞのアクセスを提䟛したす。 Roslynが提䟛するAPIは、機胜API機胜API、ワヌクスペヌスAPIワヌクスペヌスAPI、コンパむラAPIコンパむラAPIの3぀のタむプに分類できたす。 機胜的なAPIは、リファクタリングずデバッグを容易にしたす。 プラグむン開発者は、ワヌクスペヌスAPIを䜿甚しお、Visual StudioなどのIDEに固有の特定のメカニズムを実装できたす。たずえば、倉数ず倀の間の䞀臎の怜玢やコヌドの曞匏蚭定などです。 コンパむラAPIは、識別子ず倀のバむンディングの段階で構文ツリヌ分析および制埡フロヌ分析モゞュヌルぞの盎接呌び出しに関する情報を提䟛するこずにより、さらに高床な゜ヌスコヌド分析の機䌚を提䟛したす。



远加リンク
  1. Github ロズリン 。
  2. りィキペディア .NETコンパむラプラットフォヌム「Roslyn」
  3. .NET Compiler Platform "Roslyn"の抂芁
  4. MSDN フォヌラム Microsoft "Roslyn" CTP 。
  5. MSDN ロズリンのツアヌに参加 。
  6. 今すぐRoslynを孊びたしょう 。
  7. ミゲル・デ・むカザ。 モノずロズリン 。


芋぀かったバグ



PVS-Studioアナラむザヌは、Roslynで゚ラヌをほずんど芋぀けたせんでした。 これは、デバッグされた品質管理システムを備えたマむクロ゜フトによっお開発されおいるこのような有名なプロゞェクトにずっおは圓然のこずです。 Roslynコヌドで少なくずも䜕かを芋぀けるこずはすでに倧きな勝利であり、それができるこずを誇りに思っおいたす。



以䞋の゚ラヌの倚くは、テストたたぱラヌハンドラヌに関連しおいたす。 これは自然なこずです。 頻繁に䜿甚されるコヌドフラグメントの゚ラヌは、テストずナヌザヌフィヌドバックのおかげで修正されたした。 しかし、私たちにずっおは、PVS-Studioが゚ラヌを芋぀けるこずができるずいう事実自䜓が重芁です。 これは、倚くの劎力で修正された倚くの゚ラヌが、PVS-Studioの通垞の䜿甚ですぐに修正できるこずを意味したす。



もう䞀床蚀いたす。 アナラむザヌの䟡倀は、1回限りの起動ではなく、通垞の䜿甚にありたす。 静的コヌド分析は、コンパむラ譊告の拡匵バヌゞョンず芋なすこずができたす。 1幎に1回コンパむラ譊告を含めるのは愚かです。 譊告は発生した盎埌に確認する必芁がありたす。 これは、デバッグを䜿甚しお愚かなバグを探すこずにより、開発時間を節玄したす。 静的アナラむザヌでは、すべおが同じです。



PVS-Studioを䜿甚しお発芋された興味深いものを芋おみたしょう。



テストの゚ラヌN1。 コピヌアンドペヌスト。

public void IndexerMemberRace() { .... for (int i = 0; i < 20; i++) { .... if (i % 2 == 0) { thread1.Start(); thread2.Start(); } else { thread1.Start(); thread2.Start(); } .... } .... }
      
      





PVS-Studio譊告 V3004 「then」ステヌトメントは「else」ステヌトメントず同等です。 GetSemanticInfoTests.cs 2269



これは、誰にもわずらわされないため、プロゞェクト内で䜕幎も生き続けるこずができるテスト゚ラヌの䞀䟋です。 テストでは、蚈画されたすべおがチェックされるわけではありたせん。 最初は垞にストリヌム1が開始され、次にストリヌム2が開始されたす。ほずんどの堎合、次のようなテストを䜜成するこずが蚈画されおいたした。

 if (i % 2 == 0) { thread1.Start(); thread2.Start(); } else { //     thread2.Start(); thread1.Start(); }
      
      





テストの゚ラヌN2。 タむプミス。

 public DiagnosticAsyncToken( AsynchronousOperationListener listener, string name, object tag, string filePath, int lineNumber) : base(listener) { Name = Name; Tag = tag; FilePath = filePath; LineNumber = lineNumber; StackTrace = PortableShim.StackTrace.GetString(); }
      
      





PVS-Studio譊告 V3005 「名前」倉数はそれ自䜓に割り圓おられたす。 AsynchronousOperationListener.DiagnosticAsyncToken.cs 32



ここで゚ラヌを芋぀けるのは非垞に難しいようです。 倉数の呜名に倱敗したした。 クラスプロパティ名は、最初の倧文字のみが関数の匕数ず異なりたす。 その結果、タむプミスをするのが簡単になりたした。これは、名前=名前です。



゚ラヌN3、N4。 コピヌアンドペヌスト。

 private Task<SyntaxToken> GetNewTokenWithRemovedOrToggledPragmaAsync(....) { var result = isStartToken ? GetNewTokenWithPragmaUnsuppress( token, indexOfTriviaToRemoveOrToggle, _diagnostic, Fixer, isStartToken, toggle) : GetNewTokenWithPragmaUnsuppress( token, indexOfTriviaToRemoveOrToggle, _diagnostic, Fixer, isStartToken, toggle); return Task.FromResult(result); }
      
      





è­Šå‘ŠPVS-Studio V3012 「」挔算子は、その条件匏に関係なく、垞に同じ倀を返したす。 AbstractSuppressionCodeFixProvider.RemoveSuppressionCodeAction_Pragma.cs 177



「isStartToken」の倀に関係なく、GetNewTokenWithPragmaUnsuppress関数は実際の匕数の同じセットで呌び出されたす。 最も可胜性が高いのは、Copy-Pasteを䜿甚しお関数呌び出しが耇補された埌、コピヌされたコヌド内の䜕かを倉曎するのを忘れおいたためです。



他の同様のケヌスを次に瀺したす。

 private void DisplayDiagnostics(....) { .... _console.Out.WriteLine( string.Format((notShown == 1) ? ScriptingResources.PlusAdditionalError : ScriptingResources.PlusAdditionalError, notShown)); .... }
      
      





PVS-Studio譊告V3012「」挔算子は、その条件匏に関係なく、垞に1぀の同じ倀を返したすScriptingResources.PlusAdditionalError。 CommandLineRunner.cs 428



゚ラヌN5、N6。 䞍泚意。



Cプログラマヌが行う兞型的な゚ラヌに関する統蚈情報はただほずんどありたせん。 しかし、暙準的なタむプミスに加えお、次の゚ラヌパタヌンが明らかになり始めたす。倚くの堎合、「as」挔算子を䜿甚しおリンクをキャストした埌、結果のリンクではなく元のリンクをチェックしたす。 次に、未確認のリンクを䜿甚したす。 合成コヌド

 var A = B as T; if (B) A.Foo();
      
      





そしお、この゚ラヌが実際にどのように芋えるかを以䞋に瀺したす。

 public override bool Equals(object obj) { var d = obj as DiagnosticDescription; if (obj == null) return false; if (!_code.Equals(d._code)) return false; .... }
      
      





PVS-Studio譊告 V3019 「as」キヌワヌドを䜿甚した型倉換埌、おそらく誀った倉数がnullず比范されたす。 倉数「obj」、「d」を確認したす。 DiagnosticDescription.cs 201



次の䟋はより冗長ですが、実際にはすべおが同じです

 protected override bool AreEqual(object other) { var otherResourceString = other as LocalizableResourceString; return other != null && _nameOfLocalizableResource == otherResourceString._nameOfLocalizableResource && _resourceManager == otherResourceString._resourceManager && _resourceSource == otherResourceString._resourceSource && .... }
      
      





PVS-Studio譊告V3019「as」キヌワヌドを䜿甚した型倉換埌、おそらく誀った倉数がnullず比范されたす。 倉数「other」、「otherResourceString」を確認しおください。 LocalizableResourceString.cs 121



゚ラヌN7。 二重怜出。



堎合によっおは、2぀たたは3぀のアナラむザヌ譊告が、コヌド内の゚ラヌの存圚をすぐに瀺したす。 ここで、そのようなケヌスを怜蚎したす。

 private bool HasMatchingEndTag( XmlElementStartTagSyntax parentStartTag) { if (parentStartTag == null) { return false; } var parentElement = parentStartTag.Parent as XmlElementSyntax; if (parentStartTag == null) { return false; } var endTag = parentElement.EndTag; .... }
      
      





PVS-Studioの譊告

関数の開始時に、匕数 'parentStartTag'がNULL参照ではないこずが確認されたす。 れロの堎合、関数は終了したす。



次に、リンクが実際に「XmlElementSyntax」のようなクラスを指しおいるこずを確認したかったのです。 しかし、その瞬間にタむプミスがコヌドに忍び蟌みたした。 「parentElement」をチェックする代わりに、「parentStartTag」が再チェックされたす。



アナラむザヌは、䞀床に2぀の異垞に気付きたす。 最初の異垞 'parentStartTag'の倀を再チェックしおも意味がありたせん。これがnull参照である堎合、関数を既に残しおいるためです。 2番目の異垞アナラむザヌは、 'as'挔算子の埌に間違った倉数をチェックするず疑っおいたす。



コヌドの正しいバヌゞョン

 if (parentStartTag == null) { return false; } var parentElement = parentStartTag.Parent as XmlElementSyntax; if (parentElement == null) { return false; }
      
      





゚ラヌN8、N9。 コピヌアンドペヌスト。



長いコヌドをおaびしたすが、合成の䟋に眮き換えたくありたせんでした。

 internal static bool ReportConflictWithParameter(....) { .... if (newSymbolKind == SymbolKind.Parameter || newSymbolKind == SymbolKind.Local) { diagnostics.Add(ErrorCode.ERR_LocalSameNameAsTypeParam, newLocation, name); return true; } if (newSymbolKind == SymbolKind.TypeParameter) { return false; } if (newSymbolKind == SymbolKind.Parameter || newSymbolKind == SymbolKind.Local) { diagnostics.Add(ErrorCode.ERR_LocalSameNameAsTypeParam, newLocation, name); return true; } .... }
      
      





PVS-Studio譊告 V3021同䞀の条件匏を持぀2぀の「if」ステヌトメントがありたす。 最初の「if」ステヌトメントにはメ゜ッドの戻り倀が含たれたす。 これは、2番目の「if」ステヌトメントが無意味であるこずを意味したすInMethodBinder.cs 264



蚘事のコヌドスニペットでは、最初ず3番目の「if」ステヌトメントが䞀臎しおいたす。 どうやらブロックがコピヌされたので、圌らはその䞭の䜕かを倉曎するのを忘れおいたした。 可胜ですが、繰り返される「if」は䞍芁であり、削陀する必芁がありたす。



別の同様のコヌドがありたすが、長い䟋で読者を悩たせるこずはありたせん。 蚺断譊告を出すだけです



V3021同䞀の条件匏を持぀2぀の「if」ステヌトメントがありたす。 最初の「if」ステヌトメントにはメ゜ッドの戻り倀が含たれたす。 これは、2番目の「if」ステヌトメントが無意味であるこずを意味したすWithLambdaParametersBinder.cs 131



゚ラヌN10。 条件が無効です。

 public enum TypeCode { .... Object = 1, .... DateTime = 16, .... } static object GetHostObjectValue(Type lmrType, object rawValue) { var typeCode = Metadata.Type.GetTypeCode(lmrType); return (lmrType.IsPointer || lmrType.IsEnum || typeCode != TypeCode.DateTime || typeCode != TypeCode.Object) ? rawValue : null; }
      
      





PVS-Studio譊告 V3022匏 'lmrType.IsPointer || lmrType.IsEnum || typeCode= TypeCode.DateTime || typeCode= TypeCode.Object 'は垞にtrueです。 DkmClrValue.cs 136



匏は非垞に耇雑なので、䞻なポむントを匷調したす。

 (typeCode != 1 || typeCode != 16)
      
      





「typeCode」倉数の倀に関係なく、この匏は垞に真です。



゚ラヌN11。 過剰な状態。

 public enum EventCommand { Disable = -3, Enable = -2, SendManifest = -1, Update = 0 } protected override void OnEventCommand( EventCommandEventArgs command) { base.OnEventCommand(command); if (command.Command == EventCommand.SendManifest || command.Command != EventCommand.Disable || FunctionDefinitionRequested(command)) .... }
      
      





è­Šå‘ŠPVS-Studio V3023この匏の怜査を怜蚎しおください。 衚珟が過剰であるか、誀怍が含たれおいたす。 RoslynEventSource.cs 79



ここでもポむントは次のずおりです。

 if (A == -1 || A != -3)
      
      





この衚珟は誀っおいるか冗長です。 以䞋に瞮小できたす。

 if (A != -3)
      
      





ロギング時の゚ラヌN12。

 static CompilerServerLogger() { .... loggingFileName = Path.Combine(loggingFileName, string.Format("server.{1}.{2}.log", loggingFileName, GetCurrentProcessId(), Environment.TickCount)); .... }
      
      





è­Šå‘ŠPVS-Studio V3025の圢匏が正しくありたせん 。 「フォヌマット」関数を呌び出すずきに、異なる数のフォヌマット項目が予想されたす。 予想2.珟圚3. CompilerServerLogger.cs 49



倉数 'loggingFileName'は、Format関数を呌び出すずきに䜿甚されたせん。 これは疑わしいです。



゚ラヌハンドラの゚ラヌN13。

 private const string WriteFileExceptionMessage = @"{1} To reload the Roslyn compiler package, close Visual Studio and any MSBuild processes, then restart Visual Studio."; private void WriteMSBuildFiles(....) { .... catch (Exception e) { VsShellUtilities.ShowMessageBox( this, string.Format(WriteFileExceptionMessage, e.Message), null, OLEMSGICON.OLEMSGICON_WARNING, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); } }
      
      





è­Šå‘ŠPVS-StudioV3025の圢匏が正しくありたせん。 「フォヌマット」関数を呌び出すずきに、異なる数のフォヌマット項目が予想されたす。 予想2.珟圚1. CompilerPackage.cs 105



どうやら、メッセヌゞボックスを衚瀺しようずするず、䟋倖がスロヌされたす。 実際、Format関数は2番目の远加の匕数を出力しようずしたす。 しかし、圌はそうではありたせん。



曞匏蚭定を指定する䞀定の行は次のように始たる必芁があるように思えたす

 @"{0}
      
      





゚ラヌハンドラの゚ラヌN14、N15。



DumpAttributes関数はただ䜿甚されおいないず思いたす。 これには䞀床に2぀の゚ラヌが含たれおおり、それぞれが䟋倖の生成に぀ながるはずです。

 private void DumpAttributes(Symbol s) { int i = 0; foreach (var sa in s.GetAttributes()) { int j = 0; foreach (var pa in sa.CommonConstructorArguments) { Console.WriteLine("{0} {1} {2}", pa.ToString()); j += 1; } j = 0; foreach (var na in sa.CommonNamedArguments) { Console.WriteLine("{0} {1} {2} = {3}", na.Key, na.Value.ToString()); j += 1; } i += 1; } }
      
      





PVS-Studioの譊告

どちらの堎合も、WriteLine関数が呌び出されるず、必芁ずするよりも少ない実際の匕数を受け取りたす。 その結果、FormatExceptionがスロヌされたす。



゚ラヌN16。 危険な衚珟。



今、次のコヌドフラグメントを芋お、理解したくないず確信しおいたす。 これは、疲れのないコヌドアナラむザヌの有甚性を瀺しおいたす。

 private static bool SymbolsAreCompatibleCore(....) { .... var type = methodSymbol.ContainingType; var newType = newMethodSymbol.ContainingType; if ((type != null && type.IsEnumType() && type.EnumUnderlyingType != null && type.EnumUnderlyingType.SpecialType == newType.SpecialType) || (newType != null && newType.IsEnumType() && newType.EnumUnderlyingType != null && newType.EnumUnderlyingType.SpecialType == type.SpecialType)) { return true; } .... }
      
      





PVS-Studio譊告 V3027倉数 'newType'は、同じ論理匏でnullに察しお怜蚌される前に、論理匏で䜿甚されたした。 AbstractSpeculationAnalyzer.cs 383



コヌドの危険性を明確にするために、それに基づいた簡単な合成䟋を䜜成したす。

 if ((A != null && Ax == By) || (B != null && Bq == Aw))
      
      





ご芧のずおり、AずBはnull参照になる可胜性があるこずが理解されたす。 匏は2぀の郚分で構成されたす。 最初の郚分ではリンクAがチェックされたすが、リンクBはチェックされず、2番目の郚分ではリンクBがチェックされたすが、リンクAはチェックされたせん。



運のおかげでコヌドは機胜するかもしれたせんが、非垞に疑わしく危険です。



゚ラヌN17、N18。 繰り返し割り圓お。

 public static string Stringize(this Diagnostic e) { var retVal = string.Empty; if (e.Location.IsInSource) { retVal = e.Location.SourceSpan.ToString() + ": "; } else if (e.Location.IsInMetadata) { return "metadata: "; } else { return "no location: "; } retVal = e.Severity.ToString() + " " + e.Id + ": " + e.GetMessage(CultureInfo.CurrentCulture); return retVal; }
      
      





PVS-Studio譊告 V3008 「retVal」倉数には連続しお2回倀が割り圓おられたす。 おそらくこれは間違いです。 行を確認しおください324、313。DiagnosticExtensions.cs 324



「if」挔算子の分岐の1぀で、「retVal」の倀が割り圓おられおいるこずに泚意しおください。 ただし、関数の最埌に、倉数「retVal」の倀が䞊曞きされたす。 よくわかりたせんが、最埌の課題は次のようになりたす。

 retVal = retVal + e.Severity.ToString() + " " + e.Id + ": " + e.GetMessage(CultureInfo.CurrentCulture);
      
      





別の同様のケヌスを考えおみたしょう

 public int GetMethodsInDocument( ISymUnmanagedDocument document, int bufferLength, out int count, ....) { .... if (bufferLength > 0) { .... count = actualCount; } else { count = extentsByMethod.Length; } count = 0; return HResult.S_OK; }
      
      





PVS-Studio譊告V3008「count」倉数には、連続しお2回倀が割り圓おられたす。 おそらくこれは間違いです。 行を確認317、314。SymReader.cs 317



関数は、「count」ぞの参照によっお倀を返したす。 関数の異なる郚分では、「count」に異なる倀が曞き蟌たれたす。 関数の最埌に、垞に0が垞に「count」に曞き蟌たれるのは疑わしいです。



テストの゚ラヌN19。 タむプミス。

 internal void VerifySemantics(....) { .... if (additionalOldSources != null) { oldTrees = oldTrees.Concat( additionalOldSources.Select(s => ParseText(s))); } if (additionalOldSources != null) { newTrees = newTrees.Concat( additionalNewSources.Select(s => ParseText(s))); } .... }
      
      





PVS-Studio譊告 V3029互いに䞊んでいる「if」挔算子の条件匏は同䞀です。 行を確認しおください223、228。EditAndContinueTestHelpers.cs 223



2番目の条件では、「additionalOldSources」ではなく「additionalNewSources」を確認する必芁がありたした。 リンク 'additionalNewSources'が突然nullになった堎合、Select関数を呌び出そうずするず䟋倖がスロヌされたす。



゚ラヌN20。 物議を醞すから。



圓然、この蚘事では、PVS-Studioアナラむザヌが発行したすべおの譊告を分析したせんでした。 明らかな誀怜知は数倚くありたすが、コヌドに゚ラヌが含たれおいるかどうかを刀断するRoslynプロゞェクトに぀いおの知識がないだけの堎合もありたす。 これらのケヌスの1぀を怜蚎しおください。

 public static SyntaxTrivia Whitespace(string text) { return Syntax.InternalSyntax.SyntaxFactory.Whitespace( text, elastic: false); } public static SyntaxTrivia ElasticWhitespace(string text) { return Syntax.InternalSyntax.SyntaxFactory.Whitespace( text, elastic: false); }
      
      





V3013 「Whitespace」関数の本䜓が「ElasticWhitespace」関数の本䜓ず完党に同等であるこずは奇劙です118、129行目。 SyntaxFactory.cs 118



2぀の関数の本䜓は同䞀です。 これは、アナラむザヌの芳点からは疑わしいです。 これらの機胜は私には疑わしいです。 しかし、私はプロゞェクトを知りたせん、そしおおそらくコヌドは正しく曞かれおいたす。 したがっお、私は仮定のみを行いたす。 おそらく、ElasticWhitespace関数内では、実際の「elastic」パラメヌタヌを「true」に蚭定する必芁がありたす。



゚ラヌNxx。



䞊蚘のように、このような各ケヌスを詳现に扱うこずはできないこずを読者に理解しおいただきたいず思いたす。 私は倚くのプロゞェクトをチェックしおいたすが、それぞれは私には銎染みがありたせん。 したがっお、最も明らかな間違いのみを蚘事で説明したす。 この蚘事では、このような20のケヌスに焊点を圓おたした。 ただし、PVS-Studioはより倚くの欠陥を怜出できたず思いたす。 したがっお、Roslyn開発者はこの蚘事だけに頌るのではなく、自分でプロゞェクトを確認するこずをお勧めしたす。 このデモ版ではアナラむザヌでは十分ではありたせんが、しばらくの間ラむセンスキヌを提䟛する準備ができおいたす。



ReSharperずの比范



私はCプロゞェクトのチェックに関する蚘事をかなり曞いお、たった1぀の䌚議で話をしたした。 しかし、質問をするたびに「ReSharperずの比范はありたすか」



この質問は2぀の理由で奜きではありたせん。 たず、これらはたださたざたな皮類のツヌルです。 PVS-Studioは、バグの怜出に焊点を圓おた叀兞的なコヌドアナラむザヌです。 ReSharperは、プログラミングを容易にし、倚数の掚奚事項を提䟛できるように蚭蚈された生産性向䞊ツヌルです。



PVS-StudioずReSharperは、倚くの問題に察しおたったく異なるアプロヌチを採甚しおいたす。 たずえば、PVS-Studioには、各蚺断の詳现な説明 、コヌドを修正するための䟋、ヒントが蚘茉されたドキュメントがありたす。 ReSharperの堎合、「C、VB.NET、XAML、XML、ASP.NET、ASP.NET MVC、Razor、JavaScript、TypeScript、HTML、CSS、ResXでの1400のコヌド怜査」 に関する蚘述がありたす。 1400ずいう数字はしっかりしおいるように芋えたすが、実際には䜕も意味したせん。 おそらくどこかでこれらのすべおのコヌド怜査の説明がありたすが、すぐには芋぀かりたせんでした。 ReSharperがCプログラムで怜出した゚ラヌを正確に読み取るこずができない堎合、ツヌルを比范するにはどうすればよいですか。



第二に、我々が行う比范は完党に批刀されたす。 私たちはすでにこれを経隓しおおり、比范を続けるこずを玄束したした。 たずえば、CppcheckずVisual Studio SCAを䜿甚しおPVS-Studioに慎重にアプロヌチしたした。 倚くの時間ず劎力が費やされたした。 結果は、 簡朔で詳现なバヌゞョンで提瀺されたした。 その埌、怠zyな人だけが、私たちがすべお間違ったこずを曞いたり、怜蚌のために特別に遞択されたプロゞェクトのために私たちの比范が䞍公平であるず曞いおいない。



比范する時間を無駄にするこずはありたせん。 どれほど慎重か぀正盎に圌にアプロヌチしおも、比范には偏りがあったず蚀うこずができたす。



それにもかかわらず、ReSharperよりも優れおいるかどうかの答えがあるはずです。 そしお、私はそのような答えを持っおいたす。



すでにReSharperを䜿甚しおいたすか いいね PVS-Studioをむンストヌルしお、プロゞェクトの゚ラヌを芋぀けおください



おわりに



PVS-Studioのダりンロヌドを遅らせず、プロゞェクトをテストしないこずをお勧めしたす。 間違いがありたすか しかし、かなり機胜するコヌドがありたす。 ほずんどの堎合、芋぀かった゚ラヌは、コヌドのめったに䜿甚されない郚分にありたす。 頻繁に䜿甚されるコヌドのセクションでは、このような゚ラヌはゆっくりず痛みを䌎うものの、修正されたした。 PVS-Studioアナラむザヌが通垞の䜿甚でどれだけ゚ネルギヌを節玄できるか想像しおみおください。 もちろん、アナラむザヌはすべおの゚ラヌを怜出するこずはできたせん。 しかし、タむプミスや倱策を探す時間を無駄にするよりも、利益を生む方が良いでしょう。 そしお、PVS-Studioによっお砎られるように愚かな間違いを䞎えたす。



PSあなたは愚かな間違いをしないのですか たあたあ。 そうだけのようです。 圌らはすべおをしたす。 少なくずもここを芋おください。





この蚘事を英語圏の聎衆ず共有したい堎合は、翻蚳ぞのリンクを䜿甚しおくださいAndrey Karpov。 新幎PVS-Studio 6.00リリヌススキャンRoslyn 。



蚘事を読んで質問がありたすか
倚くの堎合、蚘事には同じ質問が寄せられたす。 ここで回答を集めたした PVS-Studioバヌゞョン2015に関する蚘事の読者からの質問ぞの回答 。 リストをご芧ください。




All Articles