Skip to content

Conversation

@projectgus
Copy link
Contributor

@projectgus projectgus commented May 9, 2025

Summary

This PR is a collection of commits to fix MicroPython building under GCC 15.1 (host x86-64 toolchain, follow-up fixes may be necessary in the future for cross-toolchains).

Testing

  • Clean builds of unix port and mpy-cross using GCC 15.1 as the host compiler. Verified build success only.

Trade-offs and Alternatives

  • As noted in the linked issue, disabling -Werror by default (but leaving it on for CI and optionally for developers) would avoid end user build failures caused by newly added warnings. This seems like a good idea but it's a little fiddly to do in a uniform way across MicroPython's many build systems. In any case, addressing the warnings (as in this PR) is still necessary at some point.
  • Could alternatively disable this warning (at risk of missing a case where it reveals a termination issue), or use the non-string attribute as per py/emitinlinethumb: Use nonstring attribute to suppress compiler warnings #17215. However this approach still seems quite readable.

@projectgus projectgus added py-core Relates to py/ directory in source extmod Relates to extmod/ directory in source labels May 9, 2025
@codecov
Copy link

codecov bot commented May 9, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.54%. Comparing base (d01a981) to head (bfd5a03).
Report is 4 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #17269      +/-   ##
==========================================
- Coverage   98.54%   98.54%   -0.01%     
==========================================
  Files         169      169              
  Lines       21898    21896       -2     
==========================================
- Hits        21580    21578       -2     
  Misses        318      318              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@projectgus
Copy link
Contributor Author

error: unknown warning option '-Wno-unterminated-string-initialization'; did you mean '-Wno-nonportable-vector-initialization'? [-Werror,-Wunknown-warning-option]

Oh clang, why you gotta be so different!

@github-actions
Copy link

github-actions bot commented May 9, 2025

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:   -32 -0.004% standard
      stm32:   -16 -0.004% PYBV10
     mimxrt:    -8 -0.002% TEENSY40
        rp2:    -8 -0.001% RPI_PICO_W
       samd:    -8 -0.003% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:   -16 -0.004% VIRT_RV32

@projectgus projectgus force-pushed the bugfix/gcc15_1_initializers branch from 3186816 to 370850d Compare May 9, 2025 04:35
@dpgeorge
Copy link
Member

dpgeorge commented May 9, 2025

Nice that this reduced code size! Not sure why...

@projectgus projectgus changed the title py,extmod: Fixes for GCC 15.1 unterminated string literal warning lib,py,extmod: Fixes for GCC 15.1 unterminated string literal warning May 9, 2025
@projectgus
Copy link
Contributor Author

error: unknown warning option '-Wno-unterminated-string-initialization'; did you mean '-Wno-nonportable-vector-initialization'? [-Werror,-Wunknown-warning-option]

Oh clang, why you gotta be so different!

Have switched to use an array initialiser instead, it's too fiddly to keep clang happy and no lose -Wunknown-warning-option for unrecognised enabled warnings.

@projectgus
Copy link
Contributor Author

Nice that this reduced code size! Not sure why...

Yeah... my best guess is that previously the string literal in moductypes wasn't being de-duplicated, or maybe wasn't de-duplicated during some earlier optimisation pass so less efficient asm was generated. 🤷

@dpgeorge
Copy link
Member

dpgeorge commented May 9, 2025

  • Patch lib/littlefs/lfs1.c to use an array initialiser. Patching upstream source (even unmaintained upstream) seems drastic

I think this is the right thing to do in this situation. We've done it in the past for lfs2 code, eg 9269835

projectgus added 3 commits May 9, 2025 14:50
Avoids the new Wunterminated-string-literal when compiled with gcc 15.1.

Also split out the duplicate string to a top-level array (probably the
duplicate string literal was interned, so unlikely to have any impact.)

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <[email protected]>
Avoids the new Wunterminated-string-literal when compiled with gcc 15.1.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <[email protected]>
Avoids the new Wunterminated-string-literal when compiled with gcc 15.1.

It would be preferable to just disable this warning, but Clang
-Wunknown-warning-option kicks in even when disabling warnings so this
becomes fiddly to apply.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <[email protected]>
@projectgus projectgus force-pushed the bugfix/gcc15_1_initializers branch from 370850d to bfd5a03 Compare May 9, 2025 04:50
Copy link
Member

@dpgeorge dpgeorge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

Tested by building mpy-cross, and unix standard and coverage with GCC15.1.1.

@dpgeorge
Copy link
Member

dpgeorge commented May 9, 2025

Nice that this reduced code size! Not sure why...

Yeah... my best guess is that previously the string literal in moductypes wasn't being de-duplicated, or maybe wasn't de-duplicated during some earlier optimisation pass so less efficient asm was generated. 🤷

I got interested and took a look. Indeed it's as you say, it wasn't deduplicated in an earlier phase and so less optimal machine code was generated.

In uctypes_struct_subscr and uctypes_struct_attr_op both get_unaligned and set_unaligned are called and inlined by the compiler. They both have separate references to the common string, and the compiler dedups the string only after they are inlined. So there remain two references to the same string in the const data.

Eg before this PR:

00000000 <uctypes_struct_subscr>:
   0:   e92d 43f0       stmdb   sp!, {r4, r5, r6, r7, r8, r9, lr}
   4:   4605            mov     r5, r0
   6:   b085            sub     sp, #20
   8:   4614            mov     r4, r2

<cut>

 11c:   e7de            b.n     dc <uctypes_struct_subscr+0xdc>
 11e:   4614            mov     r4, r2
 120:   e7a1            b.n     66 <uctypes_struct_subscr+0x66>
 122:   bf00            nop
        ...
                        124: R_ARM_ABS32        mp_type_tuple
                        128: R_ARM_ABS32        .rodata.uctypes_struct_subscr.str1.1
 12c:   00000005        .word   0x00000005
                        12c: R_ARM_ABS32        .rodata.uctypes_struct_subscr.str1.1
        ...
                        130: R_ARM_ABS32        mp_type_IndexError
                        134: R_ARM_ABS32        .rodata.type2char.1
                        138: R_ARM_ABS32        .rodata.type2char.1
                        13c: R_ARM_ABS32        .rodata.uctypes_struct_type

And then with this PR:

00000000 <uctypes_struct_subscr>:
   0:   e92d 43f0       stmdb   sp!, {r4, r5, r6, r7, r8, r9, lr}
   4:   4605            mov     r5, r0
   6:   b085            sub     sp, #20
   8:   4614            mov     r4, r2

<cut>

 11c:   e7de            b.n     dc <uctypes_struct_subscr+0xdc>
 11e:   4614            mov     r4, r2
 120:   e7a1            b.n     66 <uctypes_struct_subscr+0x66>
 122:   bf00            nop
        ...
                        124: R_ARM_ABS32        mp_type_tuple
                        128: R_ARM_ABS32        .rodata.uctypes_struct_subscr.str1.1
 12c:   00000005        .word   0x00000005
                        12c: R_ARM_ABS32        .rodata.uctypes_struct_subscr.str1.1
        ...
                        130: R_ARM_ABS32        mp_type_IndexError
                        134: R_ARM_ABS32        .rodata.type2char
                        138: R_ARM_ABS32        .rodata.uctypes_struct_type

@projectgus projectgus merged commit ae6062a into micropython:master May 9, 2025
64 checks passed
@projectgus projectgus deleted the bugfix/gcc15_1_initializers branch May 9, 2025 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

extmod Relates to extmod/ directory in source py-core Relates to py/ directory in source

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Build fails with GCC 15 due to -Wunterminated-string-initialization

2 participants