IronPythonããã³IronRuby
IronPythonãšIronRubyã¯ãäž¡æ¹ãšã.NETãšPythonããã³Rubyããã°ã©ãã³ã°èšèªã®Pythonå®è£ ã§ãã ãããã®ãããžã§ã¯ãã®ãœãŒã¹ã³ãŒãã¯ããã®ãªã³ã¯ã® GitHubã§å ¥æã§ããŸãã DLRãœãŒã¹ã³ãŒããå«ãŸããŠããŸãã .NET Framework 4.0以éãDLRã¯ãã®äžéšã§ãããIronPythonãšIronRubyã䜿çšããŠããŸãã ããã«ããããããã圌女ãããã®ã§ãç§ã¯ãŸã å€ãããŒãžã§ã³ã®DLRããã§ãã¯ããŸããã
ãããžã§ã¯ãã®æ€èšŒã«ã€ããŠ
ãããã£ãŠãã³ãŒãå šäœã¯ãDLRãIronPythonãIronRubyã®3ã€ã®å€§ããªéšåã§æ§æããã1630 * .csãã¡ã€ã«ãå«ãŸããŠããŸãã æ€èšŒã®ããã«ãç§ãã¡ã®ãŠã§ããµã€ãããããŠã³ããŒãã§ããPVS-Studio 6.00ã䜿çšããŸããã 決å®ã®æ€èšŒã«ã¯1å以äžããããŸããã ãã®çµæãåæè£ çœ®ã¯ãæåã®34åã®èŠåã2çªç®ã®15åã®èŠåãããã³3çªç®ã®ã¬ãã«ã®280åã®èŠåãçºè¡ããŸããã
æåã®ã¬ãã«ã§ã¯ã34ã®èŠåã®ãã¡ã19ãæ¬åœã®ééãã§ããããšãå€æããŸãã-ããªãè¯ãçµæã§ã6ç®æãçããããšæãããŸã-ããªãã¯ãããã«æ³šæãæãå¿ èŠããããŸãã æ®ãã®9ã€ã®ã¡ãã»ãŒãžã¯èª€æ€ç¥ã§ããããã®ãã¡ã®ååã¯ã¢ãã©ã€ã¶ãŒèªäœãç·šéããããšã§é€å»ã§ããŸãããè¿ããã¡ã«è¡ããŸãã
2çªç®ãš3çªç®ã®ã¬ãã«ã®ãšã©ãŒãšçãããå Žæã¯ãå€§å¹ ã«å°ãªããªããŸããã
èŠã€ãã£ããã°
PVS-Studioã§èŠã€ãã£ãå®éã®ãšã©ãŒã®äŸãèŠãŠã¿ãŸãããã
äŸ1ããã³2ãäžæ³šæã
private bool Enter(RangeExpression/*!*/ node, bool isCondition) { .... if (!isCondition && litBegin != null && litEnd != null && litBegin.Value is int && litBegin.Value is int) { _result = MakeNode(NodeKind.lit, new Range( (int)litBegin.Value, (int)litEnd.Value, node.IsExclusive)); } else { .... } .... }
PVS-StudioèŠåïŒ V3001 ã&&ãæŒç®åã®å·Šå³ã«ã¯ããlitBegin.Value is intããšåãå¯æ¬¡åŒããããŸãã IronRubyParseTreeOps.cs 277
æ¡ä»¶ã¯ãlitEnd.Valueããã§ãã¯ããã®ã§ã¯ãªããlitBegin.Valueãintåã§ããããšãäºéã«ãã§ãã¯ããŸãã
åãåŒã®åæ§ã®ãã§ãã¯ããããšãã°æ¬¡ã®2ã€ã®å Žæã«ãããŸãã
private static PythonTuple ReduceProtocol2( CodeContext/*!*/ context, object self) { .... if (self is PythonDictionary || self is PythonDictionary) { dictIterator = PythonOps.Invoke(context, self, "iteritems", ArrayUtils.EmptyObjects); } .... }
PVS-StudioèŠåïŒ V3001 ã||ãã®å·Šå³ã«ãself is PythonDictionaryããšåãå¯æ¬¡åŒããããŸã æŒç®åã IronPython ObjectOps.cs 452
äŸ3.åãåŒã
protected override MSAst.Expression VisitTry( MSAst.TryExpression node) { .... if (newHandlers != null || newFinally != null) { node = Ast.MakeTry(node.Type, node.Body, newFinally != null ? newFinally : node.Finally, node.Fault, newHandlers != null ? newHandlers : newHandlers ); } return node; }
èŠåPVS-StudioïŒ V3012 ãïŒïŒãæŒç®åã¯ããã®æ¡ä»¶åŒã«é¢ä¿ãªããåžžã«1ã€ã®åãå€newHandlersãè¿ããŸãã DebugInfoRewriter.cs 252
ããã§ã¯ãæ¡ä»¶åŒã®äž¡æ¹ã®ãã©ã³ãã§newHandlersã䜿çšãããŠããŸãã newHandlersãnullã®å Žåãnode.Handlersã䜿çšããããšã«ãªã£ãŠããã
äŸ4ããã³5ãäžæ³šæã
public static bool HasValue(RubyContext/*!*/ context, object/*!*/ self, object value) { var strValue = value as MutableString; if (value == null) { return false; } var clrStrValue = strValue.ConvertToString(); .... }
PVS-StudioèŠåïŒ V3019 ãasãããŒã¯ãŒãã䜿çšããåå€æåŸããããã誀ã£ãå€æ°ãnullãšæ¯èŒãããŸãã å€æ°ãå€ãããstrValueãã確èªããŠãã ããã EnvironmentSingletonOps.cs 189
ããã¯ããasãæŒç®åã䜿çšããŠãã£ã¹ãããåŸããã£ã¹ãã®çµæã§ã¯ãªããœãŒã¹ãªããžã§ã¯ããäžæ³šæã§ãã§ãã¯ãããæªæ€èšŒã®åç §ã䜿çšãããå Žåã«ããããééãã§ãã
å¥ã®åæ§ã®ã±ãŒã¹ã次ã«ç€ºããŸãã
private static RubyRegex/*!*/ ConstructRubyRegexp( RubyConstructor/*!*/ ctor, Node/*!*/ node) { ScalarNode scalar = node as ScalarNode; if (node == null) { throw RubyExceptions.CreateTypeError( "Can only create regex from scalar node"); } Match match = _regexPattern.Match(scalar.Value); .... }
PVS-StudioèŠåïŒ V3019 ãasãããŒã¯ãŒãã䜿çšããåå€æåŸããããã誀ã£ãå€æ°ãnullãšæ¯èŒãããŸãã å€æ°ãnodeãããscalarãã確èªããŠãã ããã RubyConstructor.cs 230
äŸ6.ã³ããŒããŒã¹ãã
private void LoadNewObj(CodeContext/*!*/ context) { PythonTuple args = PopStack() as PythonTuple; if (args == null) { throw PythonOps.TypeError("expected second argument, got {0}", DynamicHelpers.GetPythonType(args)); } PythonType cls = PopStack() as PythonType; if (args == null) { throw PythonOps.TypeError("expected first argument, got {0}", DynamicHelpers.GetPythonType(args)); } .... }
PVS-StudioèŠåïŒ V3021åäžã®æ¡ä»¶åŒãæã€2ã€ã®ãifãã¹ããŒãã¡ã³ãããããŸãã æåã®ãifãã¹ããŒãã¡ã³ãã«ã¯ã¡ãœããã®æ»ãå€ãå«ãŸããŸãã ããã¯ã2çªç®ã®ãifãã¹ããŒãã¡ã³ããç¡æå³ã§ããããšãæå³ããŸãã cPickle.cs 2194
äžèšã®ã³ãŒãã¹ããããã§ã¯ã2ã€ã®æ¡ä»¶ãšGetPythonTypeïŒïŒé¢æ°ã®åŒã³åºãã¯ãŸã£ããåãã§ãã æããã«ã2çªç®ã®æ¡ä»¶ã¯æåã®æ¡ä»¶ãã³ããŒããããšã«ãã£ãŠååŸãããŸããããèè ã¯å€æ°ã®ååãå€æŽããã®ãå¿ããŠããŸããã ãããžã§ã¯ãã«ã¯ãåæ§ã®ç¶æ³ãããã€ããããŸãã
äŸ7.åãæ¡ä»¶ã
public static int Compare(SourceLocation left, SourceLocation right) { if (left < right) return -1; if (right > left) return 1; return 0; }
PVS-StudioèŠåïŒ V3021åäžã®æ¡ä»¶åŒãæã€2ã€ã®ãifãã¹ããŒãã¡ã³ãããããŸãã æåã®ãifãã¹ããŒãã¡ã³ãã«ã¯ã¡ãœããã®æ»ãå€ãå«ãŸããŸãã ããã¯ã2çªç®ã®ãifãã¹ããŒãã¡ã³ããç¡æå³ã§ããããšãæå³ããŸãã SourceLocation.cs 156
ãã®æ¹æ³ã¯éåžžã«ç°¡åã§ãééããç¯ãå Žæã¯ãªãããã§ãã ããã§ãã2çªç®ã®æ¡ä»¶ã§ã¯ãäœããã®çç±ã§å·Šå³ã®ãã©ã¡ãŒã¿ãŒã亀æããããããã¢ãã©ã€ã¶ãŒãæ€åºãããã®ãšåããã®ãäž¡æ¹ã®æ¡ä»¶ã§ãã§ãã¯ãããŸãã
ã³ãŒãã®æ£ããããŒãžã§ã³ïŒ
public static int Compare(SourceLocation left, SourceLocation right) { if (left < right) return -1; if (left > right) return 1; return 0; }
äŸ8.é床ã®ç¶æ ã
private void WriteSingleQuoted(string text, bool split) { .... while (ending <= text.Length) { c = '\0'; if (ending < text.Length) { c = text[ending]; } if (spaces) { if (c == 0 || c != 32) { .... }
PVS-StudioèŠåïŒ V3023 'c == 0ã®æ€æ»ãæ€èšããŠãã ãã|| cïŒ= 32 'åŒã è¡šçŸãéå°ã§ãããã誀æ€ãå«ãŸããŠããŸãã Emitter.cs 308
ãŸããå€æ°ãcãã«ããã©ã«ãå€ã\ 0ããå²ãåœãŠãããŸãã 次ã«ãæååå šäœããŸã åŠçãããŠããªãå Žåããcãã¯æ¬¡ã®æåã®å€ãååŸããŸãã ãããŠæåŸã«ãããã©ã«ãå€ãå€æ°ãcãã«æ®ã£ãŠãããã©ããããŸãã¯ã¹ããŒã¹ä»¥å€ã®ãã®ãããã«èªã¿èŸŒãŸãããã©ããããã§ãã¯ãããŸãã å®éããŒãã¯ãã§ã«32ïŒã¹ããŒã¹ã³ãŒãïŒãšã¯ç°ãªãããããŒããšã®æ¯èŒã¯ããã§ã¯äžèŠã§ãã ãã®ã³ãŒãã¯ãšã©ãŒã«ã€ãªããããšã¯ãããŸããããç解ããã®ãé£ãããªãããããŒããšã®æ¯èŒã¯ç Žæ£ãããå¯èœæ§ããããŸãã ã¢ãã©ã€ã¶ãŒã¯ããã®ãããžã§ã¯ãã§ããã«ããã€ãã®åæ§ã®è¿œå ãã§ãã¯ãèŠã€ããŸããã
äŸ9ããã³10ãç¡å¹ãªãã©ãŒãããæååã
String.Formaté¢æ°ã䜿çšããéã®äžè¬çãªåé¡ã¯ãString.Formatã«æž¡ããããã©ã¡ãŒã¿ãŒã®æ°ã«ã€ããŠããã©ãŒãããæååã®æ°ãšãã©ã¡ãŒã¿ãŒçªå·ãã³ã³ãã€ã©ãŒã«ãã£ãŠãã§ãã¯ãããªãããšã§ãã ãã®çµæã誀ã£ãæååãçæãããããFormatExceptionãã¹ããŒãããŸãã ããã€ãã®äŸãèŠãŠã¿ãŸãããã
public T Current { get { try { return (T)enumerable.Current; } catch (InvalidCastException iex) { throw new InvalidCastException(string.Format( "Error in IEnumeratorOfTWrapper.Current. Could not cast: {0} in {0}", typeof(T).ToString(), enumerable.Current.GetType().ToString()), iex); } } }
èŠåPVS-StudioïŒ V3025ã®åœ¢åŒãæ£ãããããŸãã ã ããã©ãŒããããé¢æ°ãåŒã³åºããšãã«ãç°ãªãæ°ã®ãã©ãŒãããé ç®ãäºæ³ãããŸãã äºæ³ïŒ1.çŸåšïŒ2. ConversionWrappers.cs 235
ãã®äŸã§ã¯ãæåŸã®ãã©ã¡ãŒã¿ãŒã¯äœ¿çšãããã代ããã«å€typeofïŒTïŒ.ToStringïŒïŒã2å衚瀺ãããŸãã
private static void DumpGenericParameters( MetadataTableView genericParams, MetadataRecord owner) { foreach (GenericParamDef gp in genericParams) { _output.WriteLine(" generic parameter #{0}: {1}", gp.Index, gp.Name, gp.Attributes); .... }
èŠåPVS-StudioïŒ V3025ã®åœ¢åŒãæ£ãããããŸãã ã ãWriteLineãé¢æ°ã®åŒã³åºãäžã«ãç°ãªãæ°ã®ãã©ãŒãããé ç®ãäºæãããŸãã äºæ³ïŒ2.çŸåšïŒ3. Program.cs 268
ãŸãããã®ã³ãŒããã©ã°ã¡ã³ãã§ã¯ããã©ãŒãããæååãå¿ èŠãšãããã©ã¡ãŒã¿ãŒããã1ã€å€ãã®ãã©ã¡ãŒã¿ãŒãWriteLineé¢æ°ã«æž¡ãããŸãã
äŸ11.ã¢ã¯ã»ã¹åŸã®nullã®ç¢ºèªã
public static MutableString ChompInPlace(....) { MutableString result = InternalChomp(self, separator); if (result.Equals(self) || result == null) { self.RequireNotFrozen(); return null; } .... }
PVS-StudioèŠåïŒ V3027å€æ° 'result'ã¯ãåãè«çåŒã§nullã«å¯ŸããŠæ€èšŒãããåã«ãè«çåŒã§äœ¿çšãããŸããã MutableStringOps.cs 1097
ãã®ç¶æ ã§ã¯ãnullãã§ãã¯ã亀æããŠEqualsã¡ãœãããåŒã³åºãå¿ èŠããããŸãã çŸåšã®ãšãããã¢ããªã±ãŒã·ã§ã³ã¯NullReferenceExceptionã§ã¯ã©ãã·ã¥ããå¯èœæ§ããããŸãã
äŸ12.åæã®åé¡ã
class DictThreadGlobalState { public int DoneCount; .... } private static void RunThreadTest(DictThreadGlobalState globalState) { .... globalState.DoneEvent.Reset(); globalState.Event.Set(); while (globalState.DoneCount != 0) { // wait for threads to get back to finish } .... }
PVS-StudioèŠåïŒ V3032ãã®åŒã§åŸ æ©ããããšã¯ãã³ã³ãã€ã©ãããã€ãã®å€æ°ãæé©åããå¯èœæ§ããããããä¿¡é Œã§ããŸããã ãããåé¿ããã«ã¯ãæ®çºæ§å€æ°ãŸãã¯åæããªããã£ãã䜿çšããŸãã EngineTest.cs 2558
ãã®ã³ãŒãã«ã¯ãåžžã«çºçãããšã¯éããªããšã©ãŒãå«ãŸããŠããŸãããã©ã³ã¿ã€ã ã.NET Frameworkã®ããŒãžã§ã³ãã·ã¹ãã å ã®ããã»ããµæ°ããŸãã¯ãã®ä»ã®å®è£ ã®è©³çŽ°ã«ãã£ãŠç°ãªããŸãã ãã®ãããªãšã©ãŒãèŠã€ããã®ã¯éåžžã«å°é£ã§ãã ãã®çç±ã¯ãDoneCountå€æ°ãvolatile宣èšãããŠããªãå Žåãã³ã³ãã€ã©ãŒã¯ããã1ã€ã®ã¹ã¬ããã§ã®ã¿äœ¿çšãããŠãããšèããŠããããã§ããããšãã°ããã®å€æ°ã¯ã«ãŒãå ã§å€æŽãããªãã®ã§ããã£ãã·ã¥ããåžžã«éä¿¡ããã³éä¿¡ã§ããŸãã ããããç§ãã¡ã®å Žåããã®å€ã¯å¥ã®ã¹ã¬ããã§å€åããããããã®ãããªå Žåãå€æ°ã䜿çšããŠã¹ã¬ãããåæããå ŽåãvolatileãšããŠå®£èšããå¿ èŠããããŸãã 詳现ã«ã€ããŠã¯ã MSDNãã芧ãã ããã
äŸ13.äºéå²ãåœãŠ
private static Dictionary<string, EncodingInfoWrapper> MakeCodecsDict() { .... switch (normalizedName) { case "iso_8859_1": d["8859"] = d["latin_1"] = d["latin1"] = d["iso 8859_1"] = d["iso8859_1"] = d["cp819"] = d["819"] = d["latin"] = d["latin1"] = d["l1"] = encs[i]; break; .... }
PVS-StudioèŠåïŒ V3005 'd ["latin1"]'å€æ°ã¯ããèªäœã«å²ãåœãŠãããŸãã StringOps.cs 1905
ãã®ã³ãŒãã¯ãå€ãå€æ°d ["latin1"]ã«2åå²ãåœãŠãŸãã ã»ãšãã©ã®å Žåãããã¯åãªãã³ãŒãã§ããããšã©ãŒã§ã¯ãããŸããã ãããã圌ãã¯ããã€ãã®ã³ãŒãããŒãžãå¿ããã®ãããããŸããã ãããã«ãããäžèŠã®äŸ¡å€ããããŸãã
äŸ14.笊å·ãªãå€æ°ãšãŒãã®æ¯èŒ
public static int __hash__(UInt64 x) { int total = unchecked((int) (((uint)x) + (uint)(x >> 32))); if (x < 0) { return unchecked(-total); } return total; }
PVS-Studio èŠå ïŒ V3022åŒ 'x <0'ã¯åžžã«falseã§ãã 笊å·ãªãã®åã®å€ã¯ãåžžã«0以äžã§ããIntOps.Generated.cs1967
ããããããxãããŒããšæ¯èŒããã®ã§ã¯ãªãããåèšããæ¯èŒããå¿ èŠããã£ãã®ã§ãããããxãã䜿çšããŠäœããã®ã¢ã¯ã·ã§ã³ãå®è¡ããç¹æ®ãªã±ãŒã¹ããã§ãã¯ããã®ã¯å¥åŠã ããã§ãã ã¯ãããåèšãã«ã¯ç¬Šå·ä»ãã¿ã€ããããããããåèš<0ããšããæ¯èŒã¯ããè«ççã«èŠããŸãã
äŸ15.åäžã®ãã§ãã¯ã
public void ReflectTypes(Type[]/*!*/ allTypes) { .... def.Super = null; if (cls != null && def.Extends != typeof(BasicObject) && !def.Extends.IsInterface) { if (cls != null && cls.Inherits != null) { def.Super = new TypeRef(cls.Inherits); .... }
PVS-StudioèŠåïŒ V3030å®æãã§ãã¯ã 'clsïŒ= Null'æ¡ä»¶ã¯ã373è¡ç®ã§æ¢ã«æ€èšŒãããŠããŸããLibraryDef.cs 374
ããã§ã¯ãäž¡æ¹ã®æ¡ä»¶ã§ãå€æ°ãclsãã®ãã«ããã§ãã¯ãããŸãã ã»ãšãã©ã®å Žåãèè ã¯æåã®æ¡ä»¶ã§ 'def'ã®nullããã§ãã¯ãããã£ãã®ã¯ãããã§ããã«Extendsããããã£ã«ã¢ã¯ã»ã¹ããããã§ãã ããããæ¡ä»¶ã®çŽåã«nullããdef.Superãã«æžã蟌ãŸããããããããå¿ èŠã§ã¯ãããŸãããã€ãŸãããdefãã¯ãã¯ãnullã§ã¯ãããŸããã äžè¬ã«ãããã¯åãªãè¿œå ã®ãã§ãã¯ã§ãã
äŸ16.ã³ããŒãšè²Œãä»ãã
ç§ã¯ããã280åã®ç¬¬3ã¬ãã«ã®ãšã©ãŒã«å°éããŸããã ãããã®å€§éšåã¯ã2ã€ã®é¢æ°ã®æ¬äœãäžèŽãããšããèŠåãšãæµ®åå°æ°ç¹æ°ã®æ¯èŒã«é¢ããèŠåã§ãã ç§ã¯ããã§äœãæ·±å»ãªãã®ãèŠã€ããããšãã§ãããšã¯æããªãã£ãã®ã§ããšã©ãŒããã£ãšèª¿ã¹å§ããŸããããããã§ããããèŠã€ããŸããã
public static bool IsPositiveOne(BigDecimal x) { return IsOne(x) && IsPositive(x); } public static bool IsNegativeOne(BigDecimal x) { return IsOne(x) && IsPositive(x); }
PVS-StudioèŠåïŒ V3013 ãIsPositiveOneãé¢æ°ã®æ¬äœããIsNegativeOneãé¢æ°ã®æ¬äœãšå®å šã«åçã§ããããšã¯å¥åŠã§ãïŒ351ãè¡355ïŒã BigDecimal.cs 351
ããã¯æ¬åœã«æ¬åœã®ééãã§ãããã³ãŒããããé¢æ°ããå¥ã®é¢æ°ã«ã³ããŒããçµæã§ãã ã³ãŒãã®æ£ããããŒãžã§ã³ã¯æ¬¡ã®ããã«ãªããŸãã
public static bool IsNegativeOne(BigDecimal x) { return IsOne(x) && IsNegative(x); }
äŸ17 NaNã®å¥åŠãªãã¹ãã
public static bool Equals(float x, float y) { if (x == y) { return !Single.IsNaN(x); } return x == y; }
PVS-StudioèŠåïŒ V3024å¥åŠãªæ£ç¢ºãªæ¯èŒïŒx == yã å®çŸ©ããã粟床ã®æ¯èŒã䜿çšããããšãæ€èšããŠãã ããïŒMath.AbsââïŒA-BïŒ<Epsilonã FloatOps.cs 1048
NaNã®ç¹å¥ãªãã§ãã¯ã®ãã€ã³ããäœã§ãããç解ã§ããŸããã§ããã æ¡ä»¶ïŒx == yïŒãæºããããå ŽåãNaNã¯ããèªäœãå«ãä»ã®å€ãšçãããªãããããxããšãyãã®äž¡æ¹ãNaNãšç°ãªãããšãæå³ããŸãã ã€ãŸããæåã®æ»ãå€ã¯åžžã«trueãè¿ããŸãã NaNã確èªããããšã¯äžèŠãªããã§ãã
ãããã«
ãããžã§ã¯ãæ€èšŒã®çµæã«åºã¥ããŠãã¢ãã©ã€ã¶ãŒã®äœæ¥ã«æºè¶³ããŸãããæåã«ãæ°åã®å®éã®ãšã©ãŒãèŠã€ãã£ãããããããžã§ã¯ãã³ãŒããæ¹åãããããã§ãã ãããŠæ¬¡ã«ãæé€ã§ããããã€ãã®èª€æ€ç¥ãç¹å®ããããã«ãã£ãŠè£œåãåæã«æ¹åããŸããã ãããã£ãŠãPVS-Studioã®ãã¢ããŒãžã§ã³ãããŠã³ããŒãããã³ãŒãã確èªããããšããå§ãããŸãã
ãã®èšäºãè±èªåã®èŽè¡ãšå ±æãããå Žåã¯ã翻蚳ãžã®ãªã³ã¯ã䜿çšããŠãã ããïŒã€ãªã€ã€ã¯ããã PVS-Studioã䜿çšããIronPythonããã³IronRubyã®åæ ã
èšäºãèªãã§è³ªåããããŸããïŒ
å€ãã®å Žåãèšäºã«ã¯åã質åãå¯ããããŸãã ããã§åçãåéããŸããïŒ PVS-StudioããŒãžã§ã³2016ã«é¢ããèšäºã®èªè
ããã®è³ªåãžã®åç ã ãªã¹ããã芧ãã ããã