https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125642

            Bug ID: 125642
           Summary: [LoongArch] `__FRACT_FBIT__` predefined in C++ mode
                    despite `_Fract` keyword being unsupported
           Product: gcc
           Version: 16.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wszqkzqk at qq dot com
  Target Milestone: ---

On the LoongArch64 target, the C++ preprocessor defines `__FRACT_FBIT__` even
in C++ mode. However, the GCC C++ frontend does not recognize the ISO/IEC TR
18037 fixed-point keywords `_Fract` and `_Accum`, causing any C++ code that
uses these types or relies on the macros to enable fixed-point features to fail
compilation.

This is inconsistent with the x86_64 target, where `__FRACT_FBIT__` is not
predefined in C++ mode.

According to https://gcc.gnu.org/onlinedocs/gcc/Fixed-Point.html, it's a C-only
extension and should not be defined in C++ mode.

> "As an extension, GNU C supports fixed-point types as defined in the N1169 
> draft of ISO/IEC DTR 18037."

This behavior is not observed on x86_64, where `__FRACT_FBIT__` is not
predefined in C++ mode. This indicates the bug is LoongArch64-specific.

## Steps to Reproduce

Run the following command on a LoongArch64 host:

```bash
g++ -dM -E -x c++ /dev/null | grep __FRACT_FBIT__
```

Observed result on LoongArch64 but not on x86_64:

```
#define __FRACT_FBIT__ 15
```

Also, a minimal test:

```cpp
#include <cstdio>

int main() {
#ifdef __FRACT_FBIT__
    short _Fract a = 0.5HR;
    std::printf("DEFINED: sizeof(short _Fract)=%zu\n", sizeof(a));
#else
    std::printf("NOT_DEFINED\n");
#endif
    return 0;
}
```

On loonarch64:

```
test-fixed-point-litmus.cpp: In function ‘int main()’:
test-fixed-point-litmus.cpp:5:18: error: expected initializer before ‘a’
    5 |     short _Fract a = 0.5HR;
      |                  ^
test-fixed-point-litmus.cpp:6:63: error: ‘a’ was not declared in this scope
    6 |     std::printf("DEFINED: sizeof(short _Fract)=%zu\n", sizeof(a));
      |                                                               ^
```

While on x86_64, it will print `NOT_DEFINED` as expected.

Reply via email to