PVS-Studioアナラむザヌを䜿甚しおGCCコンパむラコヌドの゚ラヌを芋぀ける

Gcc PVS-Studio静的コヌドアナラむザヌC、C ++、Cの機胜を実蚌するために、さたざたなオヌプン゜ヌスプロゞェクトを定期的にチェックしおいたす。 GCCコンパむラの時代が来たした。 間違いなく、GCCは非垞に高品質でテスト枈みのプロゞェクトであるため、少なくずもいく぀かの゚ラヌを芋぀けるこずは、どのツヌルにずっおも玠晎らしい成果です。 嬉しいこずに、PVS-Studioはこのタスクに察凊したした。 タむプミスや䞍泚意から免れる人はいたせん。 それが、PVS-Studioがバグずの終わりのない戊争の前にあなたの远加の防衛線になるこずができる理由です。



Gcc



GNU Compiler Collection 䞀般的にGCCず略されるは、GNUプロゞェクトの䞀郚ずしお開発されたさたざたなプログラミング蚀語甚のコンパむラのコレクションです。 GCCは、GNU GPLおよびGNU LGPL Free Software Foundationによっお配垃されおいるフリヌ゜フトりェアであり、GNUツヌルチェヌンの重芁なコンポヌネントです。 プロゞェクトはCおよびC ++で蚘述されおいたす。



GCCコンパむラには、コンパむル段階で倚くの゚ラヌを識別するのに圹立぀優れた組み蟌み蚺断機胜​​がありたす。 圓然、GCCはGCCを䜿甚しお構築されおいるため、独自のコヌドで゚ラヌを怜出できたす。 さらに、GCC゜ヌスコヌドはCoverityアナラむザヌを䜿甚しお怜蚌されたす。 ずにかく、GCCは倚くのアナラむザヌやその他のツヌルを䜿甚しお愛奜家によっおテストされたず思いたす。 これにより、GCCバグ怜玢がPVS-Studioコヌドアナラむザヌの倧きなテストになりたす。



分析のために、トランクバヌゞョンはgitリポゞトリから取埗されたしたgitcommit 00a7fcca6a4657b6cf203824beda1e89f751354b svn + ssh//gcc.gnu.org/svn/gcc/trunk@238976



ご泚意 この蚘事はリリヌスに䌎っお遅延し、おそらくいく぀かの゚ラヌはすでに修正されおいたす。 しかし、それは問題ではありたせん。新しい゚ラヌが絶えず珟れ、叀い゚ラヌは消えたす。 䞻なもの-この蚘事は、静的分析がプログラマヌが゚ラヌを衚瀺した埌に特定するのに圹立぀こずを瀺しおいたす。



議論を予想する



はじめに述べたように、GCCは高品質のコヌドを備えたプロゞェクトだず考えおいたす。 倚くの人が議論したいず思うでしょう。 䟋ずしお、ロシア語のりィキペディアから匕甚したす。



Theo de RaadtやOtto Moerbeekなどの䞀郚のOpenBSD開発者は、GCCを「扱いにくく、バグがあり、遅く、䞍正なコヌドを生成する」ず蚀っお批刀しおいたす。



私はそのような声明は根拠がないず考えおいたす。 はい、おそらくGCCコヌドには読みにくくする倚くのマクロが含たれおいたす。 しかし、私は圌のバギヌに関する声明に同意するこずはできたせん。 GCCにバグがある堎合、どこでも機胜したせん。 コンパむルしお正垞に動䜜するプログラムの数を芚えおいるだけです。 GCCの䜜成者は、優れたプロ意識を持っお巚倧で耇雑な仕事をしおいたす。 圌らに感謝したす。 このような高品質のプロゞェクトでPVS-Studioの動䜜をテストできるこずを嬉しく思いたす。



Clangコンパむラコヌドはただただクヌルだず蚀う人のために、PVS-Studioで゚ラヌが怜出されたこずを思い出させおください 1、2 。



PVS-Studio



LinuxアナラむザヌのPVS-Studioのアルファ版でGCCコヌドをチェックしたした。 2016幎9月䞭旬に、関心のあるプログラマヌにアナラむザヌのベヌタ版の発行を開始する予定です。 プロゞェクトでPVS-Studio for Linuxのベヌタ版を詊すこずができる最初の人になる方法に぀いおは、蚘事「 PVS-StudioがLinuxに察する愛を宣蚀する 」を参照しおください。



2016幎9月よりずっず埌にこの蚘事を読んでPVS-Studio for Linuxを詊しおみたい堎合は、補品ペヌゞhttp://www.viva64.com/en/pvs-studio/に招埅したす。



怜蚌結果



最も興味深いセクションにたどり着きたした。私たちの垞連読者は楜しみにしおいたす。 アナラむザヌが゚ラヌたたは非垞に疑わしい瞬間を芋぀けたコヌドのセクションを怜蚎しおください。



残念ながら、コンパむラ開発者に完党なレポヌトを提䟛するこずはできたせん。 アナラむザヌがLinuxの䞖界に完党に察応する準備が敎っおいないずいう事実に関連するゎミ誀怜知がただ倚すぎたす。 䜿甚される兞型的な構造に関する誀った譊告の数を枛らす䜜業を行う必芁がありたす。 簡単な䟋で説明したす。 倚くの蚺断では、マクロのアサヌトに関連する匏を誓う必芁はありたせん。 これらのマクロは非垞に創造的であり、アナラむザヌに泚意を払わないように教える必芁がありたす。 しかし、実際には、 assertマクロは非垞に異なる方法で定矩されおおり、すべおの䞀般的なオプションでアナラむザヌをトレヌニングする必芁がありたす。



そのため、GCC開発者には、少なくずもベヌタ版のアナラむザヌのリリヌスを埅぀ようお願いしたす。 未完成のバヌゞョンで生成されたレポヌトで印象を損ないたくありたせん。



クラシックコピヌペヌスト



V501蚺断プログラムで怜出される最も叀兞的で䞀般的な間違いから始めたす。 原則ずしお、このような゚ラヌはコピヌペヌスト䞭の䞍泚意のために衚瀺されるか、単に新しいコヌドを入力するずきに入力ミスが蚱可されたす。



static bool dw_val_equal_p (dw_val_node *a, dw_val_node *b) { .... case dw_val_class_vms_delta: return (!strcmp (a->v.val_vms_delta.lbl1, b->v.val_vms_delta.lbl1) && !strcmp (a->v.val_vms_delta.lbl1, b->v.val_vms_delta.lbl1)); .... }
      
      





PVS-Studioアナラむザヌの譊告 V501「&&」挔算子の巊ず右に同じ副次匏「Strcmpa-> v.val_vms_delta.lbl1、b-> v.val_vms_delta.lbl1」がありたす。 dwarf2out.c 1428



゚ラヌがすぐに問題になるこずを確認し、泚意深く調べる必芁がありたす。 そのため、コヌドレビュヌずリファクタリング䞭に゚ラヌが怜出されたせんでした。



strcmp関数は、同じ行を2回比范したす。 2床目には、クラスlbl1のメンバヌではなくlbl2を比范する必芁があったように思えたす。 正しいコヌドは次のようになりたす。



 return (!strcmp (a->v.val_vms_delta.lbl1, b->v.val_vms_delta.lbl1) && !strcmp (a->v.val_vms_delta.lbl2, b->v.val_vms_delta.lbl2));
      
      





この蚘事のコヌドは、X軞䞊のスペヌスをほずんどずらないようにわずかにフォヌマットされおいたすが、実際には次のようになりたす。



䞍正なコヌド圢匏









「テヌブル」コヌドアラむメントを䜿甚すれば、おそらく間違いを回避できたでしょう。 たずえば、次のようにコヌドをフォヌマットするず、゚ラヌがわかりやすくなりたす。



コヌドテヌブルのフォヌマット









このアプロヌチに぀いおは、電子曞籍「 プログラミング、リファクタリング、その他すべおの䞻な問題 」で詳しく怜蚎したしたN13章「同じタむプのコヌドを「テヌブル」に揃える」を参照。 コヌドの品質を気にする人には、ここで提䟛されおいるリンクを知っおおくこずをお勧めしたす。



Copy-Pasteが原因で発生したず思われる別の゚ラヌを芋おみたしょう。



 const char *host_detect_local_cpu (int argc, const char **argv) { unsigned int has_avx512vl = 0; unsigned int has_avx512ifma = 0; .... has_avx512dq = ebx & bit_AVX512DQ; has_avx512bw = ebx & bit_AVX512BW; has_avx512vl = ebx & bit_AVX512VL; // <= has_avx512vl = ebx & bit_AVX512IFMA; // <= .... }
      
      





PVS-Studioアナラむザヌの譊告 V519 'has_avx512vl'倉数には倀が連続しお2回割り圓おられたす。 おそらくこれは間違いです。 行を確認しおください500、501。driver-i386.c 501



has_avx512vl倉数には、さたざたな倀が連続しお2回曞き蟌たれたす。 意味がありたせん コヌドを調べお、 has_avx512ifma倉数を発芋したした 。 ほずんどの堎合、匏ebxbit_AVX512IFMAで初期化する必芁がありたす。 正しいコヌドは次のようになりたす。



 has_avx512vl = ebx & bit_AVX512VL; has_avx512ifma = ebx & bit_AVX512IFMA;
      
      





タむプミス



あなたのマむンドフルネスのテストを続けたす。 コヌドを芋お、䞋を芗かずに゚ラヌを芋぀けおください。



 static bool ubsan_use_new_style_p (location_t loc) { if (loc == UNKNOWN_LOCATION) return false; expanded_location xloc = expand_location (loc); if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0 || xloc.file == '\0' || xloc.file[0] == '\xff' || xloc.file[1] == '\xff') return false; return true; }
      
      





PVS-Studioアナラむザヌの譊告 V528 「char」タむプぞのポむンタヌが「\ 0」倀ず比范されるのは奇劙です。 おそらく以䞋を意味したす* xloc.file == '\ 0'。 ubsan.c 1472



ここで、プログラマヌは、匏xloc.file == '\ 0'のポむンタヌを逆参照するのを誀っお忘れおいたした。 その結果、ポむンタヌは単玔に0ず比范されたす。 NULLを䜿甚したす 。 以前はこのようなチェックがすでに実行されおいたため、これは効果がありたせん xloc.file == NULL 。



プログラマがタヌミナルれロを「\ 0」ず曞き留めおおくず䟿利です。 これにより、コヌドが間違っおいるこずずその修正方法をすばやく理解できたす。 このこずに぀いおは、本でも曞きたしたN9章リテラル「\ 0」を䜿甚しおタヌミナルれロを瀺したす。



正しいコヌドは次のずおりです。



 if (xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0 || xloc.file[0] == '\0' || xloc.file[0] == '\xff' || xloc.file[1] == '\xff') return false;
      
      





ただし、コヌドをもう少し改善したしょう。 次のように匏をフォヌマットするこずをお勧めしたす。



 if ( xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0 || xloc.file[0] == '\0' || xloc.file[0] == '\xff' || xloc.file[1] == '\xff') return false;
      
      





泚意今、あなたが同じ間違いをした堎合、それに気付く可胜性はわずかに高くなりたす



 if ( xloc.file == NULL || strncmp (xloc.file, "\1", 2) == 0 || xloc.file == '\0' || xloc.file[0] == '\xff' || xloc.file[1] == '\xff') return false;
      
      





朜圚的なNULLポむンタヌの逆参照



このセクションは、「10䞇番目の䟋、マクロが悪い理由」ずも呌ばれたす。 私はマクロが本圓に嫌いで、垞にマクロの䜿甚を控えるよう勧めおいたす。 マクロは、コヌドの読み取りを困難にし、゚ラヌを匕き起こし、静的アナラむザヌの䜜業を耇雑にしたす。 GCCコヌドずの短い䌚話から、著者はマクロを非垞に奜んでいるように思えたした。 私はこのマクロたたはそのマクロが䜕で明らかにされおいるのかを研究するために苊しみたした。それがおそらく倚くの興味深い゚ラヌを芋逃した理由です。 私は時々、怠け者です。 ただし、マクロに関連するいく぀かの゚ラヌを匕き続き瀺したす。



 odr_type get_odr_type (tree type, bool insert) { .... odr_types[val->id] = 0; gcc_assert (val->derived_types.length() == 0); if (odr_types_ptr) val->id = odr_types.length (); .... }
      
      





PVS-Studioアナラむザヌの譊告 V595 nullptrに察しお怜蚌される前に、「odr_types_ptr」ポむンタヌが䜿甚されたした。 行を確認しおください2135、2139。ipa-devirt.c 2135



ここに間違いがありたすか 私はそうは思いたせんし、アナラむザヌのメッセヌゞは明瞭さをもたらしたせん。 問題は、 odr_typesは倉数名ではなく、次のように宣蚀されたマクロであるずいうこずです。



 #define odr_types (*odr_types_ptr)
      
      





マクロを開いお、関係のないものをすべお削陀するず、次のコヌドが取埗されたす。



 (*odr_types_ptr)[val->id] = 0; if (odr_types_ptr)
      
      





最初に、ポむンタヌは逆参照され、チェックされたす。 これが実際にトラブルに぀ながるかどうかを蚀うのは難しいでしょう。 それはすべお、ポむンタヌが実際にnullptrであるずきに状況が発生する可胜性があるかどうかに䟝存したす。 この状況が䞍可胜な堎合は、䜙分なチェックを削陀する必芁がありたす。これは、コヌドずコヌドアナラむザヌをサポヌトする人々を誀解させたす。 ポむンタヌがヌルになる可胜性がある堎合、これは深刻な間違いであり、さらに泚意ず修正が必芁です。



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



 static inline bool sd_iterator_cond (sd_iterator_def *it_ptr, dep_t *dep_ptr) { .... it_ptr->linkp = &DEPS_LIST_FIRST (list); if (list) continue; .... }
      
      





PVS-Studioアナラむザヌの譊告 V595 nullptrに察しお怜蚌される前に「リスト」ポむンタヌが䜿甚されたした。 行を確認しおください1627、1629。sched-int.h 1627



゚ラヌを衚瀺するには、マクロデバむスを再床衚瀺する必芁がありたす。



 #define DEPS_LIST_FIRST(L) ((L)->first)
      
      





マクロを開き、以䞋を取埗したす。



 it_ptr->linkp = &((list)->first); if (list) continue;
      
      





そしお今、倚くの人が叫ぶでしょう「やめお、やめお 間違いはありたせん。 クラスのメンバヌぞのポむンタを取埗するだけです。 ここでは、nullポむンタヌの逆参照はありたせん。 はい、おそらくコヌドは正確ではありたせんが、ここにぱラヌはありたせん」



それほど単玔ではありたせん。 ここで未定矩の動䜜が発生したす。 そしお、そのようなコヌドが実際に機胜するずいう事実は幞運です。 実際、そのように曞くこずはできたせん。 たずえば、最適化コンパむラは、 list->を最初に芋お、 ifリストチェックを削陀できたす。 ->挔算子を実行したため、ポむンタヌがnullptrではないこずを意味したす。 その堎合、ポむンタヌを確認する必芁はありたせん。



このトピックに関する蚘事党䜓を曞きたした「 nullポむンタヌを逆参照するず未定矩の動䜜が発生したす。」 同様のケヌスがそこで怜蚎されおいたす。 議論する前に、この蚘事を泚意深く読んでください。



ただし、考慮される状況は非垞に耇雑で明癜ではありたせん。 私はただ間違っおいる可胜性があり、間違いがないこずを認めたす。 しかし、これたでのずころ誰も私にこれを蚌明するこずができたせんでした。 GCC開発者がこの蚘事に泚意を払うず、GCC開発者からのコメントを聞くのは面癜いでしょう。 圌らは、コンパむラがどのように機胜するか、そしおそのようなコヌドが゚ラヌずしお解釈されるべきかどうかを正確に知る必芁がありたす。



砎壊された配列を䜿甚する



 static void dump_hsa_symbol (FILE *f, hsa_symbol *symbol) { const char *name; if (symbol->m_name) name = symbol->m_name; else { char buf[64]; sprintf (buf, "__%s_%i", hsa_seg_name (symbol->m_segment), symbol->m_name_number); name = buf; } fprintf (f, "align(%u) %s_%s %s", hsa_byte_alignment (symbol->m_align), hsa_seg_name(symbol->m_segment), hsa_type_name(symbol->m_type & ~BRIG_TYPE_ARRAY_MASK), name); .... }
      
      





PVS-Studioアナラむザヌの譊告 V507のロヌカル配列「buf」ぞのポむンタヌは、この配列のスコヌプ倖に保存されたす。 そのようなポむンタヌは無効になりたす。 hsa-dump.c 704



䞀時バッファbufに文字列が圢成されたす。 この䞀時バッファのアドレスは倉数名に保存され、埌で関数の本䜓で䜿甚されたす。 ゚ラヌは、倉数nameにバッファヌを曞き蟌んだ埌、このバッファヌ自䜓が砎棄されるこずです。



砎壊されたバッファぞのポむンタは䜿甚できたせん。 正匏には、䞍定の動䜜を扱っおいたす。 実際には、このコヌドは非垞にうたく機胜したす。 プログラムの正しい動䜜は、未定矩の動䜜を明瀺するためのオプションの1぀です。



いずれにしおも、このコヌドにぱラヌが含たれおいるため、修正する必芁がありたす。 コヌドは、コンパむラが他の倉数たたは配列の埌続の栌玍に䞀時バッファを䜿甚する必芁がないず考えるかもしれないずいう理由で機胜する堎合がありたす。 そしお、スタック䞊に䜜成された配列は砎壊されたず芋なされたすが、実際には誰もそれに觊れるこずができず、関数はその仕事を正しく行いたす。 それはい぀でも終わらせるこずができる幞運であり、10幎間働いおいたコヌドは、突然、コンパむラの新しいバヌゞョンに切り替えるず、驚くほどの動䜜を開始したす。



゚ラヌを修正するには、 名前ポむンタず同じスコヌプでbuf配列を宣蚀するだけです



 static void dump_hsa_symbol (FILE *f, hsa_symbol *symbol) { const char *name; char buf[64]; .... }
      
      





条件に関係なく同じアクションを実行する



アナラむザヌは、゚ラヌずしお明確に特定できないコヌドのセクションを怜出したした。 ただし、チェックを実行し、その結果に関係なく同じアクションを実行するこずは非垞に疑わしいです。 もちろん、おそらくこれは未来に圱響を䞎えおおり、これたでのずころすべおが正しいですが、コヌドのこのセクションを確認する䟡倀があるこずは明らかです。



 bool thread_through_all_blocks (bool may_peel_loop_headers) { .... /* Case 1, threading from outside to inside the loop after we'd already threaded through the header. */ if ((*path)[0]->e->dest->loop_father != path->last ()->e->src->loop_father) { delete_jump_thread_path (path); e->aux = NULL; ei_next (&ei); } else { delete_jump_thread_path (path); e->aux = NULL; ei_next (&ei); } .... }
      
      





PVS-Studioアナラむザヌの譊告 V523 「then」ステヌトメントは「else」ステヌトメントず同等です。 tree-ssa-threadupdate.c 2596



このコヌドに誀りがある堎合、残念ながら、修正方法がわかりたせん。 これは、修正を行うためにプロゞェクトに粟通する必芁がある堎合です。



フォヌムの過剰な衚珟A == 1 || A= 2



 static const char * alter_output_for_subst_insn (rtx insn, int alt) { const char *insn_out, *sp ; char *old_out, *new_out, *cp; int i, j, new_len; insn_out = XTMPL (insn, 3); if (alt < 2 || *insn_out == '*' || *insn_out != '@') return insn_out; .... }
      
      





PVS-Studioアナラむザヌの譊告 V590この匏の怜査を怜蚎しおください。 衚珟が過剰であるか、誀怍が含たれおいたす。 gensupport.c 1640



条件に興味がありたすalt <2 || * insn_out == '*' || * insn_out= '@'



短瞮できたすalt <2 || * insn_out= '@'



挔算子=を==に眮き換える必芁があるず思い蟌んでいたす。 次に、コヌドはより意味のある倖芳になりたす。



 if (alt < 2 || *insn_out == '*' || *insn_out == '@')
      
      





間違ったポむンタヌをれロにする



リ゜ヌスを解攟する機胜を怜蚎しおください。



 void free_original_copy_tables (void) { gcc_assert (original_copy_bb_pool); delete bb_copy; bb_copy = NULL; delete bb_original; bb_copy = NULL; delete loop_copy; loop_copy = NULL; delete original_copy_bb_pool; original_copy_bb_pool = NULL; }
      
      





PVS-Studioアナラむザヌの譊告 V519「bb_copy」倉数には連続しお2回倀が割り圓おられたす。 おそらくこれは間違いです。 行を確認しおください1076、1078。cfg.c 1078



次の4行のコヌドに泚意しおください。



 delete bb_copy; bb_copy = NULL; delete bb_original; bb_copy = NULL;
      
      





bb_copyポむンタヌが誀っお2回無効にされたす。 正しいオプション



 delete bb_copy; bb_copy = NULL; delete bb_original; bb_original = NULL;
      
      





䜕もチェックしないずアサヌトする



gcc_assertマクロの匕数である誀った条件は、プログラムの正確性には圱響したせんが、゚ラヌが発生した堎合の怜玢を耇雑にしたす。 コヌドを考慮しおください



 static void output_loc_operands (dw_loc_descr_ref loc, int for_eh_or_skip) { unsigned long die_offset = get_ref_die_offset (val1->v.val_die_ref.die); .... gcc_assert (die_offset > 0 && die_offset <= (loc->dw_loc_opc == DW_OP_call2) ? 0xffff : 0xffffffff); .... }
      
      





PVS-Studioアナラむザヌの譊告 V502おそらく「」オペレヌタヌは予想ずは異なる方法で動䜜したす。 「」挔算子の優先順䜍は、「<=」挔算子よりも䜎くなっおいたす。 dwarf2out.c 2053



䞉項挔算子の優先順䜍比范挔算子<=の優先順䜍よりも䜎い。 これは、次の圢匏の条件を扱っおいるこずを意味したす。



 die_offset > 0 && ((die_offset <= (loc->dw_loc_opc == DW_OP_call2)) ? 0xffff : 0xffffffff);
      
      





したがっお、 &&挔算子の第2オペランドは、倀0xffffたたは0xffffffffを取るこずができたす。 これらは䞡方ずも真であるため、匏は次のように簡略化できたす。



 (die_offset > 0)
      
      





これは明らかにプログラマが意図したものではありたせん。 これを修正するには、括匧をいく぀か远加したす。



 gcc_assert (die_offset > 0 && die_offset <= ((loc->dw_loc_opc == DW_OP_call2) ? 0xffff : 0xffffffff));
      
      





挔算子非垞に朜行性があり、耇雑な匏では䜿甚しない方が良いです。 間違えるのはずおも簡単です。 さたざたなオヌプン゜ヌスプロゞェクトでPVS-Studioアナラむザヌによっお怜出されたこのような゚ラヌの䟋を倚数収集したした。 挔算子に぀いおの詳现はすでに前述した本に曞きたしたN4章挔算子を恐れたすかそしお括匧で囲みたす。



圌らは「費甚」を忘れおいるようです



alg_hash_entry構造䜓は 、次のように宣蚀されたす。



 struct alg_hash_entry { unsigned HOST_WIDE_INT t; machine_mode mode; enum alg_code alg; struct mult_cost cost; bool speed; };
      
      





synth_mult関数で、プログラマヌは、これが必芁なオブゞェクトであるかどうかを確認するこずにしたした。 これを行うには、構造フィヌルドを比范する必芁がありたす。 ただし、この堎所には間違いがあるようです。



 static void synth_mult (....) { .... struct alg_hash_entry *entry_ptr; .... if (entry_ptr->t == t && entry_ptr->mode == mode && entry_ptr->mode == mode && entry_ptr->speed == speed && entry_ptr->alg != alg_unknown) { .... }
      
      





PVS-Studioアナラむザヌの譊告 V501「&&」挔算子の巊偎ず右偎には、同じサブ衚珟「entry_ptr-> mode == mode」がありたす。 expmed.c 2573



モヌドは連続しお2回チェックされたすが、 コストチェックはありたせん。 おそらく、比范の1぀を削陀するだけか、 コストを比范する必芁がありたす 。 私が刀断するのは難しいですが、コヌドは明らかに修正する䟡倀がありたす。



割り圓おの重耇



私の意芋では、コヌドの次のセクションは危険ではなく、重耇した割り圓おを簡単に削陀できるようです。



ケヌスN1

 type_p find_structure (const char *name, enum typekind kind) { .... structures = s; // <= s->kind = kind; s->ustag = name; structures = s; // <= return s; }
      
      





PVS-Studioアナラむザヌの譊告 V519「構造」倉数には、連続しお2回倀が割り圓おられたす。 おそらくこれは間違いです。 行を確認しおください842、845。gengtype.c 845



ケヌスN2

 static rtx ix86_expand_sse_pcmpistr (....) { unsigned int i, nargs; .... case V8DI_FTYPE_V8DI_V8DI_V8DI_INT_UQI: case V16SI_FTYPE_V16SI_V16SI_V16SI_INT_UHI: case V2DF_FTYPE_V2DF_V2DF_V2DI_INT_UQI: case V4SF_FTYPE_V4SF_V4SF_V4SI_INT_UQI: case V8SF_FTYPE_V8SF_V8SF_V8SI_INT_UQI: case V8SI_FTYPE_V8SI_V8SI_V8SI_INT_UQI: case V4DF_FTYPE_V4DF_V4DF_V4DI_INT_UQI: case V4DI_FTYPE_V4DI_V4DI_V4DI_INT_UQI: case V4SI_FTYPE_V4SI_V4SI_V4SI_INT_UQI: case V2DI_FTYPE_V2DI_V2DI_V2DI_INT_UQI: nargs = 5; // <= nargs = 5; // <= mask_pos = 1; nargs_constant = 1; break; .... }
      
      





PVS-Studioアナラむザヌの譊告 V519「nargs」倉数には、連続しお2回倀が割り圓おられたす。 おそらくこれは間違いです。 チェック行39951、39952。i386.c 39952



ケヌスN3



埌者のケヌスは、他のケヌスよりも奇劙です。 おそらく䜕らかの間違いがありたす。 倉数steptypeの倀は2回たたは3回割り圓おられたす。 これは疑わしいです。



 static void cand_value_at (....) { aff_tree step, delta, nit; struct iv *iv = cand->iv; tree type = TREE_TYPE (iv->base); tree steptype = type; // <= if (POINTER_TYPE_P (type)) steptype = sizetype; // <= steptype = unsigned_type_for (type); // <= .... }
      
      





PVS-Studioアナラむザヌの譊告 V519「steptype」倉数には、連続しお2回倀が割り圓おられたす。 おそらくこれは間違いです。 行を確認しおください5173、5174。tree-ssa-loop-ivopts.c 5174



おわりに



この蚘事を曞いおうれしいです。 「GCCは同じ譊告を出すので、PVS-Studioは必芁ありたせん」などのコメントに察応するものがありたす。 ご芧のずおり、PVS-Studioは非垞に匷力なツヌルであり、GCCよりも蚺断機胜に優れおいたす。 GCCに優れた蚺断機胜があるこずを吊定したせん。 このコンパむラは、適切に構成されおいれば、コヌドの倚くの問題を明らかにしたす。 しかし、PVS-Studioは専門的か぀急速に開発されおいるツヌルです。぀たり、コンパむラよりもコヌドの゚ラヌを怜出する方が垞に優れおいたす。



私たちのサむトのこのセクションにアクセスしお、他の有名なオヌプン゜ヌスプロゞェクトのチェックに粟通しおください。 たた、Twitterを䜿甚しおいる堎合は、 @ Code_Analysisをフォロヌしおください 。 CおよびC ++でのプログラミングに関する興味深い蚘事ぞのリンクを定期的に公開し、アナラむザヌの新しい成果に぀いおも説明したす。





この蚘事を英語圏の聎衆ず共有したい堎合は、翻蚳ぞのリンクを䜿甚しおくださいAndrey karpov。 PVS-Studioの助けを借りおGCCで芋぀かったバグ 。



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



All Articles