こんにちは。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.pdf4. コンパイラ言語仕様4.1 基本言語仕様4.1.3 処理系依存(10) 型修飾子(参) CC-RLコンパイラ ユーザーズマニュアルwww.renesas.com/ja-jp/doc/products/tool/doc/011/r20ut3123jj0106_ccrl.pdf4. コンパイラ言語仕様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 voidrx630_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_tsil_rew_mem(const uint32_t *mem){ uint32_t data; data = *((const volatile uint32_t *) mem); ←ここに__evenaccessが無いのはリスク要因な気が、、、 return(data);}Inline voidsil_wrw_mem(uint32_t *mem, uint32_t data){ *((volatile uint32_t *) mem) = data; ←ここに__evenaccessが無いのはリスク要因な気が、、、}
もっとも、mstpcrregへの書き込みが以下のスタイルですので、TOPPERS/ASPの慣習では、(たまたま?)大丈夫そうですが、、、([追記] なお、sil_rew_mem()やsil_wrw_mem()のコードに__evenaccessが無いのは、将来のCC-RXのバージョンアップに対するリスク要因である、ような気がして来ましたが、、、)pdic\rx600\rx630_uart.c
/* * SIOドライバのシリアルモードレジスタ(SMR) */static voidrx630_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_tsil_rew_mem(const uint32_t *mem){ uint32_t data; data = *((const volatile uint32_t *) mem); ←ここに__evenaccessが無いのはリスク要因な気が、、、 return(data);}Inline voidsil_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) プログラミング言語Ckikakurui.com/x3/X3010-2003-01.html
中の人です。volatile 修飾変数へのアクセスを変数の型のサイズで行う -type_size_access_to_volatile オプションを V3.04にて追加しましたので、ぜひご利用ください。
CC-RX コンパイラ ユーザーズマニュアル (renesas.com)
こんにちは。NoMaYです。たぶん、私は1つ勘違いをしていて、volatile指定有り__evenaccess指定無しだとobjectへのaccess sizeが保証されなくなる訳ではなくて、そもそも、volatile指定が有ろうと無かろうと、__evenaccess指定無しだとobjectへのaccess sizeが保証されない、のですよね、、、そして、たぶん、世の中にvolatile指定が__evenaccess指定も兼ねているように振舞うコンパイラがあるので、そのようなコンパイラと区別する為、あのようにCC-RXのマニュアルに記載されているのですよね、きっと、、、でも、それはそれとしても、あのTOPPERS/ASPのコードはどうすればよいのだろうか、、、安全なコードにするには、力技で片っ端から__evenaccessを追加していくことになってしまうのだろうか、、、(こういうことって、__evenaccessの意味に気付いた人が1度は罹る麻疹のようなものなのでしょうかね、、、)
わわいさん、リプライをどうもすみません。NoMaYです。すみません、「なにを問題にしてるのかいまいちわかりません」ということで頂いたリプライですが、今度は、私の方が、何を回答して頂いたのかが分からない、状態に陥っています。分からないスパイラルですねwww>通常のメモリアクセスで、アクセスサイズで問題が出ることはあるんでしょうか?通常のメモリアクセスのことを問題にしたつもりは無かったです。通常のメモリアクセスと思われたとすると、TOPPERS/ASPのsil_rew_mem()やsil_wrw_mem()に"mem"という文字列が付いている点からでしょうか。これらは、"mem"という文字列が付いていますが、周辺レジスタを読み書きするものなのです。実際、volatile uint32_t *といった記述があって通常のメモリアクセスには付ける事の無いvolatileが付いているのも、その為なのです。他方、レジスタアクセスの方は確かに_evenaccessを付ければ解決するかな(と思いましたが別スレッドの先程のふじさんのリプライでは解決に至らなかったようです)というところでしたが、そこまで達観することが、まだ私には出来ない、というのが私の最初の投稿ですね。わわいさんは以前に、RXの何かの周辺の動作が何故SHと同じでないのかとぼやいていたように記憶していますが、今の私はそんな感じの状態ですかね。CC-RXではそれを付けるものだと言われても(そして、私自身、ふじさんにそういうことを言ったけれども)、それに類するキーワードはCC-RX以外では見掛けない(身近な例ではCC-RLでは必要がない)ので、CC-RXだけが何故そういうものをユーザに付けさせるのか、そこを当たり前に思うようになる前の状態ですね。
わわいさん、こんにちは。NoMaYです。そういえば、わわいさんは以前にTOPPERSをSHに移植したことがあると仰っていたように記憶していますが、もしその時にSHコンパイラでは__evenaccessをあちらこちらに付けなければならないことが急遽発覚した、しかも所謂共通部のソースに付けなければらない、という状況になったら、どうされますか?素直に観念して__evenaccessを付けていくのがプロですかね?
アクセスサイズの保証は兎も角として、volatile 指示されてるオブジェクトへの読み書きが一部でも省略されるのは宜しくない気がしますね。
fujitaさん、こんにちは、リプライをどうもです。NoMaYです。>volatile 指示されてるオブジェクトへの読み書きが一部でも省略されるのは宜しくない気がしますね。(まだ力尽きたところから先へは進んでいませんが)何となく省略されるのは宜しくない気がしますよね。そして、規格書の文面からは、(今回の件はアクセス対象がshortなので、) 16bitリードを8bitリード×2、16bitライトを8bitライト×2、で構成したりしてもそれは処理系定義であるからOKである、ということであるような気配がしますよね。(ここは私が観念しつつある点です。)(もっとも、16bitリード命令や16bitライト命令があるRXで、そのようにリードやライトをわざわざ8bitずつに分割する必然性は無いと思いますが、、、)あと、今回の件から離れて仮にアクセス対象が8bitだったとして、「抽象計算機の規則に厳密に従って評価しなければならない」という条件を満たすことが出来る場合には、アクセスをビット操作命令で行ったりしてもそれは処理系定義であるからOKである、ということでもあるような気配もします、、、
こんにちは。NoMaYです。CC-RLの他にもう1つ身近(とは言い難いところもありますが)なコンパイラにCC-RHがあったことを思い出し、マニュアルを見てみました。ですが、ちょっと記載がC言語の文法的な話としてはチグハグなのでは、という感じがしました。TOPPERS/ASPのソースのようにvolatile型修飾子はポインタ型と組み合わせることが出来るのですが、以下の画面コピーの記載内容ですと、ポインタ経由でアクセスする場合は実行時にコンパイラのランタイムライブラリとかでアドレスをチェックしてアドレスに依存してアクセス方法を変えている、ということになってしまう(さすがにそれは無いと思います)のではないでしょうか、、、 (先ほど、先日のCC-RLのマニュアルを見直してみたら、CC-RLの記載もCC-RHの記載と同様にチグハグな記載でしたね、、、) それはそれとして、CC-RHでは、マニュアルの別の頁に注意事項としてvolatile修飾子に関する記述がありました。なお、__evenaccessというキーワードはありませんでした、、、CC-RHコンパイラ ユーザーズマニュアルwww.renesas.com/ja-jp/doc/products/tool/doc/011/r20ut3516jj0104-ccrh.pdf4. コンパイラ言語仕様4.1 基本言語仕様4.1.3 処理系依存(32) 型修飾子11. 注意事項11.1 volatile修飾子この際ですので、最初の投稿で調べていたCC-RLとCC-RXのマニュアルの画面コピーも以下に載せておきます。CC-RLコンパイラ ユーザーズマニュアルwww.renesas.com/ja-jp/doc/products/tool/doc/011/r20ut3123jj0106_ccrl.pdf4. コンパイラ言語仕様4.1 基本言語仕様4.1.3 処理系依存(33) 型修飾子CC-RXコンパイラ ユーザーズマニュアルwww.renesas.com/ja-jp/doc/products/tool/doc/011/r20ut3248jj0105-ccrx.pdf4. コンパイラ言語仕様4.1 基本言語仕様4.1.3 処理系依存(10) 型修飾子
Higetakaさん、こんにちは。情報を有難う御座います。NoMaYです。H8,H8S,H8SXのiodefine.hとC/C++コンパイラのマニュアルを調べてみました。気付いた点は、H8系マイコンはリードモデファイライトされる可能性のある内蔵周辺I/Oレジスタは殆ど全て8bitアクセス可能になっているらしい、という点です。だから、コンパイラにvolatile型修飾子でアクセスサイズを保証させるようにする、というモチベーションが無かったのでしょうね。ところが、H8系マイコンとは内蔵周辺I/Oレジスタの事情が異なるRXマイコンのCC-RXで仕様をそのまま引き継いだことで、今回のようなツッコミを入れられてしまった、ということになるのかなと思いました。Higetakaさんが提案されたようなコンパイラの改善があるといい、と私も思います。以下、調べた時の画面コピーです。H8,H8S,H8SXのiodefine.hは175ファイルあれど、、、__evenaccessが使われているのは、3ファイル、5箇所、だけだった、、、ひょっとして"even"の起源は、ビッグエンディアンのH8で偶数アドレスへ偶数バイトアクセスさせる、からだろうか、、、H8S、H8/300シリーズ C/C++コンパイラ、アセンブラ、最適化リンケージエディタコンパイラパッケージVer.7.00 ユーザーズマニュアルwww.renesas.com/ja-jp/doc/products/tool/004/rjj10j2552_r0c40008xsw07rum.pdf10. C/C++言語仕様10.1 言語仕様10.1.1 コンパイラの仕様(9) 型修飾子18. バージョンアップにおける注意事項18.2 追加・改善内容18.2.2 コンパイラの追加・改善(1) Ver.4.0 の主な追加・改善機能(2) Ver.4.0 → Ver.6.0 の主な追加・改善機能10. C/C++言語仕様10.2 拡張機能10.2.1 #pragma、キーワード(3) その他の拡張機能