変数サイズミスで、終わらないforループをワーニングにしたい

初めまして、よろしくお願いします。

e2 studio で CCRL 1.09 を使用させていただいています。

変数サイズミスで終わらないforループをワーニングにする方法を教えて頂けないでしょうか。

・コンパイラの最適化はDebug優先です。

・forの後のコード(ret = 10;)を生成していないので、コンパイラは無限ループを認識していると思います。

・ワーニングが出ないと、全てのforループの変数長と、終了条件を目視チェックすることになるので、非常に厳しいです。

例:(1000までカウントする変数 count を、8ビットで定義してしまった)

void main(void) {
 unsigned char count;
 unsigned char ret;
 ret = 0;
 for(count = 0; count < 1000; count++){
  ret++;
 }
 ret = 10;
}

アセンブラ出力:

#CC-RL Compiler RL78 Assembler Source
#@  CC-RL Version : V1.09.00 [11 Nov 2019]
#@  Commmand :
#@   -cpu=S2
#@   -c
#@   -dev=C:\Renesas\e2_studio\DebugComp\\RL78\RL78\Common\DR5F1026A.DVF
#@   -I C:\Program Files (x86)\Renesas\RL78\1_9_0\inc
#@   -I C:\test\char_test\generate
#@   -character_set=utf8
#@   -lang=c
#@   -g
#@   -asm_path=src/
#@   -pass_source
#@   -Onothing
#@   -o src/char_test.obj
#@   ../src/char_test.c
#@  compiled at Tue Apr 21 08:55:06 2020

 .PUBLIC _main

 .SECTION .textf,TEXTF
_main:
 .STACK _main = 6
 ;***        1 :
 ;***        2 : void main(void)
 .LINE "C:/test/char_test/src/char_test.c", 2
 push hl
 ;***        3 : {
 ;***        4 :  unsigned char count;
 ;***        5 :  unsigned char ret;
 ;***        6 :  ret = 0;
 .LINE "C:/test/char_test/src/char_test.c", 6
 mov [sp+0x00], #0x00
.BB@LABEL@1_1: ; entry.split
 ;***        7 :  for(count = 0; count < 1000; count++){
 .LINE "C:/test/char_test/src/char_test.c", 7
 mov [sp+0x01], #0x00
 br $.BB@LABEL@1_3
.BB@LABEL@1_2: ; bb
 ;***        8 :   ret++;
 .LINE "C:/test/char_test/src/char_test.c", 8
 mov a, [sp+0x00]
 inc a
 mov [sp+0x00], a
 mov a, [sp+0x01]
 inc a
 mov [sp+0x01], a
.BB@LABEL@1_3: ; bb6
 .LINE "C:/test/char_test/src/char_test.c", 7
 br $.BB@LABEL@1_2
 ;***        9 :  }
 ;***       10 :  ret = 10;
 ;***       11 : }

 

よろしくお願いいたします。

  • 補足です。

    int main() にして、return ret; にしても、コードは生成されていませんでした。
    (行番号は先ほどとは異なります)
    ;*** 6 : ret = 10;
    ;*** 7 : return ret;
    ;*** 8 : }

    よろしくお願いします。
  • > 変数サイズミスで終わらないforループをワーニングにする方法

    ・gcc(https://gcc-renesas.com/ja/rl78/rl78-download-toolchains/)でコンパイルしてみる
    ・CC-RL 改善のリクエストをルネサスに執拗に送る
    ・ループの書き方を変更する for(count = 1000; count > 0; count--){

    ぱっと思いつくのはこの辺りですね。

  • fujita nozomu さん、返信ありがとうございました。

    コンパイラを変えるのは他のプロジェクトの関係で難しいのと、
    ループの書き方はバッファ処理の時などは難しいので、
    当面はCC-RL改善リクエストの窓口を探して、リクエストしてみます。
    また、それと並行して、gccでコンパイルだけ流して、エラーチェックだけする方法も検討してみます。

    CC-RLに関しては、下記も追加でリクエストしてみます。
    ・#if でタイプミスによる未定義シンボルが、無条件で「#if 0」とみなされる。
     (「インフォメーション、ワーニング…をエラーに変更する」に20193を指定してエラーにする)
    ・farポインタ比較が、無条件で下位16ビット比較になり、
     比較対象によっては if() の後が無条件実行/非実行になる。(if(ptr >= 0xf0000) ... など)
     (ポインタ比較は必ずlongにキャストするように、「ユーザーが」注意する)

    大変参考になりました。
    今後ともよろしくお願いします。
  • komさん、こんにちは。NoMaYと申します。

    > 変数サイズミスで、終わらないforループ

    変数の型(uint8_t, unit16_t, uint32_t等)に応じた数値範囲の不整合の話なのですね。記憶では、(他のコンパイラですが)MISRA-Cチェックが(うっとおしいほど)ワーニングを出力していたように思います。CC-RLでもMISRA-Cチェックが出来たと思います(プロフェッショナル版のみだったと思いますが、無償版でも初めの内は試せると思います)ので、それを試してみる手もあるかと思います。(ただ、うっとうしいほど沢山のワーニングが出るのと、今回のが実際に検出されるかどうか不明なのと、そういった懸念はあります、、、)

    また、このたぐいの話ではlintというツールを使用するのが定番と思います。(Amazon FreeRTOSのGitHubでも、プルリクエストを出すときの文面テンプレートに、lintしたかどうかを示すチェックマークがあったりします。ただ、私は使ったことが無くて、どんなお勧めのフリーソフトがあるか分かってないです。) とは言え、今は昔ほどはlintの話を見掛けない気はします。(コンパイラのワーニングチェック能力が昔よりは全般的に向上したからかな、と思っていたります、、、)

  • fujita nozomu さん

    教えて頂きまして有難うございました。

    残念ながら、RL用のGCCの"-Wall"オプションを付けても、何も出ませんでした。
    #if 未定義シンボル」も引っ掛かりませんでした。

    販売代理店経由でリクエストを出してみます。
    今後ともよろしくお願いします。
  • NoMaY さん
    教えて頂きましてありがとうございます。

    残念ながら、CC-RLは30日以上過ぎています。
    (レジストリの情報削除はしません)

    短時間では使えそうな lint を見つけられませんでしたが、
    これからじっくり探してみます。

    今後ともよろしくお願いいたします。
  • fujita nozomu さん

    gccで "-Wextra" オプション追加で、「warning: comparison is always true....」が出ました。
    通常のビルドは CC-RL で行い、時々チェックの為に gcc でもビルドするようにします。

    大変助かりました。
    有難うございました。
  • > 残念ながら、RL用のGCCの"-Wall"オプションを付けても、何も出ませんでした。
    > 「#if 未定義シンボル」も引っ掛かりませんでした。

    フツーに出ます。

    $ cat -n hoge.c
         1  void main(void) {
         2   unsigned char count;
         3   unsigned char ret;
         4   ret = 0;
         5   for(count = 0; count < 1000; count++){
         6    ret++;
         7   }
         8   ret = 10;
         9  }
        10
        11  #if UNDEFINEDIDENTIFIER
        12  #endif
    
    $ rl78-elf-gcc -v
    Using built-in specs.
    COLLECT_GCC=C:\Renesas\e2studio\GCC for Renesas RL78 4.9.2.201904-GNURL78-ELF\rl78-elf\rl78-elf\bin\rl78-elf-gcc.exe
    COLLECT_LTO_WRAPPER=c:/renesas/e2studio/gcc\ for\ renesas\ rl78\ 4.9.2.201904-gnurl78-elf/rl78-elf/rl78-elf/bin/../libexec/gcc/rl78-elf/4.9.2.201904-GNURL78/lto-wrapper.exe
    Target: rl78-elf
    Configured with: /builder/AutomatedBuilds/rl78/builds/build_20191025_124201/rl78/source/trunk/gcc/configure --target=rl78-elf --enable-languages=c,c++ --disable-shared --with-newlib --enable-lto --enable-libssp --enable-plugins --enable-gold --disable-libstdcxx-pch --with-pkgversion=GCC_Build_20191025 --prefix=/builder/AutomatedBuilds/rl78/builds/build_20191025_124201/rl78/rl78_win --host=i586-mingw32msvc --with-gnu-as --with-gnu-ld
    Thread model: single
    gcc version 4.9.2.201904-GNURL78 20140916 (prerelease (renesas-14r1-14)) (GNUPro 14r1) (Based on: GCC 4.9.2 GDB 7.8.2 Binutils 2.24 Newlib 3.1.0) (GCC_Build_20191025)
    
    $ rl78-elf-gcc -Wall -Wextra -Wundef -Wno-main -S -O2 hoge.c
    hoge.c: In function 'main':
    hoge.c:5:23: warning: comparison is always true due to limited range of data type [-Wtype-limits]
      for(count = 0; count < 1000; count++){
                           ^
    hoge.c: At top level:
    hoge.c:11:5: warning: "UNDEFINEDIDENTIFIER" is not defined [-Wundef]
     #if UNDEFINEDIDENTIFIER
         ^
    
    $
    
  • fujita nozomu さん
    教えて頂きまして、ありがとうございます。

    "-Wall -Wextra -Wundef" の組み合わせですね。
    e2 studio の gcc のワーニング設定に "-Wundef" が無かったので、見落としていました。
    追加オプションに "-Wundef" を入れて、無事にワーニングが出ました。

    重ね重ね、ありがとうございました。
  • komさん
    横から失礼します。
    私も同様なことで悩んでいます。
    私も同様に時々gccでビルドするようにしたいと思っています。
    しかし、gccでビルドするには、まともにgcc用の新規プロジェクトを別途作って、ccrlのコードをコピペして行うのでしょうか?
    どこかの設定で簡単に切り替えてコンパイルができるのでしょうか?