re PR c/39037 (FLOAT_CONST_DECIMAL64 pragma not supported)
authorJanis Johnson <janis187@us.ibm.com>
Thu, 7 May 2009 22:34:08 +0000 (22:34 +0000)
committerJanis Johnson <janis@gcc.gnu.org>
Thu, 7 May 2009 22:34:08 +0000 (22:34 +0000)
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

24 files changed:
gcc/ChangeLog
gcc/c-common.h
gcc/c-cppbuiltin.c
gcc/c-decl.c
gcc/c-lex.c
gcc/c-parser.c
gcc/c-pragma.c
gcc/c.opt
gcc/cp/semantics.c
gcc/doc/extend.texi
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp/pragma-float-const-decimal64-1.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/Wunsuffixed-float-constants-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/pragma-float-const-decimal64-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/float-constant-double.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/dfp/pragma-float-const-decimal64-8.c [new file with mode: 0644]

index e1ffdd3dd2c865e589dee0deafb0eeac1e4c3736..7d24caae3542338a26b6186492bee27adc1f00c0 100644 (file)
@@ -1,3 +1,34 @@
+2009-05-07  Janis Johnson  <janis187@us.ibm.com>
+
+       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  <steven@gcc.gnu.org>
 
        * config/i386/i386.c: Do not include c-common.h.
index 14448800ce09137c203f284f79993865b0f67bc6..250a7ff74fa0052db79096fa71329b5a77588acf 100644 (file)
@@ -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)
index 8b776b15dbcf121026315831d9db5d1043e973f9..921addbccf0961cc3518b1191d40b83428bc8a06 100644 (file)
@@ -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.  */
index 85c4d6bf02d5fe5cb210caa4b2e136c82261edfa..409c458e195a0655b44b9770fcef6ea2be30ebde 100644 (file)
@@ -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;
index df6354843bf38a57d7b009382bb0bb46caafa600..fc89279a7d9e20468cf925baa3ccfc40b3fc467a 100644 (file)
@@ -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.  */
index 6c839e9104cc20768e175f2f544d56ba7944d7fb..033c8350776bf78b40df320ed0133b27269a4925 100644 (file)
@@ -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 %<else%>");
               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).
index 64a224f4a28a58e08c621641618ea3fc80cf41e8..bd71d1d79e8079062006aece18c855f7c1441fa6 100644 (file)
@@ -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 %<pragma %s%>, 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);
 
index 7f71699faa7351c6a781e2673e983e7a7086f36d..fc34ff57f78b46850ecb52fa917393be363b5e74 100644 (file)
--- 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
index dd84891d73be67be6cde153d88685d7376846a80..4c0c91d590573c97036358467fcaf1a11101b187 100644 (file)
@@ -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"
index 4e06be3daca79fca6a52b98c49753385971b737e..43bebf911c00520549c11d5b532f72336b7d2749 100644 (file)
@@ -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
index 2674c47ef89e8e8a57fc4bf6b68c5b24c9a5c7f9..3fc575d34de25c585a7abfb9855e86d28b6de5c9 100644 (file)
@@ -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
index eff2991e1a727f9c5d8bb880bc8decc68c517036..2dc3dd9e3e9e0187973ac9a5bcefa29131d5dda7 100644 (file)
@@ -1,3 +1,19 @@
+2009-05-07  Janis Johnson  <janis187@us.ibm.com>
+
+       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  <jakub@redhat.com>
 
        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 (file)
index 0000000..31e1ad6
--- /dev/null
@@ -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 (file)
index 0000000..b4a38d5
--- /dev/null
@@ -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 (file)
index 0000000..6333838
--- /dev/null
@@ -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 (file)
index 0000000..3f8de65
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99" } */
+
+/* Constant float values of type double in <float.h> 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 <float.h>
+
+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 (file)
index 0000000..79fabf3
--- /dev/null
@@ -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 (file)
index 0000000..212748c
--- /dev/null
@@ -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 (file)
index 0000000..b9286aa
--- /dev/null
@@ -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 (file)
index 0000000..86cec1d
--- /dev/null
@@ -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 (file)
index 0000000..75e9525
--- /dev/null
@@ -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 (file)
index 0000000..03c1715
--- /dev/null
@@ -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 (file)
index 0000000..7533ee7
--- /dev/null
@@ -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 (file)
index 0000000..5dbbda5
--- /dev/null
@@ -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;
+}