On 6/18/26 5:35 AM, Georg-Johann Lay wrote:
Am 15.05.26 um 15:11 schrieb Paul IANNETTA:
On Friday, May 15, 2026 at 09:17:14 PM GMT+9, Thomas Schwinge
<[email protected]> wrote:
[Note that emails to <[email protected]> bounce; please use Paul's
other email address: <[email protected]>.]
Hi!
I'd like to resume this patch submission here, which is adding support
for named address spaces to GNU C++, as is implemented for GNU C. As far
as I can tell, there wasn't any specific technical reason that this patch
review stalled, back then, in 2022-11? (Jason?)
I've now rebased this onto recent GCC trunk, see attached
'0001-c-parser-Support-for-target-address-spaces-in-C.patch'. There were
just a few merge conflicts that I had to fix up (nothing serious), and
I've bootstrap-tested on x86_64-pc-linux-gnu (only, so far).
Hi Paul,
I have one test case where the generated code for avr is not correct:
int func1 (int x)
{
static const __flash int arr[] = { 123, 456 };
return arr[x];
}
The code should read from AS1 but reads from generic space.
Sounds like decay_conversion isn't propagating the address space to the
pointer type.
Is AS1 the same as __flash here?
$ avr-g++ -S -Os as.cpp -v
Target: avr
Configured with: ../../source/gcc-master/configure --target=avr --
enable-languages=c,c++
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 17.0.0 20260615 (experimental) (GCC)
Apart from that, better dumping would be nice to have:
Take for example this function for which correct code is
generated:
int func2 (const __flash int *p, int x)
{
return p[x];
}
With -fdump-tree-optimized the respective dump file reads:
;; Function func2 (_Z5func2PU7__flashKii, funcdef_no=1, decl_uid=2281,
cgraph_uid=3, symbol_order=2)
int func2 (const <address-space-1> int * p, int x)
{
unsigned int x.0_1;
unsigned int _2;
const <address-space-1> int * _3;
int _7;
<bb 2> [local count: 1073741824]:
x.0_1 = (unsigned int) x_4(D);
_2 = x.0_1 * 2;
_3 = p_5(D) + _2; <-- uses AS1
_7 = *_3; <-- uses AS1
return _7;
}
So the dump could show more of the involved non-generic ASes.
Then I have some trouble with constructors:
struct SS { int val; };
const __flash SS ss[] = { 123, 456 };
SS read_ss (int x)
{
return ss[x];
}
as.cpp: In function 'SS read_ss(int)':
as.cpp:10:16: error: no matching function for call to 'SS(const __flash
SS&)'
10 | return ss[x];
| ~~~~^
• there are 3 candidates
• candidate 1: 'constexpr SS::SS(const SS&)' (near match)
as.cpp:1:8:
1 | struct SS
| ^~
• conversion of argument 1 would be ill-formed:
• error: binding reference of type 'const SS&' to 'const __flash
SS' discards qualifiers
as.cpp:10:16:
10 | return ss[x];
| ~~~~^
• candidate 2: 'constexpr SS::SS(SS&&)' (near match)
as.cpp:1:8:
1 | struct SS
| ^~
• conversion of argument 1 would be ill-formed:
• error: cannot bind rvalue reference of type 'SS&&' to lvalue of
type 'const __flash SS'
as.cpp:10:16:
10 | return ss[x];
| ~~~~^
• candidate 3: 'constexpr SS::SS()'
as.cpp:1:8:
1 | struct SS
| ^~
• candidate expects 0 arguments, 1 provided
Shouldn't there be a default constructor that reads from AS1?
At least when the class is trivially copyable?
We might want to add a hack to overload resolution to allow arbitrary
name space conversion for a trivial copy constructor argument, or skip
overload resolution entirely for copying a trivial class.
Is __flash not a subset of the generic address space?
And adding a qualified constructor doesn't work either:
struct SS
{
SS (const __flash SS &ss) : val(ss.val) {}
Can you = default this constructor? I suspect we will need to add
support in defaulted_late_check.
SS (int i) const __flash : val(i) {}
int val;
};
as.cpp:4:22: error: constructors may not be cv-qualified
4 | SS (int i) const __flash : val(i) {}
| ^~~~~~~
Notice that a non-qualified constructor will pop a static
constructor function that writes to __flash, which is invalid
because __flash cannot be changed after load time.
Instead of those invalid qualifiers, declaring the constructor
'constexpr' should work.
Jason