[gcc r17-3340] AVR: Add option for strict address space subset relations.

Georg-Johann Lay via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:cbf217f4c7076d4e23a34735d403a192d4e78191

commit r17-3340-gcbf217f4c7076d4e23a34735d403a192d4e78191
Author: Georg-Johann Lay <[email protected]>
Date:   Mon Aug 17 21:17:03 2026 +0200

    AVR: Add option for strict address space subset relations.
    
    To date, each named address space is implemented as a subset
    of all the other address spaces, which allows code like
    
       char read_char (const char *addr, bool in_flash)
       {
          return in_flash
            ? *(const __flash char*) addr  // Read from program memory.
            : *addr;                       // Read from RAM.
       }
    
    even though __flash is not a subset of Generic.
    
    This patch introduces new target option -mstrict-addr-space-subsets
    which instructs avr_addr_space_subset_p to implement the address
    space subset relations like they actually are, i.e.
    
       __memx > __flashx > __flash, __flash1, ..., __flash5
       __memx > Generic
    
    gcc/
            * config/avr/avr.opt (-mstrict-addr-space-subsets): New
            target option.
            * config/avr/avr.cc (avr_addr_space_subset_p): Use it.
            * doc/invoke.texi (AVR Options): Document it.

Diff:
---
 gcc/config/avr/avr.cc  | 22 +++++++++++-----------
 gcc/config/avr/avr.opt |  4 ++++
 gcc/doc/invoke.texi    | 19 ++++++++++++++++++-
 3 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index a873a1262843..084ee2d3715a 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -15404,26 +15404,26 @@ avr_addr_space_convert (rtx src, tree type_old, tree type_new)
 }
 
 
-/* Implement `TARGET_ADDR_SPACE_SUBSET_P'.  */
+/* Helps the next two functions.  */
 
 static bool
-avr_addr_space_subset_p (addr_space_t /*subset*/, addr_space_t /*superset*/)
+avr_addr_space_contains (addr_space_t super, addr_space_t sub)
 {
-  /* Allow any kind of pointer mess.  */
-
-  return true;
+  return (super == sub
+	  || super == ADDR_SPACE_MEMX
+	  || (super == ADDR_SPACE_FLASHX
+	      && sub != ADDR_SPACE_MEMX && ! ADDR_SPACE_GENERIC_P (sub)));
 }
 
 
-/* Helps the next function.  */
+/* Implement `TARGET_ADDR_SPACE_SUBSET_P'.  */
 
 static bool
-avr_addr_space_contains (addr_space_t super, addr_space_t sub)
+avr_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
 {
-  return (super == sub
-	  || super == ADDR_SPACE_MEMX
-	  || (super == ADDR_SPACE_FLASHX
-	      && sub != ADDR_SPACE_MEMX && ! ADDR_SPACE_GENERIC_P (sub)));
+  // Allow any kind of pointer casts with -mno-strict-addr-space-subsets.
+  return (!avropt_strict_addr_space_subsets
+	  || avr_addr_space_contains (superset, subset));
 }
 
 
diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt
index 97d207726ba9..d56061b50b6c 100644
--- a/gcc/config/avr/avr.opt
+++ b/gcc/config/avr/avr.opt
@@ -115,6 +115,10 @@ msplit-ldst
 Target Var(avropt_split_ldst) Init(0) Optimization
 Optimization. Split most of the load and store instructions into byte load and stores.
 
+mstrict-addr-space-subsets
+Target Var(avropt_strict_addr_space_subsets) Init(0)
+Implement strict named address space subset relations.
+
 mstrict-X
 Target Var(avropt_strict_X) Init(0) Optimization
 Optimization. When accessing RAM, use X as imposed by the hardware, i.e. just use pre-decrement, post-increment and indirect addressing with the X register.  Without this option, the compiler may assume that there is an addressing mode X+const similar to Y+const and Z+const and emit instructions to emulate such an addressing mode for X.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 2e53a8c8a7ee..d6cfc4598531 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -991,7 +991,7 @@ Objective-C and Objective-C++ Dialects}.
 -mdouble=@var{bits}  -mlong-double=@var{bits}  -mno-call-main
 -mn_flash=@var{size}  -mfract-convert-truncate  -mno-interrupts
 -mmain-is-OS_task  -mrelax  -mpmem-wrap-around
--mrmw  -mstrict-X  -mtiny-stack
+-mrmw  -mstrict-addr-space-subsets  -mstrict-X  -mtiny-stack
 -mrodata-in-ram  -msplit-bit-shift  -msplit-ldst  -mshort-calls
 -mskip-bug  -muse-nonzero-bits  -nodevicelib  -nodevicespecs
 -Wasm-len-notes  -Waddr-space-convert  -Wmisspelled-isr}
@@ -24595,6 +24595,23 @@ aspect of the optimization.
 @item -mfuse-move2
 Run a post combine optimization pass that tries to fuse move instructions.
 
+@opindex mstrict-addr-space-subsets
+@item -mstrict-addr-space-subsets
+Impose strict named address space subset relations.  Without this option,
+every address space is considered to be a subset of all the other spaces,
+which allows to write code like
+@example
+char read_char (const char *addr, bool in_flash)
+@{
+   return in_flash
+     ? *(const __flash char*) addr  // Read from program memory.
+     : *addr;                       // Read from RAM.
+@}
+@end example
+When the option is on, such code is rejected since address space
+@code{__flash} is not a subset of the generic space, and hence the
+cast in the above code is prohibited.
+
 @opindex mstrict-X
 @item -mstrict-X
 Use address register @code{X} in a way proposed by the hardware.  This means
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.