Hi! In Nvidia PTX, "A state space is a storage area with particular characteristics. All variables reside in some state space. [...]". These include:
.const Shared, read-only memory. .global Global memory, shared by all threads. Implemented via 'TARGET_ENCODE_SECTION_INFO', GCC/nvptx then uses special-cased instructions for accessing the respective memory regions. Now, given a 'const' array (with whatever element type; not interesting here), like: extern int * const arr[]; ..., for GCC/C compilation, we access this as '.const' memory: GCC/nvptx 'DATA_AREA_CONST', but for GCC/C++ compilation, we access it as 'DATA_AREA_GLOBAL', and then fault at run time due to mismatch with the definition, which actually is '.const' for both C and C++ compilation. The difference is, when we get to 'TARGET_ENCODE_SECTION_INFO', that for C we've got 'TREE_READONLY(decl)', but for C++ we don't. C: Breakpoint 3, nvptx_encode_section_info (decl=0x7ffff7824720, rtl=0x7ffff7843180, first=1) at ../../source-gcc/gcc/config/nvptx/nvptx.cc:468 468 { (gdb) call debug_tree(decl) <var_decl 0x7ffff7824720 arr type <array_type 0x7ffff77f7f18 type <pointer_type 0x7ffff77f7d20 type <integer_type 0x7ffff76fa5e8 int> readonly unsigned DI size <integer_cst 0x7ffff76eb600 constant 64> unit-size <integer_cst 0x7ffff76eb618 constant 8> align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff77f7d20> BLK align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff77f7f18> readonly used public external read BLK source-gcc/gcc/testsuite/gcc.target/nvptx/const-1-2.c:8:20 align:64 warn_if_not_align:0 context <translation_unit_decl 0x7ffff783a100 source-gcc/gcc/testsuite/gcc.target/nvptx/const-1-2.c> (mem/u/c:BLK (symbol_ref:DI ("arr") <var_decl 0x7ffff7824720 arr>) [1 arr+0 A64]) chain <function_decl 0x7ffff7819f00 main>> Note 'readonly' ('TREE_READONLY') in the third-last line, and '/u' (RTL 'MEM_READONLY_P') in the last line. C++: Breakpoint 3, nvptx_encode_section_info (decl=0x7ffff783fa18, rtl=0x7ffff7844a50, first=1) at ../../source-gcc/gcc/config/nvptx/nvptx.cc:468 468 { (gdb) call debug_tree(decl) <var_decl 0x7ffff783fa18 arr type <array_type 0x7ffff782f738 type <pointer_type 0x7ffff782fe70 type <integer_type 0x7ffff77015e8 int> readonly unsigned type_6 DI size <integer_cst 0x7ffff76eb900 constant 64> unit-size <integer_cst 0x7ffff76eb918 constant 8> align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff782fe70> type_6 BLK align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff782f738> used public external read decl_2 BLK source-gcc/gcc/testsuite/g++.target/nvptx/const-1-2.C:14:20 align:64 warn_if_not_align:0 context <translation_unit_decl 0x7ffff76fe000 source-gcc/gcc/testsuite/g++.target/nvptx/const-1-2.C> (mem/c:BLK (symbol_ref:DI ("arr") <var_decl 0x7ffff783fa18 arr>) [1 arr+0 A64]) chain <function_decl 0x7ffff7830600 __cxa_call_terminate>> Note no 'readonly' ('!TREE_READONLY') in the third-last line, and no '/u' (RTL '!MEM_READONLY_P') in the last line. Is this difference expected? Now, for example, in 'gcc/config/avr/avr.cc', I found code like: tree node0 = node; /* For C++, we have to peel arrays in order to get correct determination of readonlyness. */ do node0 = TREE_TYPE (node0); while (TREE_CODE (node0) == ARRAY_TYPE); if (error_mark_node == node0) return; [...] if (!TYPE_READONLY (node0) && !TREE_READONLY (node)) { That is, in our case, instead of just looking at 'TREE_READONLY (node)', we need: if (TREE_READONLY (node) || TYPE_READONLY (node0)) [DATA_AREA_CONST] else [DATA_AREA_GLOBAL] Is this indeed what we have to do? (It would appear to work in the case analyzed above, but I've not yet checked for other fallout.) Grüße Thomas