![PVS-Studio 6.00ãCãC ++ãCïŒ](https://habrastorage.org/getpro/habr/post_images/2b4/015/69c/2b401569c34fa7c9d8ff4156eca22a66.png)
åŸ æã®ã€ãã³ããå°çããŸããã 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ã¯ãèå¥åãšå€ã®ãã€ã³ãã£ã³ã°ã®æ®µéã§æ§æããªãŒåæããã³å¶åŸ¡ãããŒåæã¢ãžã¥ãŒã«ãžã®çŽæ¥åŒã³åºãã«é¢ããæ å ±ãæäŸããããšã«ãããããã«é«åºŠãªãœãŒã¹ã³ãŒãåæã®æ©äŒãæäŸããŸãã
è¿œå ãªã³ã¯ïŒ
- Github ããºãªã³ ã
- ãŠã£ãããã£ã¢ .NETã³ã³ãã€ã©ãã©ãããã©ãŒã ïŒãRoslynãïŒ
- .NET Compiler PlatformïŒ "Roslyn"ïŒã®æŠèŠ
- MSDN ãã©ãŒã©ã Microsoft "Roslyn" CTP ã
- MSDN ããºãªã³ã®ãã¢ãŒã«åå ã
- ä»ããRoslynãåŠã³ãŸããã ã
- ãã²ã«ã»ãã»ã€ã«ã¶ã ã¢ããšããºãªã³ ã
èŠã€ãã£ããã°
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ã®èŠåïŒ
- V3019 ãasãããŒã¯ãŒãã䜿çšããåå€æåŸã«ã誀ã£ãå€æ°ãnullãšæ¯èŒãããå¯èœæ§ããããŸãã å€æ°ãparentStartTagãããparentElementãã確èªããŠãã ããã XmlTagCompletionCommandHandler.cs 123
- V3021åäžã®æ¡ä»¶åŒãæã€2ã€ã®ãifãã¹ããŒãã¡ã³ãããããŸãã æåã®ãifãã¹ããŒãã¡ã³ãã«ã¯ã¡ãœããã®æ»ãå€ãå«ãŸããŸãã ããã¯ã2çªç®ã®ãifãã¹ããŒãã¡ã³ããç¡æå³ãªXmlTagCompletionCommandHandler.csã§ããããšãæå³ããŸã117
é¢æ°ã®éå§æã«ãåŒæ° '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ã®èŠåïŒ
- V3025圢åŒãæ£ãããããŸããã ãWriteLineãé¢æ°ã®åŒã³åºãäžã«ãç°ãªãæ°ã®ãã©ãŒãããé ç®ãäºæãããŸãã äºæ³ïŒ3.çŸåšïŒ1. LoadingAttributes.cs 551
- V3025圢åŒãæ£ãããããŸããã ãWriteLineãé¢æ°ã®åŒã³åºãäžã«ãç°ãªãæ°ã®ãã©ãŒãããé ç®ãäºæãããŸãã äºæ³ïŒ4.çŸåšïŒ2. LoadingAttributes.cs 558
ã©ã¡ãã®å Žåãã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ã«é¢ããèšäºã®èªè
ããã®è³ªåãžã®åç ã ãªã¹ããã芧ãã ããã