llvm / llvm/llvm-project

some floating point expressions in unions not done at runtime as required by C

Open
#201,258 4 comments 0 reactions 0 assignees View on GitHub
clang:codegen floating-point
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

The following code does not conform to C23. This is on both Intel x64 and ARM.

```c
/* clang does automatic union wrong of NaN expression */

/*
C23 N3219
F.8.5 Constant expressions
1 An arithmetic constant expression of floating type, other than one
in an initializer for an object that has static or thread storage
duration or that is declared with storage-class specifier constexpr,
is evaluated (as if) during execution; thus, it is affected by any
operative floating-point control modes and raises floating-point
exceptions as required by ISO/IEC 60559 (provided the state for the
FENV_ACCESS pragma is "on").434)
*/

#include
#include
#include
#pragma STDC FENV_ACCESS ON

#define INV (0.f / 0.f)

static int flags;

static void test1(void){
static union { float f; int i; } uf0 = { INV };
assert( isnan( uf0.f ) );
flags = fetestexcept( FE_ALL_EXCEPT );
assert( 0 == flags ); /* make sure right flag set */
}

static void test2(void){
static const union { float f; int i; } uf0 = { INV };
assert( isnan( uf0.f ) );
flags = fetestexcept( FE_ALL_EXCEPT );
assert( 0 == flags ); /* make sure right flag set */
}

static void test3(void){
const union { float f; int i; } uf0 = { INV };
assert( isnan( uf0.f ) );
flags = fetestexcept( FE_ALL_EXCEPT );
assert( 0 != flags ); /* make sure right flag set */
assert( FE_INVALID == flags ); /* make sure right flag set */
}

static void test4(void){
union { float f; int i; } uf0 = { INV };
assert( isnan( uf0.f ) );
flags = fetestexcept( FE_ALL_EXCEPT );
assert( 0 != flags ); /* make sure right flag set */
assert( FE_INVALID == flags ); /* make sure right flag set */
}

int main(void){
feclearexcept( FE_ALL_EXCEPT );
test1();
feclearexcept( FE_ALL_EXCEPT );
test2();
feclearexcept( FE_ALL_EXCEPT );
test3();
feclearexcept( FE_ALL_EXCEPT );
test4();
return 0;
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.