diff --git a/gcc/c-family/c-lex.cc b/gcc/c-family/c-lex.cc index f7168ce6fc04..8e1829389385 100644 --- a/gcc/c-family/c-lex.cc +++ b/gcc/c-family/c-lex.cc @@ -1347,7 +1347,12 @@ interpret_float (const cpp_token *token, unsigned int flags, if (flags & CPP_N_USERDEF) copylen -= strlen (suffix); else if (flags & CPP_N_DFLOAT) - copylen -= 2; + { + if (ISDIGIT (token->val.str.text[copylen - 1])) + copylen -= (flags & CPP_N_LARGE) ? 4 : 3; + else + copylen -= 2; + } else { if ((flags & CPP_N_WIDTH) != CPP_N_MEDIUM) diff --git a/gcc/testsuite/gcc.dg/dfp/c11-constants-3.c b/gcc/testsuite/gcc.dg/dfp/c11-constants-3.c new file mode 100644 index 000000000000..63b9a71b8aea --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/c11-constants-3.c @@ -0,0 +1,13 @@ +/* Test that DFP constants are diagnosed in C11 mode: -pedantic. */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic" } */ + +int a = (int) 1.1D32; /* { dg-warning "C23 feature" } */ +int b = (int) 2.d32; /* { dg-warning "C23 feature" } */ +int c = (int) .33D64; /* { dg-warning "C23 feature" } */ +int d = (int) 2e1d64; /* { dg-warning "C23 feature" } */ +int e = (int) .3e2D128; /* { dg-warning "C23 feature" } */ +int f = (int) 4.5e3d128; /* { dg-warning "C23 feature" } */ +int g = (int) 5.e0D32; /* { dg-warning "C23 feature" } */ +int h = (int) 1e+2d32; /* { dg-warning "C23 feature" } */ +int i = (int) 1000e-3D128; /* { dg-warning "C23 feature" } */ diff --git a/gcc/testsuite/gcc.dg/dfp/c11-constants-4.c b/gcc/testsuite/gcc.dg/dfp/c11-constants-4.c new file mode 100644 index 000000000000..09e2ae1bdd31 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/c11-constants-4.c @@ -0,0 +1,13 @@ +/* Test that DFP constants are diagnosed in C11 mode: -pedantic-errors. */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +int a = (int) 1.1D32; /* { dg-error "C23 feature" } */ +int b = (int) 2.d32; /* { dg-error "C23 feature" } */ +int c = (int) .33D64; /* { dg-error "C23 feature" } */ +int d = (int) 2e1d64; /* { dg-error "C23 feature" } */ +int e = (int) .3e2D128; /* { dg-error "C23 feature" } */ +int f = (int) 4.5e3d128; /* { dg-error "C23 feature" } */ +int g = (int) 5.e0D32; /* { dg-error "C23 feature" } */ +int h = (int) 1e+2d32; /* { dg-error "C23 feature" } */ +int i = (int) 1000e-3D128; /* { dg-error "C23 feature" } */ diff --git a/gcc/testsuite/gcc.dg/dfp/c23-constants-3.c b/gcc/testsuite/gcc.dg/dfp/c23-constants-3.c new file mode 100644 index 000000000000..7b09715a4bb4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/c23-constants-3.c @@ -0,0 +1,39 @@ +/* Test that DFP constants are accepted in C23 mode. */ +/* { dg-do run } */ +/* { dg-options "-std=c23 -pedantic-errors" } */ + +int a = (int) 1.1D32; +int b = (int) 2.d32; +int c = (int) .33D64; +int d = (int) 2e1d64; +int e = (int) .3e2D128; +int f = (int) 4.5e3d128; +int g = (int) 5.e0D32; +int h = (int) 1e+2d32; +int i = (int) 1000e-3D128; + +#define expr_has_type(e, t) _Generic (e, default : 0, t : 1) +static_assert (expr_has_type (1.1D32, _Decimal32)); +static_assert (expr_has_type (2.d32, _Decimal32)); +static_assert (expr_has_type (.33D64, _Decimal64)); +static_assert (expr_has_type (2e1d64, _Decimal64)); +static_assert (expr_has_type (.3e2D128, _Decimal128)); +static_assert (expr_has_type (4.5e3d128, _Decimal128)); +static_assert (expr_has_type (5.e0D32, _Decimal32)); +static_assert (expr_has_type (1e+2d32, _Decimal32)); +static_assert (expr_has_type (1000e-3D128, _Decimal128)); + +int +main () +{ + if (1.1D32 != 1.1df + || 2.d32 != 2.df + || .33D64 != .33dd + || 2e1d64 != 2e1dd + || .3e2D128 != .3e2dl + || 4.5e3d128 != 4.5e3dl + || 5.e0D32 != 5.e0df + || 1e+2d32 != 1e+2df + || 1000e-3D128 != 1000e-3dl) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/dfp/c23-constants-4.c b/gcc/testsuite/gcc.dg/dfp/c23-constants-4.c new file mode 100644 index 000000000000..e9ae6a375d50 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/c23-constants-4.c @@ -0,0 +1,13 @@ +/* Test that DFP constants are accepted in C23 mode: compat warnings. */ +/* { dg-do compile } */ +/* { dg-options "-std=c23 -Wc11-c23-compat" } */ + +int a = (int) 1.1D32; /* { dg-warning "C23 feature" } */ +int b = (int) 2.d32; /* { dg-warning "C23 feature" } */ +int c = (int) .33D64; /* { dg-warning "C23 feature" } */ +int d = (int) 2e1d64; /* { dg-warning "C23 feature" } */ +int e = (int) .3e2D128; /* { dg-warning "C23 feature" } */ +int f = (int) 4.5e3d128; /* { dg-warning "C23 feature" } */ +int g = (int) 5.e0D32; /* { dg-warning "C23 feature" } */ +int h = (int) 1e+2d32; /* { dg-warning "C23 feature" } */ +int i = (int) 1000e-3D128; /* { dg-warning "C23 feature" } */ diff --git a/libcpp/expr.cc b/libcpp/expr.cc index bbf21b8fb1c3..685233797c84 100644 --- a/libcpp/expr.cc +++ b/libcpp/expr.cc @@ -99,9 +99,9 @@ interpret_float_suffix (cpp_reader *pfile, const uchar *s, size_t len) /* The following decimal float suffixes, from TR 24732:2009, TS 18661-2:2015 and C23, are supported: - df, DF - _Decimal32. - dd, DD - _Decimal64. - dl, DL - _Decimal128. + df, DF, d32, D32 - _Decimal32. + dd, DD, d64, D64 - _Decimal64. + dl, DL, d128, D128 - _Decimal128. The dN and DN suffixes for _DecimalN, and dNx and DNx for _DecimalNx, defined in TS 18661-3:2015, are not supported. @@ -253,7 +253,18 @@ interpret_float_suffix (cpp_reader *pfile, const uchar *s, size_t len) break; } return 0; - case 'd': case 'D': d++; break; + case 'd': case 'D': + if (!CPP_OPTION (pfile, cplusplus) && orig_s == s && len > 1) + { + if (s[1] == '3' && s[2] == '2' && len == 2) + return CPP_N_DFLOAT | CPP_N_SMALL; + if (s[1] == '6' && s[2] == '4' && len == 2) + return CPP_N_DFLOAT | CPP_N_MEDIUM; + if (s[1] == '1' && s[2] == '2' && len == 3 && s[3] == '8') + return CPP_N_DFLOAT | CPP_N_LARGE; + } + d++; + break; case 'l': case 'L': l++; break; case 'w': case 'W': w++; break; case 'q': case 'Q': q++; break;