nicolasWDC opened a new pull request, #19060:
URL: https://github.com/apache/nuttx/pull/19060

   *Note: Please adhere to [[Contributing 
Guidelines](https://github.com/apache/nuttx/blob/master/CONTRIBUTING.md)](https://github.com/apache/nuttx/blob/master/CONTRIBUTING.md).*
   
   ## Summary
   
   Fix Bug #19059.
   
   `include/cxx/cmath` imports C math symbols into `std::` only when 
`FLT_EVAL_METHOD` is defined and equals zero.
   
   With `arm-none-eabi-g++`, the compiler defines `__FLT_EVAL_METHOD__`, but 
`FLT_EVAL_METHOD` is not visible when the NuttX `cmath` shim evaluates its 
guards. As a result, functions such as `std::log` and `std::pow` are not 
exposed, even though the corresponding C symbols are available from NuttX 
`math.h`.
   
   This change defines `FLT_EVAL_METHOD` locally from `__FLT_EVAL_METHOD__` 
when needed in the non-`CONFIG_LIBM_TOOLCHAIN` path.
   
   ## Impact
   
   Improve compatibility when using external GCC-based toolchains with the 
NuttX C++ `<cmath>` shim.
   
   This fixes compilation of valid C++ code such as:
   
   ```cpp
   #include <cmath>
   
   int test_cmath_symbols()
   {
     double x = 2.0;
     return static_cast<int>(std::log(x) + std::pow(x, 2.0));
   }
   ```
   
   Before this change, the above code fails with:
   
   ```text
   error: 'log' is not a member of 'std'; did you mean 'log'?
   error: 'pow' is not a member of 'std'; did you mean 'pow'?
   ```
   
   The change only affects the NuttX `cmath` shim path, when 
`CONFIG_LIBM_TOOLCHAIN` is not enabled. The `CONFIG_LIBM_TOOLCHAIN` path that 
uses `include_next <cmath>` is unchanged.
   
   ## Testing
   
   Tested with:
   
   * Host: Linux Docker container
   * Target board: `xmc4800-relax`
   * Architecture: ARM Cortex-M4
   * Toolchain: `arm-none-eabi-g++` 12.3.1
   * C++ standard: `gnu++20`
   * Configuration:
   
     * `CONFIG_CXX_STANDARD="gnu++20"`
     * `CONFIG_LIBM_TOOLCHAIN` not enabled
   
   The issue was reproduced with this standalone test case:
   
   ```cpp
   #include <cmath>
   
   int test_cmath_symbols()
   {
     double x = 2.0;
     return static_cast<int>(std::log(x) + std::pow(x, 2.0));
   }
   ```
   
   Compile command:
   
   ```sh
   arm-none-eabi-g++ \
     -std=gnu++20 \
     -mlittle-endian -march=armv7e-m -mtune=cortex-m4 \
     -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb \
     -DCONFIG_WCHAR_BUILTIN -D__NuttX__ \
     -isystem /build/nuttx/include/cxx \
     -isystem /build/nuttx/include \
     -c /tmp/test_cmath.cpp -o /tmp/test_cmath.o
   ```
   
   Before the fix, this failed with:
   
   ```text
   /tmp/test_cmath.cpp: In function 'int test_cmath_symbols()':
   /tmp/test_cmath.cpp:5:34: error: 'log' is not a member of 'std'; did you 
mean 'log'?
       5 |     return static_cast<int>(std::log(x) + std::pow(x, 2.0));
         |                                  ^~~
   In file included from /build/nuttx/include/cxx/cmath:42,
                    from /tmp/test_cmath.cpp:1:
   /build/nuttx/include/math.h:327:13: note: 'log' declared here
     327 | double      log   (double x);
         |             ^~~
   /tmp/test_cmath.cpp:5:48: error: 'pow' is not a member of 'std'; did you 
mean 'pow'?
       5 |     return static_cast<int>(std::log(x) + std::pow(x, 2.0));
         |                                                ^~~
   /build/nuttx/include/math.h:246:13: note: 'pow' declared here
     246 | double      pow   (double b, double e);
         |             ^~~
   ```
   
   The preprocessor output showed that the compiler provides 
`__FLT_EVAL_METHOD__`, but not `FLT_EVAL_METHOD`:
   
   ```sh
   echo '#include <cmath>' | arm-none-eabi-g++ \
     -std=gnu++20 \
     -mlittle-endian -march=armv7e-m -mtune=cortex-m4 \
     -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb \
     -DCONFIG_WCHAR_BUILTIN -D__NuttX__ \
     -isystem /build/nuttx/include/cxx \
     -isystem /build/nuttx/include \
     -dM -E -x c++ - | grep "CONFIG_HAVE_DOUBLE\|FLT_EVAL_METHOD"
   ```
   
   Output:
   
   ```text
   #define __FLT_EVAL_METHOD__ 0
   #define __FLT_EVAL_METHOD_TS_18661_3__ 0
   #define CONFIG_HAVE_DOUBLE 1
   ```
   
   After the fix, the standalone `<cmath>` test compiles successfully.
   
   I also rebuilt the NuttX export for `xmc4800-relax` and verified that a real 
external C++ dependency build that uses `std::log` and `std::pow` in `<cmath>` 
now passes this compilation step.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to