From 6ec637a4b85abeee6570e4cb7786df53eadbaa40 Mon Sep 17 00:00:00 2001 From: Janis Johnson Date: Thu, 7 May 2009 22:34:08 +0000 Subject: [PATCH] re PR c/39037 (FLOAT_CONST_DECIMAL64 pragma not supported) gcc/ PR c/39037 * c-common.h (mark_valid_location_for_stdc_pragma, valid_location_for_stdc_pragma_p, set_float_const_decimal64, clear_float_const_decimal64, float_const_decimal64_p): New. * c.opt (Wunsuffixed-float-constants): New. * c-lex.c (interpret_float): Use pragma FLOAT_CONST_DECIMAL64 for unsuffixed float constant, handle new warning. * c-cppbuiltin.c (c_cpp_builtins): Use cast for double constants. * c-decl.c (c_scope): New flag float_const_decimal64. (set_float_const_decimal64, clear_float_const_decimal64, float_const_decimal64_p): New. (push_scope): Set new flag. * c-parser.c (c_parser_translation_unit): Mark when it's valid to use STDC pragmas. (c_parser_external_declaration): Ditto. (c_parser_compound_statement_nostart): Ditto. * c-pragma.c (valid_location_for_stdc_pragma, mark_valid_location_for_stdc_pragma, valid_location_for_stdc_pragma_p, handle_stdc_pragma, handle_pragma_float_const_decimal64): New. (init_pragma): Register new pragma FLOAT_CONST_DECIMAL64. * cp/semantics.c (valid_location_for_stdc_pragma_p, set_float_const_decimal64, clear_float_const_decimal64, float_const_decimal64_p): New dummy functions. * doc/extend.texi (Decimal Float): Remove statement that the pragma, and suffix for double constants, are not supported. * doc/invoke.texi (Warning Options): List new option. (-Wunsuffixed-float-constants): New. gcc/testsuite PR c/39037 * gcc.dg/Wunsuffixed-float-constants-1.c: New test. * gcc.dg/cpp/pragma-float-const-decimal64-1.c: New test. * gcc.dg/dfp/float-constant-double.c: New test. * gcc.dg/dfp/pragma-float-const-decimal64-1.c: New test. * gcc.dg/dfp/pragma-float-const-decimal64-2.c: New test. * gcc.dg/dfp/pragma-float-const-decimal64-3.c: New test. * gcc.dg/dfp/pragma-float-const-decimal64-4.c: New test. * gcc.dg/dfp/pragma-float-const-decimal64-5.c: New test. * gcc.dg/dfp/pragma-float-const-decimal64-6.c: New test. * gcc.dg/dfp/pragma-float-const-decimal64-7.c: New test. * gcc.dg/dfp/pragma-float-const-decimal64-8.c: New test. * g++.dg/cpp/pragma-float-const-decimal64-1.C: New test. From-SVN: r147259 --- gcc/ChangeLog | 31 ++++ gcc/c-common.h | 5 + gcc/c-cppbuiltin.c | 13 +- gcc/c-decl.c | 40 ++++ gcc/c-lex.c | 12 +- gcc/c-parser.c | 15 ++ gcc/c-pragma.c | 113 ++++++++++++ gcc/c.opt | 4 + gcc/cp/semantics.c | 19 ++ gcc/doc/extend.texi | 4 - gcc/doc/invoke.texi | 13 +- gcc/testsuite/ChangeLog | 16 ++ .../cpp/pragma-float-const-decimal64-1.C | 5 + .../gcc.dg/Wunsuffixed-float-constants-1.c | 17 ++ .../cpp/pragma-float-const-decimal64-1.c | 5 + .../gcc.dg/dfp/float-constant-double.c | 21 +++ .../dfp/pragma-float-const-decimal64-1.c | 85 +++++++++ .../dfp/pragma-float-const-decimal64-2.c | 86 +++++++++ .../dfp/pragma-float-const-decimal64-3.c | 83 +++++++++ .../dfp/pragma-float-const-decimal64-4.c | 46 +++++ .../dfp/pragma-float-const-decimal64-5.c | 46 +++++ .../dfp/pragma-float-const-decimal64-6.c | 46 +++++ .../dfp/pragma-float-const-decimal64-7.c | 39 ++++ .../dfp/pragma-float-const-decimal64-8.c | 174 ++++++++++++++++++ 24 files changed, 923 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp/pragma-float-const-decimal64-1.C create mode 100644 gcc/testsuite/gcc.dg/Wunsuffixed-float-constants-1.c create mode 100644 gcc/testsuite/gcc.dg/cpp/pragma-float-const-decimal64-1.c create mode 100644 gcc/testsuite/gcc.dg/dfp/float-constant-double.c create mode 100644 gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-1.c create mode 100644 gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-2.c create mode 100644 gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-3.c create mode 100644 gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-4.c create mode 100644 gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-5.c create mode 100644 gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-6.c create mode 100644 gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-7.c create mode 100644 gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-8.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e1ffdd3dd2c..7d24caae354 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2009-05-07 Janis Johnson + + PR c/39037 + * c-common.h (mark_valid_location_for_stdc_pragma, + valid_location_for_stdc_pragma_p, set_float_const_decimal64, + clear_float_const_decimal64, float_const_decimal64_p): New. + * c.opt (Wunsuffixed-float-constants): New. + * c-lex.c (interpret_float): Use pragma FLOAT_CONST_DECIMAL64 for + unsuffixed float constant, handle new warning. + * c-cppbuiltin.c (c_cpp_builtins): Use cast for double constants. + * c-decl.c (c_scope): New flag float_const_decimal64. + (set_float_const_decimal64, clear_float_const_decimal64, + float_const_decimal64_p): New. + (push_scope): Set new flag. + * c-parser.c (c_parser_translation_unit): Mark when it's valid + to use STDC pragmas. + (c_parser_external_declaration): Ditto. + (c_parser_compound_statement_nostart): Ditto. + * c-pragma.c (valid_location_for_stdc_pragma, + mark_valid_location_for_stdc_pragma, + valid_location_for_stdc_pragma_p, handle_stdc_pragma, + handle_pragma_float_const_decimal64): New. + (init_pragma): Register new pragma FLOAT_CONST_DECIMAL64. + * cp/semantics.c (valid_location_for_stdc_pragma_p, + set_float_const_decimal64, clear_float_const_decimal64, + float_const_decimal64_p): New dummy functions. + * doc/extend.texi (Decimal Float): Remove statement that the + pragma, and suffix for double constants, are not supported. + * doc/invoke.texi (Warning Options): List new option. + (-Wunsuffixed-float-constants): New. + 2009-05-08 Steven Bosscher * config/i386/i386.c: Do not include c-common.h. diff --git a/gcc/c-common.h b/gcc/c-common.h index 14448800ce0..250a7ff74fa 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -809,6 +809,11 @@ extern void warn_logical_operator (location_t, enum tree_code, extern void check_main_parameter_types (tree decl); extern bool c_determine_visibility (tree); extern bool same_scalar_type_ignoring_signedness (tree, tree); +extern void mark_valid_location_for_stdc_pragma (bool); +extern bool valid_location_for_stdc_pragma_p (void); +extern void set_float_const_decimal64 (void); +extern void clear_float_const_decimal64 (void); +extern bool float_const_decimal64_p (void); #define c_sizeof(T) c_sizeof_or_alignof_type (T, true, 1) #define c_alignof(T) c_sizeof_or_alignof_type (T, false, 1) diff --git a/gcc/c-cppbuiltin.c b/gcc/c-cppbuiltin.c index 8b776b15dbc..921addbccf0 100644 --- a/gcc/c-cppbuiltin.c +++ b/gcc/c-cppbuiltin.c @@ -619,14 +619,11 @@ c_cpp_builtins (cpp_reader *pfile) TARGET_DEC_EVAL_METHOD); builtin_define_float_constants ("FLT", "F", "%s", float_type_node); - /* Cast the double precision constants when single precision constants are - specified. The correct result is computed by the compiler when using - macros that include a cast. This has the side-effect of making the value - unusable in const expressions. */ - if (flag_single_precision_constant) - builtin_define_float_constants ("DBL", "L", "((double)%s)", double_type_node); - else - builtin_define_float_constants ("DBL", "", "%s", double_type_node); + /* Cast the double precision constants. This is needed when single + precision constants are specified or when pragma FLOAT_CONST_DECIMAL64 + is used. The correct result is computed by the compiler when using + macros that include a cast. */ + builtin_define_float_constants ("DBL", "L", "((double)%s)", double_type_node); builtin_define_float_constants ("LDBL", "L", "%s", long_double_type_node); /* For decfloat.h. */ diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 85c4d6bf02d..409c458e195 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -342,6 +342,9 @@ struct GTY((chain_next ("%h.outer"))) c_scope { /* True means make a BLOCK for this scope no matter what. */ BOOL_BITFIELD keep : 1; + + /* True means that an unsuffixed float constant is _Decimal64. */ + BOOL_BITFIELD float_const_decimal64 : 1; }; /* The scope currently in effect. */ @@ -674,6 +677,30 @@ keep_next_level (void) keep_next_level_flag = true; } +/* Set the flag for the FLOAT_CONST_DECIMAL64 pragma being ON. */ + +void +set_float_const_decimal64 (void) +{ + current_scope->float_const_decimal64 = true; +} + +/* Clear the flag for the FLOAT_CONST_DECIMAL64 pragma. */ + +void +clear_float_const_decimal64 (void) +{ + current_scope->float_const_decimal64 = false; +} + +/* Return nonzero if an unsuffixed float constant is _Decimal64. */ + +bool +float_const_decimal64_p (void) +{ + return current_scope->float_const_decimal64; +} + /* Identify this scope as currently being filled with parameters. */ void @@ -705,6 +732,13 @@ push_scope (void) keep_next_level_flag = false; next_is_function_body = false; + + /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes. */ + if (current_scope->outer) + current_scope->float_const_decimal64 + = current_scope->outer->float_const_decimal64; + else + current_scope->float_const_decimal64 = false; } else { @@ -717,6 +751,12 @@ push_scope (void) else scope = GGC_CNEW (struct c_scope); + /* The FLOAT_CONST_DECIMAL64 pragma applies to nested scopes. */ + if (current_scope) + scope->float_const_decimal64 = current_scope->float_const_decimal64; + else + scope->float_const_decimal64 = false; + scope->keep = keep_next_level_flag; scope->outer = current_scope; scope->depth = current_scope ? (current_scope->depth + 1) : 0; diff --git a/gcc/c-lex.c b/gcc/c-lex.c index df6354843bf..fc89279a7d9 100644 --- a/gcc/c-lex.c +++ b/gcc/c-lex.c @@ -617,11 +617,21 @@ interpret_float (const cpp_token *token, unsigned int flags) char *copy; size_t copylen; - /* Default (no suffix) is double. */ + /* Default (no suffix) depends on whether the FLOAT_CONST_DECIMAL64 + pragma has been used and is either double or _Decimal64. Types + that are not allowed with decimal float default to double. */ if (flags & CPP_N_DEFAULT) { flags ^= CPP_N_DEFAULT; flags |= CPP_N_MEDIUM; + + if (((flags & CPP_N_HEX) == 0) && ((flags & CPP_N_IMAGINARY) == 0)) + { + warning (OPT_Wunsuffixed_float_constants, + "unsuffixed float constant"); + if (float_const_decimal64_p ()) + flags |= CPP_N_DFLOAT; + } } /* Decode _Fract and _Accum. */ diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 6c839e9104c..033c8350776 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -976,6 +976,7 @@ c_parser_translation_unit (c_parser *parser) else { void *obstack_position = obstack_alloc (&parser_obstack, 0); + mark_valid_location_for_stdc_pragma (false); do { ggc_collect (); @@ -1060,7 +1061,9 @@ c_parser_external_declaration (c_parser *parser) c_parser_consume_token (parser); break; case CPP_PRAGMA: + mark_valid_location_for_stdc_pragma (true); c_parser_pragma (parser, pragma_external); + mark_valid_location_for_stdc_pragma (false); break; case CPP_PLUS: case CPP_MINUS: @@ -3350,17 +3353,20 @@ c_parser_compound_statement_nostart (c_parser *parser) { bool last_stmt = false; bool last_label = false; + bool save_valid_for_pragma = valid_location_for_stdc_pragma_p (); location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */ if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) { c_parser_consume_token (parser); return; } + mark_valid_location_for_stdc_pragma (true); if (c_parser_next_token_is_keyword (parser, RID_LABEL)) { location_t err_loc = c_parser_peek_token (parser)->location; /* Read zero or more forward-declarations for labels that nested functions can jump to. */ + mark_valid_location_for_stdc_pragma (false); while (c_parser_next_token_is_keyword (parser, RID_LABEL)) { c_parser_consume_token (parser); @@ -3391,6 +3397,7 @@ c_parser_compound_statement_nostart (c_parser *parser) /* We must now have at least one statement, label or declaration. */ if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) { + mark_valid_location_for_stdc_pragma (save_valid_for_pragma); c_parser_error (parser, "expected declaration or statement"); c_parser_consume_token (parser); return; @@ -3409,12 +3416,14 @@ c_parser_compound_statement_nostart (c_parser *parser) label_loc = c_parser_peek_token (parser)->location; last_label = true; last_stmt = false; + mark_valid_location_for_stdc_pragma (false); c_parser_label (parser); } else if (!last_label && c_parser_next_token_starts_declspecs (parser)) { last_label = false; + mark_valid_location_for_stdc_pragma (false); c_parser_declaration_or_fndef (parser, true, true, true, true); if (last_stmt) pedwarn_c90 (loc, @@ -3441,6 +3450,7 @@ c_parser_compound_statement_nostart (c_parser *parser) ext = disable_extension_diagnostics (); c_parser_consume_token (parser); last_label = false; + mark_valid_location_for_stdc_pragma (false); c_parser_declaration_or_fndef (parser, true, true, true, true); /* Following the old parser, __extension__ does not disable this diagnostic. */ @@ -3467,6 +3477,7 @@ c_parser_compound_statement_nostart (c_parser *parser) } else if (c_parser_next_token_is (parser, CPP_EOF)) { + mark_valid_location_for_stdc_pragma (save_valid_for_pragma); c_parser_error (parser, "expected declaration or statement"); return; } @@ -3474,6 +3485,7 @@ c_parser_compound_statement_nostart (c_parser *parser) { if (parser->in_if_block) { + mark_valid_location_for_stdc_pragma (save_valid_for_pragma); error_at (loc, """expected %<}%> before %"); return; } @@ -3489,6 +3501,7 @@ c_parser_compound_statement_nostart (c_parser *parser) statement: last_label = false; last_stmt = true; + mark_valid_location_for_stdc_pragma (false); c_parser_statement_after_labels (parser); } @@ -3497,6 +3510,8 @@ c_parser_compound_statement_nostart (c_parser *parser) if (last_label) error_at (label_loc, "label at end of compound statement"); c_parser_consume_token (parser); + /* Restore the value we started with. */ + mark_valid_location_for_stdc_pragma (save_valid_for_pragma); } /* Parse a label (C90 6.6.1, C99 6.8.1). diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c index 64a224f4a28..bd71d1d79e8 100644 --- a/gcc/c-pragma.c +++ b/gcc/c-pragma.c @@ -1162,6 +1162,116 @@ handle_pragma_message (cpp_reader *ARG_UNUSED(dummy)) inform (input_location, "#pragma message: %s", TREE_STRING_POINTER (message)); } +/* Mark whether the current location is valid for a STDC pragma. */ + +static bool valid_location_for_stdc_pragma; + +void +mark_valid_location_for_stdc_pragma (bool flag) +{ + valid_location_for_stdc_pragma = flag; +} + +/* Return true if the current location is valid for a STDC pragma. */ + +bool +valid_location_for_stdc_pragma_p (void) +{ + return valid_location_for_stdc_pragma; +} + +enum pragma_switch_t { ON, OFF, DEFAULT, BAD }; + +/* A STDC pragma must appear outside of external declarations or + preceding all explicit declarations and statements inside a compound + statement; its behavior is undefined if used in any other context. + It takes a switch of ON, OFF, or DEFAULT. */ + +static enum pragma_switch_t +handle_stdc_pragma (const char *pname) +{ + const char *arg; + tree t; + enum pragma_switch_t ret; + + if (!valid_location_for_stdc_pragma_p ()) + { + warning (OPT_Wpragmas, "invalid location for %, ignored", + pname); + return BAD; + } + + if (pragma_lex (&t) != CPP_NAME) + { + warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname); + return BAD; + } + + arg = IDENTIFIER_POINTER (t); + + if (!strcmp (arg, "ON")) + ret = ON; + else if (!strcmp (arg, "OFF")) + ret = OFF; + else if (!strcmp (arg, "DEFAULT")) + ret = DEFAULT; + else + { + warning (OPT_Wpragmas, "malformed %<#pragma %s%>, ignored", pname); + return BAD; + } + + if (pragma_lex (&t) != CPP_EOF) + { + warning (OPT_Wpragmas, "junk at end of %<#pragma %s%>", pname); + return BAD; + } + + return ret; +} + +/* #pragma STDC FLOAT_CONST_DECIMAL64 ON + #pragma STDC FLOAT_CONST_DECIMAL64 OFF + #pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT */ + +static void +handle_pragma_float_const_decimal64 (cpp_reader *ARG_UNUSED (dummy)) +{ + if (c_dialect_cxx ()) + { + if (warn_unknown_pragmas > in_system_header) + warning (OPT_Wunknown_pragmas, + "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported" + " for C++"); + return; + } + + if (!targetm.decimal_float_supported_p ()) + { + if (warn_unknown_pragmas > in_system_header) + warning (OPT_Wunknown_pragmas, + "%<#pragma STDC FLOAT_CONST_DECIMAL64%> is not supported" + " on this target"); + return; + } + + pedwarn (input_location, OPT_pedantic, + "ISO C does not support %<#pragma STDC FLOAT_CONST_DECIMAL64%>"); + + switch (handle_stdc_pragma ("STDC FLOAT_CONST_DECIMAL64")) + { + case ON: + set_float_const_decimal64 (); + break; + case OFF: + case DEFAULT: + clear_float_const_decimal64 (); + break; + case BAD: + break; + } +} + /* A vector of registered pragma callbacks. */ DEF_VEC_O (pragma_handler); @@ -1330,6 +1440,9 @@ init_pragma (void) c_register_pragma ("GCC", "pop_options", handle_pragma_pop_options); c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options); + c_register_pragma ("STDC", "FLOAT_CONST_DECIMAL64", + handle_pragma_float_const_decimal64); + c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname); c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix); diff --git a/gcc/c.opt b/gcc/c.opt index 7f71699faa7..fc34ff57f78 100644 --- a/gcc/c.opt +++ b/gcc/c.opt @@ -476,6 +476,10 @@ Wunknown-pragmas C ObjC C++ ObjC++ Warning Warn about unrecognized pragmas +Wunsuffixed-float-constants +C ObjC Var(warn_unsuffixed_float_constants) Warning +Warn about unsuffixed float constants + Wunused-macros C ObjC C++ ObjC++ Warning Warn about macros defined in the main file that are not used diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index dd84891d73b..4c0c91d5905 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5050,4 +5050,23 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2) ? boolean_true_node : boolean_false_node); } +/* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64, + which is ignored for C++. */ + +void +set_float_const_decimal64 (void) +{ +} + +void +clear_float_const_decimal64 (void) +{ +} + +bool +float_const_decimal64_p (void) +{ + return 0; +} + #include "gt-cp-semantics.h" diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 4e06be3daca..43bebf911c0 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -957,10 +957,6 @@ GCC support of decimal float as specified by the draft technical report is incomplete: @itemize @bullet -@item -Pragma @code{FLOAT_CONST_DECIMAL64} is not supported, nor is the @samp{d} -suffix for literal constants of type @code{double}. - @item When the value of a decimal floating type cannot be represented in the integer type to which it is being converted, the result is undefined diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 2674c47ef89..3fc575d34de 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -259,8 +259,8 @@ Objective-C and Objective-C++ Dialects}. -Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand @gol -Wsystem-headers -Wtrigraphs -Wtype-limits -Wundef -Wuninitialized @gol -Wunknown-pragmas -Wno-pragmas -Wunreachable-code @gol --Wunused -Wunused-function -Wunused-label -Wunused-parameter @gol --Wunused-value -Wunused-variable @gol +-Wunsuffixed-float-constants -Wunused -Wunused-function @gol +-Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable @gol -Wvariadic-macros -Wvla @gol -Wvolatile-register-var -Wwrite-strings} @@ -4218,6 +4218,15 @@ minimum maximum, so we do not diagnose overlength strings in C++@. This option is implied by @option{-pedantic}, and can be disabled with @option{-Wno-overlength-strings}. + +@item -Wunsuffixed-float-constants +@opindex Wunsuffixed-float-constants + +GCC will issue a warning for any floating constant that does not have +a suffix. When used together with @option{-Wsystem-headers} it will +warn about such constants in system header files. This can be useful +when preparing code to use with the @code{FLOAT_CONST_DECIMAL64} pragma +from the decimal floating-point extension to C99. @end table @node Debugging Options diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index eff2991e1a7..2dc3dd9e3e9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,19 @@ +2009-05-07 Janis Johnson + + PR c/39037 + * gcc.dg/Wunsuffixed-float-constants-1.c: New test. + * gcc.dg/cpp/pragma-float-const-decimal64-1.c: New test. + * gcc.dg/dfp/float-constant-double.c: New test. + * gcc.dg/dfp/pragma-float-const-decimal64-1.c: New test. + * gcc.dg/dfp/pragma-float-const-decimal64-2.c: New test. + * gcc.dg/dfp/pragma-float-const-decimal64-3.c: New test. + * gcc.dg/dfp/pragma-float-const-decimal64-4.c: New test. + * gcc.dg/dfp/pragma-float-const-decimal64-5.c: New test. + * gcc.dg/dfp/pragma-float-const-decimal64-6.c: New test. + * gcc.dg/dfp/pragma-float-const-decimal64-7.c: New test. + * gcc.dg/dfp/pragma-float-const-decimal64-8.c: New test. + * g++.dg/cpp/pragma-float-const-decimal64-1.C: New test. + 2009-05-07 Jakub Jelinek PR middle-end/40057 diff --git a/gcc/testsuite/g++.dg/cpp/pragma-float-const-decimal64-1.C b/gcc/testsuite/g++.dg/cpp/pragma-float-const-decimal64-1.C new file mode 100644 index 00000000000..31e1ad6d507 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/pragma-float-const-decimal64-1.C @@ -0,0 +1,5 @@ +// { dg-do compile } +// { dg-options "-Wunknown-pragmas" } + +#pragma STDC FLOAT_CONST_DECIMAL64 ON // { dg-warning "not supported for C\\\+\\\+" } +double d = 1.0; diff --git a/gcc/testsuite/gcc.dg/Wunsuffixed-float-constants-1.c b/gcc/testsuite/gcc.dg/Wunsuffixed-float-constants-1.c new file mode 100644 index 00000000000..b4a38d5cb10 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wunsuffixed-float-constants-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -Wunsuffixed-float-constants" } */ + +#define VAL 0.5; + +double a = 1.1d; + +/* With FLOAT_CONST_DECIMAL64 switched to ON these would have type + _Decimal64. */ + +double b = VAL; /* { dg-warning "unsuffixed float constant" } */ +double c = 1.2; /* { dg-warning "unsuffixed float constant" } */ + +/* With FLOAT_CONST_DECIMAL64 switched to ON these are still binary. */ + +double d = 0x5.0p1; /* No warning for hex constant. */ +double e = 3.1i; /* No warning for imaginary constant. */ diff --git a/gcc/testsuite/gcc.dg/cpp/pragma-float-const-decimal64-1.c b/gcc/testsuite/gcc.dg/cpp/pragma-float-const-decimal64-1.c new file mode 100644 index 00000000000..633383899dd --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/pragma-float-const-decimal64-1.c @@ -0,0 +1,5 @@ +/* { dg-do compile { target { ! dfp } } } */ +/* { dg-options "-std=gnu99 -Wunknown-pragmas" } */ + +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "not supported on this target" } */ +double d = 1.0; diff --git a/gcc/testsuite/gcc.dg/dfp/float-constant-double.c b/gcc/testsuite/gcc.dg/dfp/float-constant-double.c new file mode 100644 index 00000000000..3f8de656bf6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/float-constant-double.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99" } */ + +/* Constant float values of type double in are suffixed with L + and cast to double so they can be used within code that uses pragma + FLOAT_CONST_DECIMAL64. If they were not suffixed then use of the macro + would have them interpreted as _Decimal64, leading to errors when used + in expressions with other operands of type double. */ + +#include + +extern double a, b, c, d; + +void +foo () +{ + _Pragma ("STDC FLOAT_CONST_DECIMAL64 ON") + a = 0.1d * DBL_MAX; + b = DBL_EPSILON * 10.0d; + c = DBL_MIN * 200.0d; +} diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-1.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-1.c new file mode 100644 index 00000000000..79fabf34484 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-1.c @@ -0,0 +1,85 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -Wall" } */ + +/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma. + C99 6.4.4.2a (New). + + Verify that the pragma has the expected result by using unsuffixed + float constants as operands in expressions that would mix binary and + decimal operands if the pragma had no effect, or the wrong effect. */ + +#pragma STDC FLOAT_CONST_DECIMAL64 ON +double a = 1.0 * 2.0dd; + +double +f1 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 OFF + double b = 2.0 * 3.0d; + + { + double c = 3.0 * 4.0d; + b = b + c; + } + + { +#pragma STDC FLOAT_CONST_DECIMAL64 ON + double d = 4.0 * 5.0dd; + + b = b + d; + } + + { + /* Default is OFF. */ +#pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT + double e = 5.0 * 6.0d; + b = b + e; + } + + return b; +} + +double +f2 (void) +{ + /* Use value from outer scope, which is ON. */ + double b = 2.0 * 3.0dd; + + { +#pragma STDC FLOAT_CONST_DECIMAL64 OFF + double c = 3.0 * 4.0d; + + { +#pragma STDC FLOAT_CONST_DECIMAL64 ON + double d = 4.0 * 5.0dd; + + { +#pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT + double e = 5.0 * 6.0d; + + { +#pragma STDC FLOAT_CONST_DECIMAL64 ON + double f = 6.0 * 7.0dd; + + b = a + b + c + d + e + f; + } + } + } + } + return b; +} + +/* Use previous value from this scope, which is ON. */ +double f = 6.0 * 7.0dd; + +double +f3 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 OFF + double b = 2.0 * 3.0d; + + return b + f; +} + +/* Return to the state from this scope, which is ON. */ +double g = 7.0 + 8.0dd; diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-2.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-2.c new file mode 100644 index 00000000000..212748c6c78 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-2.c @@ -0,0 +1,86 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -Wall" } */ + +/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma. + C99 6.4.4.2a (New). + + Verify that the pragma has the expected result by using unsuffixed + float constants as operands in expressions that would mix binary and + decimal operands if the pragma had no effect, or the wrong effect. + Use _Pragma rather than #pragma. */ + +_Pragma ("STDC FLOAT_CONST_DECIMAL64 ON") +double a = 1.0 * 2.0dd; + +double +f1 (void) +{ +_Pragma ("STDC FLOAT_CONST_DECIMAL64 OFF") + double b = 2.0 * 3.0d; + + { + double c = 3.0 * 4.0d; + b = b + c; + } + + { +_Pragma ("STDC FLOAT_CONST_DECIMAL64 ON") + double d = 4.0 * 5.0dd; + + b = b + d; + } + + { + /* Default is OFF. */ +_Pragma ("STDC FLOAT_CONST_DECIMAL64 DEFAULT") + double e = 5.0 * 6.0d; + b = b + e; + } + + return b; +} + +double +f2 (void) +{ + /* Use value from outer scope, which is ON. */ + double b = 2.0 * 3.0dd; + + { +_Pragma ("STDC FLOAT_CONST_DECIMAL64 OFF") + double c = 3.0 * 4.0d; + + { +_Pragma ("STDC FLOAT_CONST_DECIMAL64 ON") + double d = 4.0 * 5.0dd; + + { +_Pragma ("STDC FLOAT_CONST_DECIMAL64 DEFAULT") + double e = 5.0 * 6.0d; + + { +_Pragma ("STDC FLOAT_CONST_DECIMAL64 ON") + double f = 6.0 * 7.0dd; + + b = a + b + c + d + e + f; + } + } + } + } + return b; +} + +/* Use previous value from this scope, which is ON. */ +double f = 6.0 * 7.0dd; + +double +f3 (void) +{ +_Pragma ("STDC FLOAT_CONST_DECIMAL64 OFF") + double b = 2.0 * 3.0d; + + return b + f; +} + +/* Return to the state from this scope, which is ON. */ +double g = 7.0 + 8.0dd; diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-3.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-3.c new file mode 100644 index 00000000000..b9286aac11a --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-3.c @@ -0,0 +1,83 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -Wall" } */ + +/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma. + C99 6.4.4.2a (New). */ + +/* Check that defining macros whose names are the same as the tokens used + in the pragma doesn't affect use of the pragma. */ + +#define ON YES +#define OFF NO +#define DEFAULT NOPE +#define STDC OFFICIAL +#define FLOAT_CONST_DECIMAL64 NEW_PRAGMA + +double a; + +void +f1a (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 ON + a = 1.0dd + 2.0; +} + +void +f1b (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 OFF + a = 2.0d + 3.0; +} + +void +f1c (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT + a = 3.0d + 4.0; +} + +/* Check that a macro can be used for the entire pragma. */ + +#define PRAGMA(x) _Pragma (#x) +#define DEFAULT_FLOAT_IS_DECIMAL PRAGMA(STDC FLOAT_CONST_DECIMAL64 ON) +#define DEFAULT_FLOAT_IS_BINARY PRAGMA(STDC FLOAT_CONST_DECIMAL64 OFF) + +void +f2a (void) +{ + DEFAULT_FLOAT_IS_DECIMAL + a = 5.0 * 6.0dd; +} + +void +f2b (void) +{ + DEFAULT_FLOAT_IS_BINARY + a = 6.0 * 7.0d; +} + +/* _Pragma can be used with macros, including the use of a macro for the + switch. */ + +#undef ON +#undef OFF +#undef DEFAULT +#undef STDC +#undef FLOAT_CONST_DECIMAL64 + +#define SWITCH ON +#define FLOAT_CONST_DECIMAL64(x) PRAGMA(STDC FLOAT_CONST_DECIMAL64 x) + +void +f3a (void) +{ + FLOAT_CONST_DECIMAL64(SWITCH) + a = 1.0 * 7.0dd; +} + +void +f3b (void) +{ + FLOAT_CONST_DECIMAL64(OFF) + a = 1.0 + 2.0d; +} diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-4.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-4.c new file mode 100644 index 00000000000..86cec1dbd45 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-4.c @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99" } */ + +/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma. + C99 6.4.4.2a (New). + + Check that malformed versions of pragma STDC FLOAT_CONST_DECIMAL64 + are detected. */ + +double a; + +void f1 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 /* { dg-warning "malformed" } */ + a = 1.0; +} + +void f2 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 DFP /* { dg-warning "malformed" } */ + a = 2.0; +} + +void f3 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 ON DFP /* { dg-warning "junk at end" } */ + a = 3.0; +} + +void f4 (void) +{ + _Pragma ( "STDC FLOAT_CONST_DECIMAL64" ) /* { dg-warning "malformed" } */ + a = 1.0; +} + +void f5 (void) +{ + _Pragma ( "STDC FLOAT_CONST_DECIMAL64 DFP" ) /* { dg-warning "malformed" } */ + a = 2.0; +} + +void f6 (void) +{ + _Pragma ( "STDC FLOAT_CONST_DECIMAL64 ON DFP" ) /* { dg-warning "junk at end" } */ + a = 3.0; +} diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-5.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-5.c new file mode 100644 index 00000000000..75e9525dda0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-5.c @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c99 -pedantic" } */ + +/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma. + C99 6.4.4.2a (New). + + Check that there is a pedantic warning for the use of pragma + STD FLOAT_CONST_DECIMAL64. */ + +double a; + +void f1 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "ISO C" } */ + a = 1.0; +} + +void f2 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 OFF /* { dg-warning "ISO C" } */ + a = 2.0; +} + +void f3 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT /* { dg-warning "ISO C" } */ + a = 3.0; +} + +void f4 (void) +{ + _Pragma ("STDC FLOAT_CONST_DECIMAL64 ON") /* { dg-warning "ISO C" } */ + a = 1.0; +} + +void f5 (void) +{ + _Pragma ("STDC FLOAT_CONST_DECIMAL64 OFF") /* { dg-warning "ISO C" } */ + a = 2.0; +} + +void f6 (void) +{ + _Pragma ("STDC FLOAT_CONST_DECIMAL64 DEFAULT") /* { dg-warning "ISO C" } */ + a = 3.0; +} diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-6.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-6.c new file mode 100644 index 00000000000..03c1715bee6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-6.c @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c99 -pedantic-errors" } */ + +/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma. + C99 6.4.4.2a (New). + + Check that there is a pedantic error for the use of pragma + STD FLOAT_CONST_DECIMAL64. */ + +double a; + +void f1 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-error "ISO C" } */ + a = 1.0; +} + +void f2 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 OFF /* { dg-error "ISO C" } */ + a = 2.0; +} + +void f3 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 DEFAULT /* { dg-error "ISO C" } */ + a = 3.0; +} + +void f4 (void) +{ + _Pragma ("STDC FLOAT_CONST_DECIMAL64 ON") /* { dg-error "ISO C" } */ + a = 1.0; +} + +void f5 (void) +{ + _Pragma ("STDC FLOAT_CONST_DECIMAL64 OFF") /* { dg-error "ISO C" } */ + a = 2.0; +} + +void f6 (void) +{ + _Pragma ("STDC FLOAT_CONST_DECIMAL64 DEFAULT") /* { dg-error "ISO C" } */ + a = 3.0; +} diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-7.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-7.c new file mode 100644 index 00000000000..7533ee7f0de --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-7.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -Wall" } */ + +/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma. + C99 6.4.4.2a (New). + + Check that when pragma FLOAT_CONST_DECIMAL64 is in effect so that + unsuffixed constants are _Decimal64, invalid types are still reported + as invalid. */ + +double +f1 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 OFF + double a = 0x1.0p1; + double b = 1.0i; + + return a + b; +} + +double +f2 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 OFF + double a = 0x1.0p1dd; /* { dg-error "with hex" } */ + double b = 1.0idd; /* { dg-error "invalid suffix" } */ + + return a + b; +} + +double +f3 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 ON + double a = 0x1.0p1; /* Hex constant is not affected by pragma. */ + double b = 1.0i; /* Imaginary constant is not affected by pragma. */ + + return a + b; +} diff --git a/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-8.c b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-8.c new file mode 100644 index 00000000000..5dbbda5b8f2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-8.c @@ -0,0 +1,174 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -Wall" } */ + +/* N1312 7.1.1: The FLOAT_CONST_DECIMAL64 pragma. + C99 6.4.4.2a (New). + + Pragma STDC FLOAT_CONST_DECIMAL64 "shall occur either outside external + declarations or preceding all explicit declarations and statements + inside a compound statement." */ + +#pragma STDC FLOAT_CONST_DECIMAL64 OFF + +#define MAX 200 + +#pragma STDC FLOAT_CONST_DECIMAL64 ON + +double a; + +#pragma STDC FLOAT_CONST_DECIMAL64 OFF + +struct S1 { +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */ + int i; + int j; +}; + +struct S2 { + int i; +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */ + int j; +}; + +struct S3 { + int i; + int j; +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */ +}; + +enum E1 { +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-error "#pragma" } */ + one, + two +}; + +enum E2 { + red, +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-error "#pragma" } */ + blue +}; + +enum E3 { + cat, + dog +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-error "#pragma" } */ +}; + +double +#pragma STDC FLOAT_CONST_DECIMAL64 OFF /* { dg-error "#pragma" } */ +b; + +double +f1 (void) +{ +#pragma STDC FLOAT_CONST_DECIMAL64 ON + return a; +} + +double +f2 (void) +{ + double b; +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */ + b = 0.5; + return a + b; +} + +#pragma STDC FLOAT_CONST_DECIMAL64 OFF + +double +f3 (void) +{ + typedef double b32; +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */ + b32 b = 0.5; + return b; +} + +double +f4 (int i) +{ +top: +#pragma STDC FLOAT_CONST_DECIMAL64 OFF /* { dg-warning "invalid location" } */ + if (i == 0) + return a; + a *= 2.; + i = 0; + goto top; +} + +double +f5 (int i) +{ + a = a * i; +#pragma STDC FLOAT_CONST_DECIMAL64 OFF /* { dg-warning "invalid location" } */ + return a * 2.; +} + +double +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-error "#pragma" } */ +f6 (void) +{ + return a; +} + +double +f7 +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-error "#pragma" } */ +(void) /* { dg-error "before" } */ +{ + return a; +} + +double +f8 (void) +{ + { +#pragma STDC FLOAT_CONST_DECIMAL64 OFF + } +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */ + return a; +} + +extern void foo9 (void *); + +double +f9 (void) +{ + __label__ here; +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */ + foo9 (&&here); +here: + return a; +} + +double +f10 (void) +{ + void foo10 (void) + { + a = 1.0; + } +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */ + return a; +} + +double +f11 (void) +{ + __extension__ + struct A { + struct { char a; }; + char b; + }; +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */ + return a; +} + +double +f12 (void) +{ + __extension__ ({ a = 0.5; }); +#pragma STDC FLOAT_CONST_DECIMAL64 ON /* { dg-warning "invalid location" } */ + return a; +} -- 2.30.2