llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.97k stars 11.94k forks source link

Unclear for which purpose __STDC_IEC_559__ is defined to 1 under non-strict floating-point models #53132

Open pmor13 opened 2 years ago

pmor13 commented 2 years ago

Sample code:

#include <stdio.h>   // fix for clang, see https://stackoverflow.com/q/69976945/1778275
#if __STDC_IEC_559__ == 1
#pragma message "__STDC_IEC_559__ is 1"
#else
#pragma message "__STDC_IEC_559__ is not 1"
#endif

Invocation:

# clang 13.0.0 on Linux on x86-64
$ clang t0.c -std=c11 -pedantic -Wall -Wextra -ffp-model=fast

Expected diagnostics:

t0.c:5:9: warning: __STDC_IEC_559__ is not 1 [-W#pragma-messages]

Actual diagnostics:

t0.c:3:9: warning: __STDC_IEC_559__ is 1 [-W#pragma-messages]

If clang under non-strict floating-point models does not conform to the specifications in the Annex F, then for which purpose it defines __STDC_IEC_559__ to 1?

pmor13 commented 2 years ago

The __STDC_IEC_559__ is defined to 1 in glibc-2.25/include/stdc-predef.h, while it is expected to be defined by the compiler itself. Since clang does not define __GCC_IEC_559, then __STDC_IEC_559__ is (unexpectedly) defined to 1 by stdc-predef.h.

As a result: under -ffp-model=fast (behaves identically to specifying both -ffast-math and -ffp-contract=fast) AND if stdc-predef.h is included (as a part of #include <standard_header>), then it is unclear, for which purpose the __STDC_IEC_559__ is defined to 1.

Possible solution: implement gcc's behavior regarding __GCC_IEC_559.

pmor13 commented 2 years ago

In contrast with GCC Clang does not preinclude stdc-predef.h.

Hence, Clang violates C11, 6.10.8 Predefined macro names:

None of these macro names, nor the identifier defined, shall be the subject of a

define or a #undef preprocessing directive.

Extra: to remind:

The values of the predefined macros listed in the following subclauses176) (except for _ FILE and LINE _) remain constant throughout the translation unit.

Overall: Clang needs to preinclude stdc-predef.h.

@AaronBallman Consider fixing.

pmor13 commented 2 years ago

Relevant code from glibc, include/features.h:

/* Get definitions of __STDC_* predefined macros, if the compiler has
   not preincluded this header automatically.  */
#include <stdc-predef.h>
llvmbot commented 2 years ago

@llvm/issue-subscribers-clang-driver