OSDN Git Service

2009-05-08 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / c-lex.c
index c3e7f6e..fc89279 100644 (file)
@@ -205,10 +205,13 @@ fe_file_change (const struct line_map *new_map)
         we already did in compile_file.  */
       if (!MAIN_FILE_P (new_map))
        {
-         int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1);
+         unsigned int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1);
+         int line = 0;
+         if (included_at > BUILTINS_LOCATION)
+           line = SOURCE_LINE (new_map - 1, included_at);
 
          input_location = new_map->start_location;
-         (*debug_hooks->start_source_file) (included_at, new_map->to_file);
+         (*debug_hooks->start_source_file) (line, new_map->to_file);
 #ifndef NO_IMPLICIT_EXTERN_C
          if (c_header_level)
            ++c_header_level;
@@ -236,7 +239,6 @@ fe_file_change (const struct line_map *new_map)
     }
 
   update_header_times (new_map->to_file);
-  in_system_header = new_map->sysp != 0;
   input_location = new_map->start_location;
 }
 
@@ -468,7 +470,7 @@ narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
                         unsigned HOST_WIDE_INT high,
                         unsigned int flags)
 {
-  enum integer_type_kind itk;
+  int itk;
 
   if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
     itk = itk_unsigned_int;
@@ -484,7 +486,7 @@ narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
       if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
          || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
              && TREE_INT_CST_LOW (upper) >= low))
-       return itk;
+       return (enum integer_type_kind) itk;
     }
 
   return itk_none;
@@ -495,7 +497,7 @@ static enum integer_type_kind
 narrowest_signed_type (unsigned HOST_WIDE_INT low,
                       unsigned HOST_WIDE_INT high, unsigned int flags)
 {
-  enum integer_type_kind itk;
+  int itk;
 
   if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
     itk = itk_int;
@@ -512,7 +514,7 @@ narrowest_signed_type (unsigned HOST_WIDE_INT low,
       if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
          || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
              && TREE_INT_CST_LOW (upper) >= low))
-       return itk;
+       return (enum integer_type_kind) itk;
     }
 
   return itk_none;
@@ -580,13 +582,18 @@ interpret_integer (const cpp_token *token, unsigned int flags)
            ? widest_unsigned_literal_type_node
            : widest_integer_literal_type_node);
   else
-    type = integer_types[itk];
-
-  if (itk > itk_unsigned_long
-      && (flags & CPP_N_WIDTH) != CPP_N_LARGE
-      && !in_system_header && !flag_isoc99)
-    pedwarn ("integer constant is too large for %qs type",
-            (flags & CPP_N_UNSIGNED) ? "unsigned long" : "long");
+    {
+      type = integer_types[itk];
+      if (itk > itk_unsigned_long
+         && (flags & CPP_N_WIDTH) != CPP_N_LARGE)
+       emit_diagnostic 
+         ((c_dialect_cxx () ? cxx_dialect == cxx98 : !flag_isoc99)
+          ? DK_PEDWARN : DK_WARNING,
+          input_location, OPT_Wlong_long,
+          (flags & CPP_N_UNSIGNED) 
+          ? "integer constant is too large for %<unsigned long%> type"
+          : "integer constant is too large for %<long%> type");
+    }
 
   value = build_int_cst_wide (type, integer.low, integer.high);
 
@@ -603,11 +610,30 @@ static tree
 interpret_float (const cpp_token *token, unsigned int flags)
 {
   tree type;
+  tree const_type;
   tree value;
   REAL_VALUE_TYPE real;
+  REAL_VALUE_TYPE real_trunc;
   char *copy;
   size_t copylen;
 
+  /* 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.  */
   if (flags & CPP_N_FRACT || flags & CPP_N_ACCUM)
     return interpret_fixed (token, flags);
@@ -639,8 +665,8 @@ interpret_float (const cpp_token *token, unsigned int flags)
 
            return error_mark_node;
          }
-       else if (pedantic)
-         pedwarn ("non-standard suffix on floating constant");
+       else
+         pedwarn (input_location, OPT_pedantic, "non-standard suffix on floating constant");
 
        type = c_common_type_for_mode (mode, 0);
        gcc_assert (type);
@@ -653,6 +679,10 @@ interpret_float (const cpp_token *token, unsigned int flags)
     else
       type = double_type_node;
 
+  const_type = excess_precision_type (type);
+  if (!const_type)
+    const_type = type;
+
   /* Copy the constant to a nul-terminated buffer.  If the constant
      has any suffixes, cut them off; REAL_VALUE_ATOF/ REAL_VALUE_HTOF
      can't handle them.  */
@@ -673,21 +703,30 @@ interpret_float (const cpp_token *token, unsigned int flags)
   memcpy (copy, token->val.str.text, copylen);
   copy[copylen] = '\0';
 
-  real_from_string3 (&real, copy, TYPE_MODE (type));
+  real_from_string3 (&real, copy, TYPE_MODE (const_type));
+  if (const_type != type)
+    /* Diagnosing if the result of converting the value with excess
+       precision to the semantic type would overflow (with associated
+       double rounding) is more appropriate than diagnosing if the
+       result of converting the string directly to the semantic type
+       would overflow.  */
+    real_convert (&real_trunc, TYPE_MODE (type), &real);
 
   /* Both C and C++ require a diagnostic for a floating constant
      outside the range of representable values of its type.  Since we
      have __builtin_inf* to produce an infinity, this is now a
      mandatory pedwarn if the target does not support infinities.  */
-  if (REAL_VALUE_ISINF (real)) 
+  if (REAL_VALUE_ISINF (real)
+      || (const_type != type && REAL_VALUE_ISINF (real_trunc)))
     {
       if (!MODE_HAS_INFINITIES (TYPE_MODE (type)))
-       pedwarn ("floating constant exceeds range of %qT", type);
+       pedwarn (input_location, 0, "floating constant exceeds range of %qT", type);
       else
        warning (OPT_Woverflow, "floating constant exceeds range of %qT", type);
     }
   /* We also give a warning if the value underflows.  */
-  else if (REAL_VALUES_EQUAL (real, dconst0))
+  else if (REAL_VALUES_EQUAL (real, dconst0)
+          || (const_type != type && REAL_VALUES_EQUAL (real_trunc, dconst0)))
     {
       REAL_VALUE_TYPE realvoidmode;
       int overflow = real_from_string (&realvoidmode, copy);
@@ -696,9 +735,13 @@ interpret_float (const cpp_token *token, unsigned int flags)
     }
 
   /* Create a node with determined type and value.  */
-  value = build_real (type, real);
+  value = build_real (const_type, real);
   if (flags & CPP_N_IMAGINARY)
-    value = build_complex (NULL_TREE, convert (type, integer_zero_node), value);
+    value = build_complex (NULL_TREE, convert (const_type, integer_zero_node),
+                          value);
+
+  if (type != const_type)
+    value = build1 (EXCESS_PRECISION_EXPR, type, value);
 
   return value;
 }
@@ -974,7 +1017,7 @@ lex_charconst (const cpp_token *token)
   cppchar_t result;
   tree type, value;
   unsigned int chars_seen;
-  int unsignedp;
+  int unsignedp = 0;
 
   result = cpp_interpret_charconst (parse_in, token,
                                    &chars_seen, &unsignedp);