Skip to content

Commit f06fce6

Browse files
committed
[clang][DFP] Add support for -fexperimental-decimal-floating-point.
Though the ISO/IEC TS 18661-2:2015 decimal floating-point (DFP) extension has been adopted for the upcoming C23 standard, it will remain necessary to be able to explicitly enable and disable support for the extension for the foreseeable future for use with previous C standards and with C++. This change adds a driver and cc1 option to enable language support. Since support for the feature is not yet complete, the option name explicitly reflects its status as experimental and only serves to enable testing at this point. No target considerations have been implemented yet. The option only serves to enable the _Decimal32, _Decimal64, and _Decimal128 keywords to be used as DFP type specifiers in C; these keywords are not enabled for C++ since, per ISO/IEC TR 24733:2011 and the gcc implementation, DFP support in C++ is provided via standard library types (that are expected to wrap a builtin type exposed by other means). The C23 standard specifies that the __STDC_IEC_60559_DFP__ macro be predefined when the DFP extensions are available. This change adds that macro with a placeholder value for use in testing.
1 parent 707f162 commit f06fce6

File tree

10 files changed

+77
-11
lines changed

10 files changed

+77
-11
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10232,8 +10232,8 @@ def ext_missing_type_specifier : ExtWarn<
1023210232
"implicit int">, InGroup<ImplicitInt>, DefaultError;
1023310233
def err_missing_type_specifier : Error<
1023410234
"a type specifier is required for all declarations">;
10235-
def err_decimal_unsupported : Error<
10236-
"GNU decimal type extension not supported">;
10235+
def err_dfp_disabled : Error<
10236+
"decimal floating-point extensions are not enabled">;
1023710237
def err_objc_array_of_interfaces : Error<
1023810238
"array of interface %0 is invalid (probably should be an array of pointers)">;
1023910239
def ext_c99_array_usage : Extension<

clang/include/clang/Basic/LangOptions.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,9 @@ LANGOPT(FixedPoint, 1, 0, "fixed point types")
427427
LANGOPT(PaddingOnUnsignedFixedPoint, 1, 0,
428428
"unsigned fixed point types having one extra padding bit")
429429

430+
// ISO/IEC TS 18661-2, ISO/IEC TR 24733, and C23 decimal floating-point.
431+
LANGOPT(DecimalFloatingPoint, 1, 0, "decimal floating-point extensions")
432+
430433
LANGOPT(RegisterStaticDestructors, 1, 1, "Register C++ static destructors")
431434

432435
LANGOPT(RegCall4, 1, 0, "Set __regcall4 as a default calling convention to respect __regcall ABI v.4")

clang/include/clang/Basic/TokenKinds.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,9 @@ KEYWORD(_Fract , KEYNOCXX)
428428
KEYWORD(_Sat , KEYNOCXX)
429429

430430
// ISO/IEC TS 18661-2, ISO/IEC TR 24733, and C23 decimal floating-point.
431-
KEYWORD(_Decimal32 , KEYALL)
432-
KEYWORD(_Decimal64 , KEYALL)
433-
KEYWORD(_Decimal128 , KEYALL)
431+
KEYWORD(_Decimal32 , KEYNOCXX)
432+
KEYWORD(_Decimal64 , KEYNOCXX)
433+
KEYWORD(_Decimal128 , KEYNOCXX)
434434

435435
// GNU Extensions (in impl-reserved namespace)
436436
KEYWORD(__null , KEYCXX)

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,6 +2055,11 @@ defm fixed_point : BoolFOption<"fixed-point",
20552055
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
20562056
NegFlag<SetFalse, [], [ClangOption], "Disable">,
20572057
BothFlags<[], [ClangOption], " fixed point types">>, ShouldParseIf<!strconcat("!", cplusplus.KeyPath)>;
2058+
defm decimal_floating_point : BoolFOption<"experimental-decimal-floating-point",
2059+
LangOpts<"DecimalFloatingPoint">, DefaultFalse,
2060+
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
2061+
NegFlag<SetFalse, [], [ClangOption], "Disable">,
2062+
BothFlags<[], [ClangOption], " decimal floating-point extensions">>;
20582063
defm cxx_static_destructors : BoolFOption<"c++-static-destructors",
20592064
LangOpts<"RegisterStaticDestructors">, DefaultTrue,
20602065
NegFlag<SetFalse, [], [ClangOption, CC1Option],

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6004,6 +6004,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
60046004
Args.addOptInFlag(CmdArgs, options::OPT_ffixed_point,
60056005
options::OPT_fno_fixed_point);
60066006

6007+
Args.addOptInFlag(CmdArgs, options::OPT_fdecimal_floating_point,
6008+
options::OPT_fno_decimal_floating_point);
6009+
60076010
if (Arg *A = Args.getLastArg(options::OPT_fcxx_abi_EQ))
60086011
A->render(Args, CmdArgs);
60096012

clang/lib/Frontend/InitPreprocessor.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,12 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
498498
Builder.defineMacro("__STDC_UTF_16__", "1");
499499
Builder.defineMacro("__STDC_UTF_32__", "1");
500500

501+
// C23 decimal floating point extensions.
502+
// FIXME: Define to 202311L when support for C23 decimal floating point
503+
// FIXME: extensions is feature complete.
504+
if (!LangOpts.CPlusPlus && LangOpts.DecimalFloatingPoint)
505+
Builder.defineMacro("__STDC_IEC_60559_DFP__", "197001L");
506+
501507
if (LangOpts.ObjC)
502508
Builder.defineMacro("__OBJC__");
503509

clang/lib/Sema/SemaType.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,9 +1588,13 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
15881588
case DeclSpec::TST_decimal32: // _Decimal32
15891589
case DeclSpec::TST_decimal64: // _Decimal64
15901590
case DeclSpec::TST_decimal128: // _Decimal128
1591-
S.Diag(DS.getTypeSpecTypeLoc(), diag::err_decimal_unsupported);
1592-
Result = TSTToDecimalFloatType(Context, DS.getTypeSpecType());
1593-
declarator.setInvalidType(true);
1591+
if (!S.getLangOpts().DecimalFloatingPoint) {
1592+
S.Diag(DS.getTypeSpecTypeLoc(), diag::err_dfp_disabled);
1593+
Result = Context.IntTy;
1594+
declarator.setInvalidType(true);
1595+
} else {
1596+
Result = TSTToDecimalFloatType(Context, DS.getTypeSpecType());
1597+
}
15941598
break;
15951599
case DeclSpec::TST_class:
15961600
case DeclSpec::TST_enum:
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// This test is intended to validate whether decimal floating-point (DFP)
2+
// extensions are enabled based on language standard and to ensure a proper
3+
// diagnostic is issued for any use of DFP features otherwise.
4+
5+
// RUN: %clang -target x86_64-unknown-linux-gnu -std=c17 -fsyntax-only -Xclang -verify=dfp-off,c-dfp-off %s
6+
// RUN: %clang -target x86_64-unknown-linux-gnu -std=c17 -fsyntax-only -fexperimental-decimal-floating-point -Xclang -verify %s
7+
// FIXME: Remove -fexperimental-decimal-floating-point once -std=c23 implies DFP enablement.
8+
// RUN: %clang -target x86_64-unknown-linux-gnu -std=c23 -fsyntax-only -fexperimental-decimal-floating-point -Xclang -verify %s
9+
// RUN: %clang -target x86_64-unknown-linux-gnu -std=c23 -fsyntax-only -fno-experimental-decimal-floating-point -Xclang -verify=dfp-off,c-dfp-off %s
10+
// RUN: %clang -target x86_64-unknown-linux-gnu -x c++ -std=c++23 -fsyntax-only -Xclang -verify=cxx,dfp-off %s
11+
// RUN: %clang -target x86_64-unknown-linux-gnu -x c++ -std=c++23 -fsyntax-only -fexperimental-decimal-floating-point -Xclang -verify=cxx %s
12+
// FIXME: Remove -fexperimental-decimal-floating-point once -std=c++2c (or later) implies DFP enablement.
13+
// RUN: %clang -target x86_64-unknown-linux-gnu -x c++ -std=c++2c -fsyntax-only -fexperimental-decimal-floating-point -Xclang -verify=cxx %s
14+
// RUN: %clang -target x86_64-unknown-linux-gnu -x c++ -std=c++2c -fsyntax-only -fno-experimental-decimal-floating-point -Xclang -verify=cxx,dfp-off %s
15+
16+
// expected-no-diagnostics
17+
18+
#if defined(__cplusplus)
19+
#if defined(__STDC_IEC_60559_DFP__)
20+
#error __STDC_IEC_60559_DFP__ should never be defined for C++
21+
#endif
22+
#else
23+
#if !defined(__STDC_IEC_60559_DFP__)
24+
// c-dfp-off-error@+1 {{__STDC_IEC_60559_DFP__ should be defined}}
25+
#error __STDC_IEC_60559_DFP__ should be defined for C when DFP support is enabled
26+
#elif __STDC_IEC_60559_DFP__ != 197001L
27+
#error __STDC_IEC_60559_DFP__ has the wrong value
28+
#endif
29+
#endif
30+
31+
_Decimal32 d32; // cxx-error {{unknown type name '_Decimal32'}} \
32+
// c-dfp-off-error {{decimal floating-point extensions are not enabled}}
33+
_Decimal64 d64; // cxx-error {{unknown type name '_Decimal64'}} \
34+
// c-dfp-off-error {{decimal floating-point extensions are not enabled}}
35+
_Decimal128 d128; // cxx-error {{unknown type name '_Decimal128'}} \
36+
// c-dfp-off-error {{decimal floating-point extensions are not enabled}}

clang/test/Sema/dfp-types.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c23 -fexperimental-decimal-floating-point -fsyntax-only -verify=c %s
2+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -x c++ -std=c++2c -fexperimental-decimal-floating-point -fsyntax-only -verify=cxx %s
3+
4+
// c-no-diagnostics
5+
6+
// _Decimal32, _Decimal64, and _Decimal128 are never keywords in C++.
7+
_Decimal32 d32; // cxx-error {{unknown type name '_Decimal32'}}
8+
_Decimal64 d64; // cxx-error {{unknown type name '_Decimal64'}}
9+
_Decimal128 d28; // cxx-error {{unknown type name '_Decimal128'}}

clang/test/Sema/types.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ enum e { e_1 };
4848
extern int j[sizeof(enum e)]; // expected-note {{previous declaration}}
4949
int j[42]; // expected-error {{redefinition of 'j' with a different type: 'int[42]' vs 'int[4]'}}
5050

51-
_Decimal32 d32; // expected-error {{GNU decimal type extension not supported}}
52-
_Decimal64 d64; // expected-error {{GNU decimal type extension not supported}}
53-
_Decimal128 d128; // expected-error {{GNU decimal type extension not supported}}
51+
_Decimal32 d32; // expected-error {{decimal floating-point extensions are not enabled}}
52+
_Decimal64 d64; // expected-error {{decimal floating-point extensions are not enabled}}
53+
_Decimal128 d128; // expected-error {{decimal floating-point extensions are not enabled}}
5454

5555
int __attribute__ ((vector_size (8), vector_size (8))) v; // expected-error {{invalid vector element type}}
5656

0 commit comments

Comments
 (0)