
ã¯ããã¯ãã ããªãã¯æ£ããèããã ä»åã®èšäºã¯ããã®éãã§ãã ãããžã§ã¯ãããã§ãã¯ããã®ã§ã¯ãªããå¥ã®ããŒã«ã䜿çšããŠã¢ãã©ã€ã¶ãŒããã§ãã¯ããŸãã å®éãããã¯ä»¥åã«è¡ã£ãããšããããŸãã ããšãã°ãCppcheckã䜿çšããŠPVS-Studioããã§ãã¯ããVisual Studioã«çµã¿èŸŒãŸããã¢ãã©ã€ã¶ãŒã䜿çšããŠãIntel C ++ã®èŠåã調ã¹ãŸããã ããããèšäºãæžãçç±ã¯ãããŸããã§ããã é¢çœããã®ã¯èŠã€ãããŸããã§ããã ããããClangã¯èšºæã¡ãã»ãŒãžã«é¢å¿ãå¯ããããšãã§ããŸããã
PVS-Studio [ 1ã2 ]ã䜿çšããŠClangã 2åãã¹ãããæ¯åèå³æ·±ããã®ãèŠã€ããŸããã ããããPVS-Studioãæ€èšŒããããšã¯ã§ããŸããã§ããã Clangéçºè ã¯ãVisual C ++ã䜿çšããŠéçºãããWindowsãããžã§ã¯ãã®æ§ç¯ãåŸæã§ããããšãé·ãéå ±åããŠããŸããã ãããå®éã«ã¯ãã©ããããããããŸããããŸããã ãŸãã¯ãç§ãã¡ã¯å¹žéã§ã¯ãããŸããã
ãããŠå æ¥ãçªç¶Clangã䜿çšããŠã¢ãã©ã€ã¶ãŒãç°¡åã«ãã¹ãã§ããããšã«æ°ä»ããŸããã å察åŽããã¿ã¹ã¯ã«ã¢ãããŒãããå¿ èŠããããŸããã æ¯æ©ãGCCã䜿çšããŠLinuxçšPVS-Studioã®ã³ãã³ãã©ã€ã³ããŒãžã§ã³ãååŸããŸãã ãŸããGCCã³ã³ãã€ã©ã¯éåžžã«ç°¡åã«Clangã«çœ®ãæããããŸãã ãããã£ãŠãPVS-Studioãç°¡åã«ç¢ºèªã§ããŸãã ãããŠæ¬åœã«ã åãæ¥ã«ãåŸæ¥å¡ã®1人ã«æããã¢ã€ãã¢ãæµ®ããã ã®ã§ãPVS-Studioã®æ€èšŒã«é¢ããã¬ããŒãããããŸããã ä»ãç§ã¯åº§ã£ãŠã¬ããŒãã®å 容ãšç§ã®å°è±¡ã«ã€ããŠè©±ããŸãã
HTMLã¬ããŒãã®å°è±¡
ãã¡ãããç§ã¯ãã§ã«Clangãæ±ã£ãŠããŸãã ãã ãããµãŒãããŒãã£ã®ãããžã§ã¯ãã®åæã®è³ªãå€æããããšã¯å°é£ã§ãã ééãããããã©ããåãããªãããšããããããŸãã ãœãŒã¹ã³ãŒãã§37ãã€ã³ãã®ãã¹ã衚瀺ããå¿ èŠãããããšãClangã瀺ããŠããå Žåã¯ç¹ã«æãã§ãã
ããã©ããããPVS-Studioã®ã³ãŒãã¯ç§ã«ã¯éŠŽæã¿ããããã€ãã«Clangãçºè¡ããã¬ããŒããå®å šã«æäœããããšãã§ããŸããã æ®å¿µãªãããããã¯ãæ€åºããããšã©ãŒãéæããããã«ãã°ãã°ç€ºãããæ¹æ³ã¯åé·ã§ãããããã°ã©ããæ··ä¹±ããããšããç§ã®ä»¥åã®å°è±¡ã確èªããŸããã ããã°ã©ã ã®å®è¡ã«éèŠãªãã€ã³ããäžãããã®ãããªãã¹ãæ§ç¯ããããšã¯éåžžã«é£ããã¿ã¹ã¯ã§ããããšãç解ããŠããŸãã ããšãã°ãPVS-Studioã®å Žåãäžè¬ã«ãã®ãããªèšå€§ãªã¿ã¹ã¯ãåŒãåããããšãæããŠããŸãã ãã ããClangã¯ãã®ãã¹ã®ãã¢ã³ã¹ãã¬ãŒã·ã§ã³ãå®è£ ããŠãããããæããã«ãã®ã¡ã«ããºã ãããã«æ¹åããå¿ èŠããããŸãã
ãããªããã°ããã®ãããªãã€ã³ãã¯ãã ããã¯ããŠã³ããçµè«ãæ£ããããç解ãè€éã«ããŸãïŒ
å³ã¯ããã€ã³ãN4ãã瀺ããŠããŸãã 以äžã¯ãšã©ãŒã§ãã æ¡ä»¶ãæºããããªãå Žåã«ã®ã¿ãšã©ãŒãçºçããããšãç解ããŠããŸãã ããã¯Clangãå ±åãããã®ã§ãã ãããããªããã®æ å ±ã衚瀺ããã®ã§ããããïŒ ãã®ãããæ¡ä»¶ãçã®å Žåãé¢æ°ã¯çµäºãããšã©ãŒã¯çºçããŸããã äœåãªç¡æå³ãªæ å ±ã ãã®ãããªåé·ãªæ å ±ã¯ãããããããŸãã æããã«ããã®ã¡ã«ããºã ã¯æ¹åå¯èœã§ãããæ¹åãã¹ãã§ãã
ããããç§ã¯Clangéçºè ã®å瞟ã称ããããšæããŸãã å€ãã®å Žåããã®ãããªãã¹ã衚瀺ãããšãç¹ã«è€æ°ã®æ©èœãé¢äžããŠããå Žåã«ããšã©ãŒã®åå ãç解ããã®ã«åœ¹ç«ã¡ãŸãã ãŸããClangéçºè ã¯ãæ確ã«ãVisual Studio 2013éçã¢ãã©ã€ã¶ãŒãããã¯ããã«åªãããšã©ãŒãéæããæ¹æ³ã瀺ããŸããã ãããŠããã®çè²ãäžãããã®ã¯å®å šã«ç解äžèœã§ãã
èŠã€ãã£ããšã©ãŒã®é倧床
PVS-Studioã®ç¢ºèªã¯éåžžã«è¯ãäŸã§ãããååã«ãã¹ããããäœæ¥äžã®ãããžã§ã¯ãã§ã®éç解æã®å©ç¹ã瀺ãããã®æè¬ã®ãªãã¿ã¹ã¯ã§ãã å®éã次ã®ããã«èšã£ãŠããã¹ãŠã®ééããããéãããããšãã§ããŸãã
- ãã®ã³ãŒãã¯çŸåšäœ¿çšãããŠããŸããã
- ãã®ã³ãŒãã¯ãããŸãã«äœ¿çšããããããšã©ãŒåŠçã«äœ¿çšãããŸãã
- ãã®ãšã©ãŒã¯ãé¡èãªçµæã«ã¯ã€ãªãããŸããïŒãã®ä¿®æ£ã¯ãå€æ°ã®ãªã°ã¬ãã·ã§ã³ãã¹ãã§ã¯æ±ºããŠçŸããŸããïŒã
otmazyvatsyaãæã£ãŠããã®ã§ãç§ã¯æ·±å»ãªééããç¯ããŠããªãããã«èŠããŸããèªãããã«èŠãããšãClangã¯ããã°ã©ãã³ã°ã®åå¿è ã«ã®ã¿é©ããŠãããšèšããŸãã
ãã¡ãããç§ã¯ããã¯èšããŸããïŒ é倧ãªãšã©ãŒãèŠã€ãããªãã£ããšããäºå®ã¯ãClangãåæã«åŒ±ããšããæå³ã§ã¯ãããŸããã ãã®ãããªæ¬ é¥ããªãããšã¯ãããŸããŸãªæ¹æ³ã«ãããã¹ãã«é¢ããå€ãã®äœæ¥ã®çµæã§ãã
- å éšãŠããããã¹ãã
- 蚺æååž°ãã¹ãïŒããŒã¯ã¢ããããããã¡ã€ã«ïŒ;
- ããŸããŸãªC ++ã³ã³ã¹ãã©ã¯ããšããŸããŸãªæ¡åŒµåãå«ã* .iãã¡ã€ã«ã®ã»ããã®ãã¹ãã
- 90ã®ãªãŒãã³ãœãŒã¹ãããžã§ã¯ãã§ã®ååž°ãã¹ãã
- ãããŠããã¡ãããPVS-Studioã䜿çšããéçåæã
ãã®ãããªåŸ¹åºçãªé²åŸ¡ã®åŸãClangããã«ãã€ã³ã¿ãŒã®20ã®éåç §ãš0ã«ãã10ã®é€ç®ãèŠã€ããããšã¯æåŸ ãã«ããã§ããããããèããŠã¿ãŠãã ããã æ éã«ãã¹ãããããããžã§ã¯ãã§ãããClangã¯ããã€ãã®ãã°ãçºèŠããŸããã ããã¯ãå®æçã«äœ¿çšããã°ãå€ãã®ãã©ãã«ãåé¿ã§ããããšãæå³ããŸãã * .iãŠãŒã¶ãŒããPVS-Studioãã¯ã©ãã·ã¥ãããã¡ã€ã«ãååŸããããããClangãæ€åºãããšãã«ãšã©ãŒãä¿®æ£ããããšããå§ãããŸãã
åœç¶ãç§ãã¡ã¯èªåèªèº«ã§çµè«ãåºããŸããã ä»ãç§ã®ååã¯ããµãŒããŒäžã§Clangã®èµ·åãèšå®ããã¢ãã©ã€ã¶ãŒãäœããèŠã€ããå Žåã«ãã°ãã¡ãŒã«ã«éä¿¡ããã ãã§ãã
誀æ€ç¥ã«ã€ããŠ
åèšã§ãClangã¢ãã©ã€ã¶ãŒã¯45åã®èŠåãçæããŸããã 誀æ€ç¥ã®æ°ã«ã€ããŠè©±ããããããŸããã 12ç®æãä¿®æ£ããå¿ èŠããããŸãã
å®éãã誀æ€ç¥ãã¯çžå¯Ÿçãªåé¡ã§ãã æ£åŒã«ã¯ãã¢ãã©ã€ã¶ãŒã¯æ£ããã§ã-ã³ãŒãã¯äžæ£ã§çãããã§ãã ããããããã¯æ¬ é¥ãèŠã€ãã£ããšããæå³ã§ã¯ãããŸããã äŸã§èª¬æããŸãã
æåã«ãå®éã®èª€æ€ç¥ãæ€èšããŸãã
#define CreateBitMask(bitNum) ((v_uint64)(1) << bitNum) unsigned GetBitCountForRepresntValueLoopMethod( v_int64 value, unsigned maxBitsCount) { if (value == 0) return 0; if (value < 0) return maxBitsCount; v_uint64 uvalue = value; unsigned n = 0; int bit; for (bit = maxBitsCount - 1; bit >= 0; --bit) { if ((uvalue & CreateBitMask(bit)) != 0) // Clang: Within the expansion of the macro 'CreateBitMask': // The result of the '<<' expression is undefined { n = bit + 1; break; } .... }
ç§ãç解ããŠããããã«ãã¢ãã©ã€ã¶ãŒã¯ãã·ããæäœãæªå®çŸ©ã®åäœã«ã€ãªããå¯èœæ§ããããšå ±åããŠããŸãã ã©ããããClangã¯ããžãã¯ã§æ··ä¹±ããããå€æ°maxBitsCountã®å¯èœãªå€ã®ç¯å²ãæ£ããèšç®ã§ããŸããã§ããã GetBitCountForRepresntValueLoopMethodïŒïŒé¢æ°ãã©ã®ããã«åŒã³åºããããã泚ææ·±ãç 究ããŸãããããmaxBitsCountãå€æ°ã®å€ã倧ããããç¶æ³ãèŠã€ããããšãã§ããŸããã§ããã ã·ãããç解ããŠããŸã[ 3 ]ã ã ããããšã©ãŒã¯ãªããšç¢ºä¿¡ããŠããŸãã
èªä¿¡ã¯ãããŸãããååã§ã¯ãããŸããã ãããã£ãŠãç§ã¯ããã«ãã®ãããªã¢ãµãŒãïŒïŒãå ¥åããŸããïŒ
.... for (bit = maxBitsCount - 1; bit >= 0; --bit) { VivaAssert(bit >= 0 && bit < 64); if ((uvalue & CreateBitMask(bit)) != 0) ....
ãã¹ãŠã®ãã¹ãã§ããã®assertïŒïŒã¯æ©èœããŸããã§ããã ãããã£ãŠãããã¯å®éã«Clangã¢ãã©ã€ã¶ãŒã®èª€æ€ç¥ã®äŸã§ãã
assertïŒïŒãè¿œå ããããšã®è¯ãçµæã¯ãClangãã¬ããŒããåæ¢ããããšã§ãã assertïŒïŒãã¯ãã«çŠç¹ãåœãŠãŠããŸãã ã¢ãã©ã€ã¶ãŒã«å€æ°å€ã®å¯èœãªç¯å²ãäŒããŸãã
ãã®ãããªçã®èª€æ€ç¥ã¯ã»ãšãã©ãããŸããã ãããã®ã¡ãã»ãŒãžã®å€ãããããŸãïŒ
static bool G807_IsException1(const Ptree *p) { .... if (kind == ntArrayExpr) { p = First(p); kind = p->What(); // Clang: Value stored to 'kind' is never read ....
å²ãåœãŠãkind = p-> WhatïŒïŒ;ãã¯äœ¿çšãããŸããã 以åã¯ããã§ããããå€æŽåŸããã®è¡ã¯äžèŠã«ãªããŸããã ã¢ãã©ã€ã¶ãŒã¯æ£ããã§ãã ãã®è¡ã¯äžèŠã§ãããã®ã³ãŒãã«åè¡ãã人ãæ··ä¹±ãããªãããã«ãå°ãªããšãåé€ããå¿ èŠããããŸãã
å¥ã®äŸïŒ
template<> template<> void object::test<11>() { .... // nullWalker . VivaCore::VivaWalker *nullWalker = 0; left.m_simpleType = ST_INT; left.SetCountOfUsedBits(32); left.m_creationHistory = TYPE_FROM_VALUE; right.m_simpleType = ST_INT; right.SetCountOfUsedBits(11); right.m_creationHistory = TYPE_FROM_EXPRESSION; result &= ApplyRuleN1(*nullWalker, left, right, false); // Clang: Forming reference to null pointer .... }
åäœãã¹ãã§ã¯ãnullãã€ã³ã¿ãŒãéåç §ãããŸãã ã¯ããããã¯ã§ããŸããããcanãã§ãã ããããæ¬åœã«ãããã å®éãVivaWalkerã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãæºåããããšã¯éåžžã«é£ããããã®å Žåããªããžã§ã¯ããžã®åç §ã¯ãŸã£ãã䜿çšãããŸããã
äž¡æ¹ã®äŸã¯ãæ©èœããã³ãŒãã瀺ããŠããŸãã ãã ããããã誀æ€ç¥ãšã¯åŒã³ãŸããã ãããã¯å¯ŸåŠããå¿ èŠãããæ¬ é¥ã§ãã ãã ãããããã®èŠåã¯ãfound errorsãåã«ãèšèŒããŸããã ã ããããã誀æ€ç¥ã¯çžå¯ŸçãªæŠå¿µã ãšèšããŸãã
èŠã€ãã£ããã°
æåŸã«ãClangãPVS-Studioå ã§èŠã€ããèå³æ·±ãã³ãŒãã¹ããããã衚瀺ããã»ã¯ã·ã§ã³ã«è¡ããŸããã
çºèŠããããšã©ãŒã¯ããã°ã©ã ã«ãšã£ãŠéèŠã§ã¯ãããŸããã èšãèš³ãããããšã¯ããŠããŸããã ããããããã¯æ¬åœã«ããã§ããã ãã¹ãŠã®èŠåãç·šéããåŸãååž°ãã¹ãã§ã¯PVS-Studioã®åäœã®éãã¯æããã«ãªããŸããã§ããã
ããããç§ãã¡ã¯æ¬åœã®ééãã«ã€ããŠè©±ããŠããã®ã§ãClangãããããèŠã€ããããšãã§ããããšã¯çŽ æŽãããããšã§ãã å®æçãªãªãªãŒã¹ã«ãããæ°ããPVS-Studioã³ãŒãã®ããæ·±å»ãªééããèŠã€ããããšãã§ããããã«ãªããŸããã
2ã€ã®åæåãããŠããªãå€æ°ã䜿çšãã
ã³ãŒãã¯å€§ããè€éã§ããã èšäºã«å ¥ããããšã¯æå³ããããŸããã ãšã©ãŒã®æ¬è³ªãåæ ããåæã³ãŒããäœæããŸããã
int A, B; bool getA, getB; Get(A, getA, B, getB); int TmpA = A; // Clang: Assigned value is garbage or undefined int TmpB = B; // Clang: Assigned value is garbage or undefined if (getA) Use(TmpA); if (getB) Use(TmpB);
GetïŒïŒé¢æ°ã¯ãå€æ°Aããã³Bãåæåã§ããŸããå€æ°Aããã³Bãåæåãããã©ããã«ããããããå€æ°ã®getAãgetBã«æ³šæããŸãã
å€æ°AãšBãåæåãããŠãããã©ããã«ãããããããããã®å€ã¯TmpAãTmpBã«ã³ããŒãããŸãã ãã®æç¹ã§ãåæåãããŠããªãå€æ°ã䜿çšãããŠããŸãã
ãããé倧ã§ã¯ãªããšã©ãŒã ãšèšã£ãŠããã®ã¯ãªãã§ããïŒ å®éã«ã¯ãã¿ã€ã 'int'ã®åæåãããŠããªãå€æ°ãã³ããŒããŠãåé¡ã¯ãããŸããã æ£åŒã«ã¯ãç§ãç解ããŠããããã«ãæªå®çŸ©ã®åäœãçºçããŸãã å®éã«ã¯ããŽãã¯åçŽã«ã³ããŒãããŸãã ã¬ããŒãžãå«ããã®ä»ã®å€æ°ã¯äœ¿çšãããŸããã
ã³ãŒãã¯æ¬¡ã®ããã«æžãçŽãããŸããã
if (getA) { int TmpA = A; Use(TmpA); } if (getB) { int TmpB = B; Use(TmpB); }
åæåãããŠããªããã€ã³ã¿ãŒ
GetPtreePosïŒïŒé¢æ°ã®åŒã³åºããèŠãŠã¿ãŸãããã åæåãããŠããªããã€ã³ã¿ãŒãžã®åç §ãæž¡ããŸãã
SourceLocation Parser::GetLocation(const Ptree* ptree) { const char *begin, *end; GetPtreePos(ptree, begin, end); return GetSourceLocation(*this, begin); }
ããã¯ééã£ãŠããŸãã GetPtreePosïŒïŒé¢æ°ã¯ããã€ã³ã¿ãŒãnullptrã«åæåãããããšãåæãšããŠããŸãã ä»çµã¿ã¯æ¬¡ã®ãšããã§ãã
void GetPtreePos(const Ptree *p, const char *&begin, const char *&end) { while (p != nullptr) { if (p->IsLeaf()) { const char *pos = p->GetLeafPosition(); if (....) { if (begin == nullptr) { // Clang: The left operand of '==' is a garbage value begin = pos; } else { begin = min(begin, pos); } end = max(end, pos); } return; } GetPtreePos(p->Car(), begin, end); p = p->Cdr(); } }
åäœãã¹ããµãã·ã¹ãã ã§ç¹å®ã®ã³ãŒã解æãšã©ãŒãçºçãããšãã«GetLocationïŒïŒé¢æ°ãåŒã³åºãããã®ã¯æ®å¿µãªããšã§ãã ã©ããããããã¯èµ·ãã£ãããšããªãã
éçåæãTDDãè£å®ããæ¹æ³ã®è¯ãäŸã§ã[4]ã
æãæ瀺çãªãã£ã¹ã
åå€æãæããŠæ£ãããªã3ã€ã®é¡äŒŒããé¢æ°ããããŸãã ãããã®1ã€ã次ã«ç€ºããŸãã
bool Environment::LookupType( CPointerDuplacateGuard &envGuard, const char* name, size_t len, Bind*& t, const Environment **ppRetEnv, bool includeFunctions) const { VivaAssert(m_isValidEnvironment); //todo: Environment *eTmp = const_cast<Environment *>(this); Environment **ppRetEnvTmp = const_cast<Environment **>(ppRetEnv); bool r = eTmp->LookupType(envGuard, name, len, t, ppRetEnvTmp, includeFunctions); ppRetEnv = const_cast<const Environment **>(ppRetEnvTmp); // Clang: Value stored to 'ppRetEnv' is never read return r; }
ãœãã ãšãŽã¢ã©ã äžå€æ§ãåãé€ãããšããŸããã ãããŠãåãåã£ãå€ãè¿ããŸãã ããããå®éã«ã¯ããppRetEnv = const_cast ....ããšããè¡ã§ã¯ãããŒã«ã«å€æ°ppRetEnvãåã«å€æŽãããŠããŸãã
ãã®ãããªäžåèªãã©ãããæ¥ãã®ãããããããã°ã©ã ã«ã©ã®ããã«åœ±é¿ããã®ãã説æããŸãããã
PVS-Studioã¢ãã©ã€ã¶ãŒã¯ãOpenC ++ã©ã€ãã©ãªã«åºã¥ããŠããŸãã å®éã«ã¯ãããŒã¯ãŒããconstãã¯äœ¿çšããŸããã§ããã ãã€ã§ããéå®æ°ãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒã䜿çšããŠãäœã§ãã©ãã§ãå€æŽã§ããŸãã PVS-Studioã¯ãã®æ¬ é¥ãç¶æ¿ããŸããã
圌ãã¯åœŒãšæŠã£ãã ãããããŸã æåŸãŸã§ã§ã¯ãããŸããã constã1ãæã«èšè¿°ãã2çªç®ã«èšè¿°ãã次ã«3çªç®ã«èšè¿°ããå¿ èŠããããŸãã 次ã«ãç¹å®ã®ç¶æ³ã§ã¯ããã€ã³ã¿ãŒã䜿çšããŠäœããå€æŽããå¿ èŠããããé¢æ°ãéšåã«åå²ããããããã«åºç¯ãªãªãã¡ã¯ã¿ãªã³ã°ãå®è¡ããå¿ èŠãããããšãããããŸããã
çæ³äž»çŸ©çãªååè ã®äžäººãã©ãã§ãconstã«ããããšããæåŸã®è±éçãªè©Šã¿ã¯1é±éããããéšåçã«å€±æããŸããã ã³ãŒããšããŒã¿ã¹ãã¬ãŒãžæ§é ã®ç·šéã«å€§ããªå€æŽãå¿ èŠã§ããããšãæããã«ãªããŸããã éã®çåœãžã®å ã®æã¡èŸŒã¿ã¯åæ¢ãããŸããã æ€èšãããŠããããã«ãã¹ã¿ãã®ããã€ãã®æ©èœãããããã®ç®çã¯ã³ã³ãã€ã«ãããã³ãŒããäœæããããšã§ãã
ãã®ãšã©ãŒã¯äœã«åœ±é¿ããŸããïŒ å¥åŠãªããšã«ãããã¯äœã§ããããšæãããŸãã ãã¹ãŠã®åäœãã¹ããšååž°ãã¹ãã§ã¯ãä¿®æ£åŸã®PVS-Studioã®åäœã®å€åã¯æããã«ãªããŸããã§ããã ã©ãããããppRetEnvãã®æ»ãå€ã¯è·å Žã§ã¯ããŸãå¿ èŠã§ã¯ãªãããã§ãã
æœåšçã«åæåãããŠããªãå€æ°ã䜿çšãã
v_uint64 v; // Clang: 'v' declared without an initial value verify(GetEscape(p, len - 3, v, notation, &p)); retValue <<= 8; retValue |= v; // Clang: Assigned value is garbage or undefined
GetEscapeïŒïŒé¢æ°ã¯æ£åžžã«åäœããªãå Žåããããå€æ°ãvãã¯åæåãããªããŸãŸã«ãªããŸãã äœããã®çç±ã§GetEscapeïŒïŒã®çµæãverifyïŒïŒãã¯ãããã§ãã¯ããŸãã ã©ã®ããã«èµ·ãã£ãã®ãã¯ãã§ã«ããã£ãŠããŸããã
ãšã©ãŒã¯æ¬¡ã®çç±ã§æ°ä»ãããŸããã GetEscapeïŒïŒé¢æ°ã¯ãPVS-Studioã¢ãã©ã€ã¶ãŒã誀ã£ãããã°ã©ã ããã¹ãã§åäœããå Žåã«ã®ã¿å€æ°ãåæåããŸããã æ£ããããã°ã©ã ããã¹ãã§ã¯ãæ£ããESCã·ãŒã±ã³ã¹ãåžžã«ååšããå€æ°ã¯åžžã«åæåãããŸãã
èªåèªèº«ãã©ã®ããã«æ©èœããããé©ããã
Ptree *varDecl = bind->GetDecl(); if (varDecl != nullptr) { if (varDecl->m_wiseType.IsIntegerVirtualValue()) varRanges.push_back(....); else if (varDecl->m_wiseType.IsPointerVirtualValue()) varRanges.push_back(....); else varRanges.push_back(nullptr); } rangeTypes.push_back(varDecl->m_wiseType.m_simpleType); // Clang: Dereference of null pointer
varDeclãã€ã³ã¿ãŒã¯nullptrã®å ŽåããããŸãã ãã ããæåŸã®è¡ã¯åžžã«å®è¡ãããŸãã ãŸããnullãã€ã³ã¿ãŒéåç §ãçºçããå ŽåããããŸãïŒvarDecl-> m_wiseType.m_simpleTypeã
ããã«äžåºŠã転èœããããšããªãã®ã¯ãç§ã«ã¯è¬ã§ãã å¯äžã®ä»®å®ã¯ããªããžã§ã¯ããå€æ°å®£èšïŒå€æ°ã®å®£èšåïŒãžã®ãã€ã³ã¿ãŒãæ ŒçŽããŠããªãå Žåãããã«å°éããªãããšã§ãã ãããããšã«ããããã«é Œãããšã¯ã§ããŸããã
éåžžã«é倧ãªééããèŠã€ãããŸããããä»ã§ã¯ããã§ãªããã°ããã€ã®æ¥ã確ãã«ããã蚌æãããŸãã
é©ãã¹ãããšã«ãããã§ãæ»ã¯èŠãããŸããã§ããã
å¥ã®çŽ æŽãããå Žæã ã©ããããnullãã€ã³ã¿ãŒã®éåç §ã«ã€ãªããå¯èœæ§ã®ããèŠå ã®çµã¿åããã¯ã»ãšãã©ãããŸããã å°ãªããšãããã®é¢æ°ã®èšè¿°ä»¥æ¥ãèœäžã¯èªèãããŠããŸããã ãããããã®åŸãäžå¹ŽåãçµéããŸããã å¥è·¡
void ApplyRuleG_657(VivaWalker &walker, const BindFunctionName *bind, const IntegerVirtualValueArray *pReturnIntegerVirtualValues, const PointerVirtualValueArray *pReturnPointerVirtualValues, const Ptree *body, const Ptree *bodySrc, const Environment *env) { if (body == nullptr || bodySrc == nullptr) { VivaAssert(false); return; } if (bind == nullptr) return; if (pReturnIntegerVirtualValues == nullptr && pReturnPointerVirtualValues == nullptr) return; .... size_t integerValueCount = pReturnIntegerVirtualValues->size(); // Clang: Called C++ object pointer is null
ãã€ã³ã¿ãŒpReturnIntegerVirtualValuesã¯nullptrã§ããå¯èœæ§ããããŸãã
äžèŠããšã©ãŒã¯ç¶æ ã«ãããã||ãæŒç®åã䜿çšããå¿ èŠãããããã§ãã
if (pReturnIntegerVirtualValues == nullptr && pReturnPointerVirtualValues == nullptr)
ããããããã¯ããã§ã¯ãããŸããã ç¶æ ã¯æ£ããã§ãã ãã€ã³ã¿ãŒãéæ¥åç §ããåã«ããã€ã³ã¿ãŒãnullã§ãªãããšã確èªããå¿ èŠããããŸãã ãŒãã®å ŽåãintegerValueCountå€æ°ã¯0ã«èšå®ããå¿ èŠããããŸããæ£ãããªãã·ã§ã³ïŒ
size_t integerValueCount = pReturnIntegerVirtualValues != nullptr ? pReturnIntegerVirtualValues->size() : 0;
ããã éåžžã«å€ãã®ãã¹ãã 90ã®ãªãŒãã³ãœãŒã¹ãããžã§ã¯ãã§å®è¡ãããŸãã ããã«ãä»å¹Žã¯ä»ã®å€ãã®ãããžã§ã¯ãããã§ãã¯ããŸããã ããã§ããã³ãŒãã«ã¯ãã°ãååšããŸãã ãããŠã圌ã¯ç§ãã¡ã®éèŠãªæœåšçãªã¯ã©ã€ã¢ã³ãã§èªåèªèº«ãèŠããŠããã ããã
éçã¢ãã©ã€ã¶ãŒã«æ å ãïŒ Clangã«æ å ãïŒ
ãã®ä»
ã¢ãã©ã€ã¶ãŒã¯ãä¿®æ£ããå¿ èŠã®ãããšã©ãŒãããã«æããã«ããŸããã ããããèšè¿°ããããšã¯å°é£ã§ãããç§ã¯åæäŸãäœããããããŸããã ããã«ãããã€ãã®èŠåããããŸããããããã¯å®å šã«çå®ã§ããã圹ã«ç«ããªããã®ã§ãã ããã§ãåæããªãã«ããå¿ èŠããããŸããã
ããšãã°ãClangã¯RunPVSBatchFileModeïŒïŒé¢æ°ã䜿çšãããšãã«åæåãããŠããªãå€æ°ãå¿é ã§ããã ããããå®éã«ã¯ããããèµ·åã¯åã«Linuxã«å®è£ ãããŠããããã¹ã¿ãããããŸãã ãŸãããŸã å®è£ ããäºå®ã¯ãããŸããã
çµè«
äœæ¥äžã«éçã¢ãã©ã€ã¶ãŒã䜿çšããŸãã
PVS-Studioã³ã¢ã¯é«åºŠã«ãã¹ããããŠããŸãã ãã ããClangéçã¢ãã©ã€ã¶ãŒã¯12ã®å®éã®ãšã©ãŒãæ€åºããŸããã ä»ã®å Žæã¯ãšã©ãŒã§ã¯ãããŸããããèããããã³ãŒãã§ãããç§ã¯ãã®ãããªå Žæããã¹ãŠä¿®æ£ããŸããã
èŠã€ãã£ããšã©ãŒã¯ãæãäžé©åãªç¬éã§ããããšãå€æããå¯èœæ§ããããŸãã ããã«ããã®ã¢ãã©ã€ã¶ãŒã¯ããã¹ãã§ææãããå€ãã®ãšã©ãŒãèŠã€ããã®ã«åœ¹ç«ã€ãšæããŸãã ã¡ã€ã³ã®ååž°ãã¹ãã®å®è¡ã«ã¯çŽ2æéããããŸãã ãã£ãšæ©ãäœããèŠã€ããããããã§ããã
Clangåºåãå«ãèšäºã次ã«ç€ºããŸãã ãããã圌ã¯ããã«å€ããŸããã
ä»ã®ã¢ãã©ã€ã¶ãŒã¯ã»ãšãã©åœ¹ã«ç«ããªããšã¯æããªãã§ãã ããã ããšãã°ãå人çã«ã¯Cppcheckã¢ãã©ã€ã¶ãŒãæ¬åœã«å¥œãã§ãã éåžžã«äœ¿ãããããéåžžã«æ確ãªèšºææ©èœãåããŠããŸãã ããããããŸããŸåœŒãPVS-Studioã§å€æ°ã®ãšã©ãŒãèŠã€ããããªãã£ãããã圌ã«é¢ããåæ§ã®èšäºãæžãããšã¯ã§ããŸããã
ãããŠããã¡ãããä»äºã§PVS-Studioã¢ãã©ã€ã¶ãŒã䜿çšããããšããå§ãããŸãã Visual C ++ [ 5 ]ã䜿çšããŠãã人ã«ãšã£ãŠéåžžã«äŸ¿å©ã§ãã ç¹ã«ãå€æŽããããã¡ã€ã«ã®ã³ã³ãã€ã«ãæåããåŸã«éå§ãããèªååæã«ã€ããŠå¿ããªãã§ãã ããã
ãã®èšäºã¯è±èªã§ãã
ãã®èšäºãè±èªåã®èŽè¡ãšå ±æãããå Žåã¯ã翻蚳ãžã®ãªã³ã¯ã䜿çšããŠãã ããïŒAndrey Karpovã Clangã§PVS-Studioã確èªããŸãã
è¿œå ã®ãªã³ã¯ïŒ
- ã¢ã³ãã¬ã€ã»ã«ã«ããã PVS-Studio察Clang
- ã¢ã³ãã¬ã€ã»ã«ã«ããã éç解æã¯å®æçã«é©çšããå¿ èŠããããŸã ã
- ã¢ã³ãã¬ã€ã»ã«ã«ããã ãã©ãŒããç¥ããªããæ°Žã«å ¥ã£ãŠã¯ãããªãã ããŒã3ïŒã·ããæäœã«ã€ããŠïŒ ã
- ã¢ã³ãã¬ã€ã»ã«ã«ããã éçåæãTDDãè£å®ããæ¹æ³ ã
- ã¢ã³ãã¬ã€ã»ã«ã«ããã PVS-Studio for Visual C ++ ã
èšäºãèªãã§è³ªåããããŸããïŒ
å€ãã®å Žåãèšäºã«ã¯åã質åãå¯ããããŸãã ããã§ãããã«å¯ŸããåçãåéããŸããïŒ PVS-Studioããã³CppCatããŒãžã§ã³2014ã«é¢ããèšäºã®èªè
ããã®è³ªåãžã®åç ã ãªã¹ããã芧ãã ããã