OSDN Git Service

2010-04-14 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / fortran / intrinsic.c
index a92b5b5..470839a 100644 (file)
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 /* Namespace to hold the resolved symbols for intrinsic subroutines.  */
 static gfc_namespace *gfc_intrinsic_namespace;
 
-bool gfc_init_expr_flag = false;
+int gfc_init_expr = 0;
 
 /* Pointers to an intrinsic function and its argument names that are being
    checked.  */
@@ -956,14 +956,17 @@ gfc_is_intrinsic (gfc_symbol* sym, int subroutine_flag, locus loc)
   /* See if this intrinsic is allowed in the current standard.  */
   if (gfc_check_intrinsic_standard (isym, &symstd, false, loc) == FAILURE)
     {
-      if (sym->attr.proc == PROC_UNKNOWN
-         && gfc_option.warn_intrinsics_std)
-       gfc_warning_now ("The intrinsic '%s' at %L is not included in the"
-                        " selected standard but %s and '%s' will be"
-                        " treated as if declared EXTERNAL.  Use an"
-                        " appropriate -std=* option or define"
-                        " -fall-intrinsics to allow this intrinsic.",
-                        sym->name, &loc, symstd, sym->name);
+      if (sym->attr.proc == PROC_UNKNOWN)
+       {
+         if (gfc_option.warn_intrinsics_std)
+           gfc_warning_now ("The intrinsic '%s' at %L is not included in the"
+                            " selected standard but %s and '%s' will be"
+                            " treated as if declared EXTERNAL.  Use an"
+                            " appropriate -std=* option or define"
+                            " -fall-intrinsics to allow this intrinsic.",
+                            sym->name, &loc, symstd, sym->name);
+         gfc_add_external (&sym->attr, &loc);
+       }
 
       return false;
     }
@@ -1476,6 +1479,8 @@ add_functions (void)
             gfc_check_dble, gfc_simplify_dble, gfc_resolve_dble,
             a, BT_REAL, dr, REQUIRED);
 
+  make_alias ("dfloat", GFC_STD_GNU);
+
   make_generic ("dble", GFC_ISYM_DBLE, GFC_STD_F77);
 
   add_sym_1 ("digits", GFC_ISYM_DIGITS, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
@@ -1781,7 +1786,7 @@ add_functions (void)
   make_generic ("ierrno", GFC_ISYM_IERRNO, GFC_STD_GNU);
 
   add_sym_2 ("image_index", GFC_ISYM_IMAGE_INDEX, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F2008,
-            gfc_check_image_index, gfc_simplify_image_index, gfc_resolve_image_index,
+            gfc_check_image_index, gfc_simplify_image_index, NULL,
             ca, BT_REAL, dr, REQUIRED, sub, BT_INTEGER, ii, REQUIRED);
 
   /* The resolution function for INDEX is called gfc_resolve_index_func
@@ -1920,12 +1925,12 @@ add_functions (void)
   make_generic ("lbound", GFC_ISYM_LBOUND, GFC_STD_F95);
 
   add_sym_3 ("lcobound", GFC_ISYM_LCOBOUND, CLASS_INQUIRY, ACTUAL_NO,
-            BT_INTEGER, di, GFC_STD_F2008,
-            gfc_check_lcobound, gfc_simplify_lcobound, gfc_resolve_lcobound,
+            BT_INTEGER, di, GFC_STD_F95,
+            gfc_check_lcobound, gfc_simplify_lcobound, NULL,
             ca, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
             kind, BT_INTEGER, di, OPTIONAL);
 
-  make_generic ("lcobound", GFC_ISYM_LCOBOUND, GFC_STD_F2008);
+  make_generic ("lcobound", GFC_ISYM_LCOBOUND, GFC_STD_F95);
 
   add_sym_1 ("leadz", GFC_ISYM_LEADZ, CLASS_ELEMENTAL, ACTUAL_NO,
             BT_INTEGER, di, GFC_STD_F2008,
@@ -2291,15 +2296,11 @@ add_functions (void)
             a, BT_UNKNOWN, dr, REQUIRED);
 
   add_sym_1 ("float", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F77,
-            gfc_check_float, gfc_simplify_float, NULL,
+            gfc_check_i, gfc_simplify_float, NULL,
             a, BT_INTEGER, di, REQUIRED);
 
-  add_sym_1 ("dfloat", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dd, GFC_STD_GNU,
-            gfc_check_float, gfc_simplify_dble, gfc_resolve_dble,
-            a, BT_REAL, dr, REQUIRED);
-
   add_sym_1 ("sngl", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F77,
-            gfc_check_sngl, gfc_simplify_sngl, NULL,
+            NULL, gfc_simplify_sngl, NULL,
             a, BT_REAL, dd, REQUIRED);
 
   make_generic ("real", GFC_ISYM_REAL, GFC_STD_F77);
@@ -2539,7 +2540,7 @@ add_functions (void)
   make_generic ("tanh", GFC_ISYM_TANH, GFC_STD_F77);
 
   add_sym_2 ("this_image", GFC_ISYM_THIS_IMAGE, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F2008,
-            gfc_check_this_image, gfc_simplify_this_image, gfc_resolve_this_image,
+            gfc_check_this_image, gfc_simplify_this_image, NULL,
             ca, BT_REAL, dr, OPTIONAL, dm, BT_INTEGER, ii, OPTIONAL);
 
   add_sym_0 ("time", GFC_ISYM_TIME, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU, 
@@ -2599,12 +2600,12 @@ add_functions (void)
   make_generic ("ubound", GFC_ISYM_UBOUND, GFC_STD_F95);
 
   add_sym_3 ("ucobound", GFC_ISYM_UCOBOUND, CLASS_INQUIRY, ACTUAL_NO,
-            BT_INTEGER, di, GFC_STD_F2008,
-            gfc_check_ucobound, gfc_simplify_ucobound, gfc_resolve_ucobound,
+            BT_INTEGER, di, GFC_STD_F95,
+            gfc_check_ucobound, gfc_simplify_ucobound, NULL,
             ca, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
             kind, BT_INTEGER, di, OPTIONAL);
 
-  make_generic ("ucobound", GFC_ISYM_UCOBOUND, GFC_STD_F2008);
+  make_generic ("ucobound", GFC_ISYM_UCOBOUND, GFC_STD_F95);
 
   /* g77 compatibility for UMASK.  */
   add_sym_1 ("umask", GFC_ISYM_UMASK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
@@ -3291,7 +3292,7 @@ keywords:
 
       if (f->actual != NULL)
        {
-         gfc_error ("Argument '%s' appears twice in call to '%s' at %L",
+         gfc_error ("Argument '%s' is appears twice in call to '%s' at %L",
                     f->name, name, where);
          return FAILURE;
        }
@@ -3805,7 +3806,7 @@ gfc_intrinsic_func_interface (gfc_expr *expr, int error_flag)
 
   if ((isym->id == GFC_ISYM_REAL || isym->id == GFC_ISYM_DBLE
        || isym->id == GFC_ISYM_CMPLX)
-      && gfc_init_expr_flag
+      && gfc_init_expr
       && gfc_notify_std (GFC_STD_F2003, "Fortran 2003: Function '%s' "
                         "as initialization expression at %L", name,
                         &expr->where) == FAILURE)
@@ -3881,7 +3882,7 @@ got_specific:
      (4)   A reference to an elemental standard intrinsic function,
            where each argument is an initialization expression  */
 
-  if (gfc_init_expr_flag && isym->elemental && flag
+  if (gfc_init_expr && isym->elemental && flag
       && gfc_notify_std (GFC_STD_F2003, "Fortran 2003: Elemental function "
                        "as initialization expression with non-integer/non-"
                        "character arguments at %L", &expr->where) == FAILURE)
@@ -4015,66 +4016,11 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
 
   /* At this point, a conversion is necessary. A warning may be needed.  */
   if ((gfc_option.warn_std & sym->standard) != 0)
-    {
-      gfc_warning_now ("Extension: Conversion from %s to %s at %L",
-                      gfc_typename (&from_ts), gfc_typename (ts),
-                      &expr->where);
-    }
-  else if (wflag)
-    {
-      /* Two modes of warning:
-         - gfc_option.warn_conversion tries to be more intelligent
-           about the warnings raised and omits those where smaller
-           kinds are promoted to larger ones without change in the
-           value
-         - gfc_option.warn_conversion_extra does not take the kinds
-           into account and also warns for coversions like
-           REAL(4) -> REAL(8)
-
-        NOTE: Possible enhancement for warn_conversion
-        If converting from a smaller to a larger kind, check if the
-        value is constant and if yes, whether the value still fits
-        in the smaller kind. If yes, omit the warning.
-      */
-
-      /* If the types are the same (but not LOGICAL), and if from-kind
-        is larger than to-kind, this may indicate a loss of precision.
-        The same holds for conversions from REAL to COMPLEX.  */
-      if (((from_ts.type == ts->type && from_ts.type != BT_LOGICAL)
-           && ((gfc_option.warn_conversion && from_ts.kind > ts->kind)
-              || gfc_option.warn_conversion_extra))
-         || ((from_ts.type == BT_REAL && ts->type == BT_COMPLEX)
-             && ((gfc_option.warn_conversion && from_ts.kind > ts->kind)
-                 || gfc_option.warn_conversion_extra)))
-       gfc_warning_now ("Possible change of value in conversion "
-                        "from %s to %s at %L", gfc_typename (&from_ts),
-                        gfc_typename (ts), &expr->where);
-
-      /* If INTEGER is converted to REAL/COMPLEX, this is generally ok if
-        the kind of the INTEGER value is less or equal to the kind of the
-        REAL/COMPLEX one. Otherwise the value may not fit.
-        Assignment of an overly large integer constant also generates
-        an overflow error with range checking. */
-      else if (from_ts.type == BT_INTEGER
-              && (ts->type == BT_REAL || ts->type == BT_COMPLEX)
-              && ((gfc_option.warn_conversion && from_ts.kind > ts->kind)
-                  || gfc_option.warn_conversion_extra))
-       gfc_warning_now ("Possible change of value in conversion "
-                        "from %s to %s at %L", gfc_typename (&from_ts),
-                        gfc_typename (ts), &expr->where);
-
-      /* If REAL/COMPLEX is converted to INTEGER, or COMPLEX is converted
-        to REAL we almost certainly have a loss of digits, regardless of
-        the respective kinds.  */
-      else if ((((from_ts.type == BT_REAL || from_ts.type == BT_COMPLEX)
-                 && ts->type == BT_INTEGER)
-               || (from_ts.type == BT_COMPLEX && ts->type == BT_REAL))
-              && (gfc_option.warn_conversion
-                  || gfc_option.warn_conversion_extra))
-       gfc_warning_now ("Possible change of value in conversion from "
-                       "%s to %s at %L", gfc_typename (&from_ts),
-                       gfc_typename (ts), &expr->where);
-    }
+    gfc_warning_now ("Extension: Conversion from %s to %s at %L",
+                    gfc_typename (&from_ts), gfc_typename (ts), &expr->where);
+  else if (wflag && gfc_option.warn_conversion)
+    gfc_warning_now ("Conversion from %s to %s at %L",
+                    gfc_typename (&from_ts), gfc_typename (ts), &expr->where);
 
   /* Insert a pre-resolved function call to the right function.  */
   old_where = expr->where;