CC-RXでvolatile指定有り__evenaccess指定無しのobjectへのaccess sizeが保証されないのは言語規格上妥当なのかな?

こんにちは。NoMaYです。

正直に言うとCC-RXの__evenaccessの"意味"を知ったのは3日前に別スレッド『RX用FITのUSBドライバをCS+6環境でコンパイル最適化レベル2以上にしたときの不具合』に関わった時ですが、以来、掲題の件が気になっています。これって、非常にハイリスクだと思うのですが、MISRA-CでもCERT(JPCERT/CC)でも、類似した件を見掛けた記憶がないのです。それって、C言語規格上そういうものでは無い、ということなのではないかと思われるのですが、、、

CC-RXのマニュアルでは以下の通りに言い切っています。(他方、CC-RLのマニュアルはそう言っていませんが。) 素朴に解釈すると、__evenaccessと一緒に使われていないvolatileなど恐ろしくて使えたものではありません。(と私は暫くしてから感じるようになりました。)

CC-RXコンパイラ ユーザーズマニュアル
www.renesas.com/ja-jp/doc/products/tool/doc/011/r20ut3248jj0105-ccrx.pdf
4. コンパイラ言語仕様
4.1 基本言語仕様
4.1.3 処理系依存
(10) 型修飾子


(参) CC-RLコンパイラ ユーザーズマニュアル
www.renesas.com/ja-jp/doc/products/tool/doc/011/r20ut3123jj0106_ccrl.pdf
4. コンパイラ言語仕様
4.1 基本言語仕様
4.1.3 処理系依存
(33) 型修飾子


ですが、そのように恐ろしい単独のvolatileですが、先程のスレッドにも投稿したTOPPERS/ASPのソースで平気で使われています。以下はそこからの引用ですが、他にも、少し凝った作りの自前のドライバのソースには、きっと__evenaccessと一緒に使われていない恐ろしい単独のvolatileが幾つも見付かるのではないかと推測されます。

もっとも、mstpcrregへの書き込みが以下のスタイルですので、TOPPERS/ASPの慣習では、(たまたま?)大丈夫そうですが、、、([追記] なお、sil_rew_mem()やsil_wrw_mem()のコードに__evenaccessが無いのは、将来のCC-RXのバージョンアップに対するリスク要因である、ような気がして来ましたが、、、)

pdic\rx600\rx630_uart.c

/*
 *  SIOドライバのシリアルモードレジスタ(SMR)
 */
static void
rx630_uart_setmode(const SIOPINIB *p_siopinib, uint8_t bitrate, uint8_t clksrc)
{

    /*
     *  モジュールストップ機能の設定
     */
    sil_wrh_mem((uint16_t *)SYSTEM_PRCR_ADDR, (uint16_t)0xA502);    /* 書込み許可 */
    sil_wrw_mem((uint32_t *)p_siopinib->mstpcrreg,
        sil_rew_mem((uint32_t *)p_siopinib->mstpcrreg) & ~p_siopinib->mstpcr_offset);
    sil_wrh_mem((uint16_t *)SYSTEM_PRCR_ADDR, (uint16_t)0xA500);    /* 書込み禁止 */

}

include\sil.h ([追記] これでは呼び出し元の方に__evenaccessが有っても効かないような気がして来ました、、、)

Inline uint32_t
sil_rew_mem(const uint32_t *mem)
{
    uint32_t    data;

    data = *((const volatile uint32_t *) mem); ←ここに__evenaccessが無いのはリスク要因な気が、、、
    return(data);
}

Inline void
sil_wrw_mem(uint32_t *mem, uint32_t data)
{
    *((volatile uint32_t *) mem) = data; ←ここに__evenaccessが無いのはリスク要因な気が、、、
}

それで、CC-RXのマニュアルで言い切っている以上、どうこう出来るものではないでしょうが、以下でGoogle検索してみました。そこで、気になる記述に気付きましたが、ここで力尽きましたので、また後日再挑戦してみます。

Google検索: 変数 アクセス サイズ site:www.jpcert.or.jp/sc-rules/
https://www.google.com/search?q=変数 アクセス サイズ site:www.jpcert.or.jp/sc-rules/

Google検索: volatile site:www.jpcert.or.jp/sc-rules/
https://www.google.com/search?q=volatile site:www.jpcert.or.jp/sc-rules/

気になる記述
DCL17-C. volatile 修飾された変数が間違ってコンパイルされることに注意
www.jpcert.or.jp/sc-rules/c-dcl17-c.html

volatile修飾された変数は「抽象計算機の規則に厳密に従って評価しなければならない」[ISO/IEC 9899:2011]


ちなみに、上の記述はC11の規格のもののようですが、C99の規格にも以下の通り同様のものが記述されていました。

JIS X 3010:2003 (ISO/IEC 9899:1999) プログラミング言語C
kikakurui.com/x3/X3010-2003-01.html


Top Replies

  • こんにちは。NoMaYです。

    __evenaccessの付け忘れが無いかとか付け忘れた影響の度合いとかを確認する方法として、1つ思い浮かんだことがあります。CC-RXのオプションに以下を追加してビルドして、アセンブリソースファイル出力の変化を確認するという方法です。(なお、後半は前半でW0520083:Type qualifier specified more than onceというワーニングが大量に出力されるようになるのを抑止する為のものです。)

    -define="volatile=volatile __evenaccess" -change_message=information=20083



    試しに別スレッドのTOPPERS/ASPのコードをCC-RX V2.03でビルドして変化を確認すると、例えば以下の変化が見付かりましたが、内蔵周辺I/Oレジスタにアクセスしている箇所ではありませんので、問題にならないことが分かります。(もともとCC-RX V2.03では問題になるコードは生成されないと予想していましたので、予想通りではありますが。なお、差分の内容が以下のような単純なものばかりとは限らず、割り付けたレジスタ番号がずれて差分が広い範囲に渡ってしまうこともあるだろうと思います。)

    私が使っているツールで比較するとr_bsp_common.srcで差分が見付かった(行フィルタは日時文字列等を無視させる為)


    内容を確認したところMOV命令によるスタックからのロードが増えていた(この時点で問題にならないことは分かる)


    ソースではvolatile uint64_tのauto変数をuint32_tへキャストしている箇所だった(何ゆえvolatile付きなのかは謎)



    ちなみにプリプロセス処理したソースを比較するとvolatile→volatile __evenaccessになっていることが分かる


    [追記]

    幾つか前の投稿の以下と同様なことですが、volatile uint64_tのloop_cnt_64変数の上位32bitの読み込みが省略されているのは宜しくない気がします。(まだ力尽きたところから先へは進んでいませんが、、、)

    >>volatile 指示されてるオブジェクトへの読み書きが一部でも省略されるのは宜しくない気がしますね。
    >(まだ力尽きたところから先へは進んでいませんが)何となく省略されるのは宜しくない気がしますよね。

  • こんにちは。NoMaYです。自己レスです。

    今日、別スレッドで__evenaccessに関して見落としていたことがあるかもしれないことに気付きました。以下のスレッドの投稿にも書いたように、ひょっとして、I/Oレジスタは常にリトルエンディアンアクセス(或いはビッグエンディアンアクセス)固定かもしれません。そうであれば、__evenaccessの記述が無いとマイコンの設定をビッグエンディアンにして、かつ、CC-RXの設定も合わせてビッグエンディアンにして、という場合、I/Oレジスタに対する #pragma bit_order left 又は right の設定が正しく機能しないかもしれません。

    CC-RX #pragma bit_order left
    japan.renesasrulz.com/cafe_rene/f/002-2095199602/5504/cc-rx-pragma-bit_order-left/30705#30705
     

  • こんにちは。NoMaYです。自己レスの3年後の続きです。

    ちょっと上の話の続きがあります。

    最近Atom IDEとかVisual Studio Codeとか新しい開発環境が出て来てますね(Renesas CSplusと連携させる方法を探したいですね)
    https://japan.renesasrulz.com/cafe_rene/f/forum21/4553/atom-ide-visual-studio-code-renesas-csplus/40135#40135
     

  • 中の人です。volatile 修飾変数へのアクセスを変数の型のサイズで行う -type_size_access_to_volatile オプションを V3.04にて追加しましたので、ぜひご利用ください。

    CC-RX コンパイラ ユーザーズマニュアル (renesas.com)

  • aduさん、こんにちは。NoMaYと申します。

    ご連絡ありがとうございます。利用していきたいと思います。

    中の人です。volatile 修飾変数へのアクセスを変数の型のサイズで行う -type_size_access_to_volatile オプションを V3.04にて追加しましたので、ぜひご利用ください。

    CC-RX コンパイラ ユーザーズマニュアル (renesas.com)