www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 23550] New: ImportC: Constant folding doesn't follow C99

https://issues.dlang.org/show_bug.cgi?id=23550

          Issue ID: 23550
           Summary: ImportC: Constant folding doesn't follow C99 semantics
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: ibuclaw gdcproject.org

DMD doesn't follow section 5.2.4.2.2 Characteristics of floating types.

Specifically:
---
Except for assignment and cast (which remove all extra range and precision),
the values yielded by operators with floating operands and values subject to
the usual arithmetic conversions and of floating constants are evaluated to a
format whose range and precision may be greater than required by the type. The
use of evaluation formats is characterized by the implementation-defined value
of FLT_EVAL_METHOD.

   -1  indeterminable;

    0  evaluate all operations and constants just to the range and precision of
the type;

    1  evaluate operations and constants of type float and double to the range
and precision of the double type, evaluate long double operations and constants
to the range and precision of the long double type;

    2  evaluate all operations and constants to the range and precision of the
long double type.

All other negative values for FLT_EVAL_METHOD characterize
implementation-defined behavior.
---

Typically the default value of __FLT_EVAL_METHOD__ is 0.  DMD evaluates
operations at compile-time as-if __FLT_EVAL_METHOD__ is 2.

e.g:
---
#include <stdint.h>
#include <stdlib.h>
int main()
{
    int64_t a = INT64_MIN;
    int64_t b = INT64_MAX;
    double c = 0.0;

    if (-1 != (a + b) + c)                     abort();
    if (-1 != (INT64_MIN + INT64_MAX) + 0.0)   abort();

    if ( 0 != a + (b + c))                     abort();
    if ( 0 != INT64_MIN + (INT64_MAX + 0.0))   abort(); // fails

    if ( 0 != a + (double)(b))                 abort();
    if ( 0 != INT64_MIN + (double)(INT64_MAX)) abort(); // fails
}
---

--
Dec 11 2022