This patch lets

const __flashx *x = NULL;

compile to x = 0x000000 instead of the previous x = 0x800000.

Apart from that, -Waddr-space-convert warns no more for such
code, which removes some itches when using a null pointer.
Dito for __flash.

Applied as obvious.

Johann

--

AVR: target/121277 - Don't load 0x800000 with const __flashx *x = NULL.

Converting from generic AS to __flashx used the same rule like
for __memx, which tags RAM (generic AS) locations by setting bit 23.
The justification was that generic isn't a subset of __flashx, though
that lead to surprises with code like const __flashx *x = NULL.

The natural thing to do is to just load 0x000000 in that case,
so that the null pointer works in __flashx as expected.

Apart from that, converting NULL to __flashx (or __flash) no more
raises a -Waddr-space-convert diagnostic.

gcc/
        PR target/121277
        * config/avr/avr.cc (avr_addr_space_convert): When converting
        from generic AS to __flashx, don't set bit 23.
        (avr_convert_to_type): Don't -Waddr-space-convert when NULL
        is converted to __flashx or to __flash.
    AVR: target/121277 - Don't load 0x800000 with const __flashx *x = NULL.
    
    Converting from generic AS to __flashx used the same rule like
    for __memx, which tags RAM (generic AS) locations by setting bit 23.
    The justification was that generic isn't a subset of __flashx, though
    that lead to surprises with code like const __flashx *x = NULL.
    
    The natural thing to do is to just load 0x000000 in that case,
    so that the null pointer works in __flashx as expected.
    
    Apart from that, converting NULL to __flashx (or __flash) no more
    raises a -Waddr-space-convert diagnostic.
    
    gcc/
            PR target/121277
            * config/avr/avr.cc (avr_addr_space_convert): When converting
            from generic AS to __flashx, don't set bit 23.
            (avr_convert_to_type): Don't -Waddr-space-convert when NULL
            is converted to __flashx or to __flash.

diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index c469297d6d0..94684468de3 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -14984,10 +14984,11 @@ avr_addr_space_convert (rtx src, tree type_old, tree type_new)
 
       /* Linearize memory: RAM has bit 23 set.  When as_new = __flashx then
 	 this is basically UB since __flashx mistreats RAM addresses, but there
-	 is no way to bail out.  (Though -Waddr-space-convert will tell.)  */
+	 is no way to bail out.  (Though -Waddr-space-convert will tell.)
+	 ...but PR121277 is confusing, in particular when NULL is coming in. */
 
       int msb = ADDR_SPACE_GENERIC_P (as_old)
-	? 0x80
+	? as_new == ADDR_SPACE_MEMX ? 0x80 : 0x00
 	: avr_addrspace[as_old].segment;
 
       src = force_reg (Pmode, src);
@@ -15085,10 +15086,16 @@ avr_convert_to_type (tree type, tree expr)
 	  const char *name_old = avr_addrspace[as_old].name;
 	  const char *name_new = avr_addrspace[as_new].name;
 
-	  warning (OPT_Waddr_space_convert,
-		   "conversion from address space %qs to address space %qs",
-		   ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old,
-		   ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new);
+	  // Be relaxed when NULL is used, and when 0x0 stands for
+	  // address 0x0.
+	  bool nowarn = (expr == null_pointer_node
+			 && (as_new == ADDR_SPACE_FLASHX
+			     || as_new == ADDR_SPACE_FLASH));
+	  if (!nowarn)
+	    warning (OPT_Waddr_space_convert,
+		     "conversion from address space %qs to address space %qs",
+		     ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old,
+		     ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new);
 
 	  return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);
 	}

Reply via email to