gfortran.h (gfc_option_t): Remove warn_aliasing,
[gcc.git] / gcc / fortran / intrinsic.c
index 494b8165584bb03d91baca431aba8fefa5790924..5dd4092e63a2d22a04ab06d296f4366acc54ff3e 100644 (file)
@@ -1,8 +1,6 @@
 /* Build up a list of intrinsic subroutines and functions for the
    name-resolution stage.
 /* Build up a list of intrinsic subroutines and functions for the
    name-resolution stage.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2000-2014 Free Software Foundation, Inc.
    Contributed by Andy Vaught & Katherine Holcomb
 
 This file is part of GCC.
    Contributed by Andy Vaught & Katherine Holcomb
 
 This file is part of GCC.
@@ -23,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "config.h"
 #include "system.h"
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
 #include "flags.h"
 #include "gfortran.h"
 #include "intrinsic.h"
 #include "flags.h"
 #include "gfortran.h"
 #include "intrinsic.h"
@@ -30,13 +29,13 @@ 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;
 
 /* Namespace to hold the resolved symbols for intrinsic subroutines.  */
 static gfc_namespace *gfc_intrinsic_namespace;
 
-int gfc_init_expr = 0;
+bool gfc_init_expr_flag = false;
 
 /* Pointers to an intrinsic function and its argument names that are being
    checked.  */
 
 const char *gfc_current_intrinsic;
 
 /* Pointers to an intrinsic function and its argument names that are being
    checked.  */
 
 const char *gfc_current_intrinsic;
-const char *gfc_current_intrinsic_arg[MAX_INTRINSIC_ARGS];
+gfc_intrinsic_arg *gfc_current_intrinsic_arg[MAX_INTRINSIC_ARGS];
 locus *gfc_current_intrinsic_where;
 
 static gfc_intrinsic_sym *functions, *subroutines, *conversion, *next_sym;
 locus *gfc_current_intrinsic_where;
 
 static gfc_intrinsic_sym *functions, *subroutines, *conversion, *next_sym;
@@ -50,7 +49,8 @@ static enum
 sizing;
 
 enum klass
 sizing;
 
 enum klass
-{ NO_CLASS = 0, CLASS_ELEMENTAL, CLASS_INQUIRY, CLASS_TRANSFORMATIONAL };
+{ CLASS_IMPURE = 0, CLASS_PURE, CLASS_ELEMENTAL,
+  CLASS_INQUIRY, CLASS_TRANSFORMATIONAL, CLASS_ATOMIC };
 
 #define ACTUAL_NO      0
 #define ACTUAL_YES     1
 
 #define ACTUAL_NO      0
 #define ACTUAL_YES     1
@@ -112,6 +112,8 @@ gfc_get_intrinsic_sub_symbol (const char *name)
   sym->attr.flavor = FL_PROCEDURE;
   sym->attr.proc = PROC_INTRINSIC;
 
   sym->attr.flavor = FL_PROCEDURE;
   sym->attr.proc = PROC_INTRINSIC;
 
+  gfc_commit_symbol (sym);
+
   return sym;
 }
 
   return sym;
 }
 
@@ -172,11 +174,77 @@ find_char_conv (gfc_typespec *from, gfc_typespec *to)
 }
 
 
 }
 
 
+/* Check TS29113, C407b for assumed type and C535b for assumed-rank,
+   and a likewise check for NO_ARG_CHECK.  */
+
+static bool
+do_ts29113_check (gfc_intrinsic_sym *specific, gfc_actual_arglist *arg)
+{
+  gfc_actual_arglist *a;
+
+  for (a = arg; a; a = a->next)
+    {
+      if (!a->expr)
+       continue;
+
+      if (a->expr->expr_type == EXPR_VARIABLE
+         && (a->expr->symtree->n.sym->attr.ext_attr
+             & (1 << EXT_ATTR_NO_ARG_CHECK))
+         && specific->id != GFC_ISYM_C_LOC
+         && specific->id != GFC_ISYM_PRESENT)
+       {
+         gfc_error ("Variable with NO_ARG_CHECK attribute at %L is only "
+                    "permitted as argument to the intrinsic functions "
+                    "C_LOC and PRESENT", &a->expr->where);
+         return false;
+       }
+      else if (a->expr->ts.type == BT_ASSUMED
+              && specific->id != GFC_ISYM_LBOUND
+              && specific->id != GFC_ISYM_PRESENT
+              && specific->id != GFC_ISYM_RANK
+              && specific->id != GFC_ISYM_SHAPE
+              && specific->id != GFC_ISYM_SIZE
+              && specific->id != GFC_ISYM_SIZEOF
+              && specific->id != GFC_ISYM_UBOUND
+              && specific->id != GFC_ISYM_C_LOC)
+       {
+         gfc_error ("Assumed-type argument at %L is not permitted as actual"
+                    " argument to the intrinsic %s", &a->expr->where,
+                    gfc_current_intrinsic);
+         return false;
+       }
+      else if (a->expr->ts.type == BT_ASSUMED && a != arg)
+       {
+         gfc_error ("Assumed-type argument at %L is only permitted as "
+                    "first actual argument to the intrinsic %s",
+                    &a->expr->where, gfc_current_intrinsic);
+         return false;
+       }
+      if (a->expr->rank == -1 && !specific->inquiry)
+       {
+         gfc_error ("Assumed-rank argument at %L is only permitted as actual "
+                    "argument to intrinsic inquiry functions",
+                    &a->expr->where);
+         return false;
+       }
+      if (a->expr->rank == -1 && arg != a)
+       {
+         gfc_error ("Assumed-rank argument at %L is only permitted as first "
+                    "actual argument to the intrinsic inquiry function %s",
+                    &a->expr->where, gfc_current_intrinsic);
+         return false;
+       }
+    }
+
+  return true;
+}
+
+
 /* Interface to the check functions.  We break apart an argument list
    and call the proper check function rather than forcing each
    function to manipulate the argument list.  */
 
 /* Interface to the check functions.  We break apart an argument list
    and call the proper check function rather than forcing each
    function to manipulate the argument list.  */
 
-static gfc_try
+static bool
 do_check (gfc_intrinsic_sym *specific, gfc_actual_arglist *arg)
 {
   gfc_expr *a1, *a2, *a3, *a4, *a5;
 do_check (gfc_intrinsic_sym *specific, gfc_actual_arglist *arg)
 {
   gfc_expr *a1, *a2, *a3, *a4, *a5;
@@ -271,6 +339,7 @@ add_sym (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type
       strcat (buf, name);
       next_sym->lib_name = gfc_get_string (buf);
 
       strcat (buf, name);
       next_sym->lib_name = gfc_get_string (buf);
 
+      next_sym->pure = (cl != CLASS_IMPURE);
       next_sym->elemental = (cl == CLASS_ELEMENTAL);
       next_sym->inquiry = (cl == CLASS_INQUIRY);
       next_sym->transformational = (cl == CLASS_TRANSFORMATIONAL);
       next_sym->elemental = (cl == CLASS_ELEMENTAL);
       next_sym->inquiry = (cl == CLASS_INQUIRY);
       next_sym->transformational = (cl == CLASS_TRANSFORMATIONAL);
@@ -323,6 +392,7 @@ add_sym (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type
          next_arg->ts.type = type;
          next_arg->ts.kind = kind;
          next_arg->optional = optional;
          next_arg->ts.type = type;
          next_arg->ts.kind = kind;
          next_arg->optional = optional;
+         next_arg->value = 0;
          next_arg->intent = intent;
        }
     }
          next_arg->intent = intent;
        }
     }
@@ -339,7 +409,7 @@ add_sym (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type
 static void
 add_sym_0 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
           int kind, int standard,
 static void
 add_sym_0 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
           int kind, int standard,
-          gfc_try (*check) (void),
+          bool (*check) (void),
           gfc_expr *(*simplify) (void),
           void (*resolve) (gfc_expr *))
 {
           gfc_expr *(*simplify) (void),
           void (*resolve) (gfc_expr *))
 {
@@ -360,7 +430,8 @@ add_sym_0 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt ty
    0 arguments.  */
 
 static void
    0 arguments.  */
 
 static void
-add_sym_0s (const char *name, gfc_isym_id id, int standard, void (*resolve) (gfc_code *))
+add_sym_0s (const char *name, gfc_isym_id id, int standard,
+           void (*resolve) (gfc_code *))
 {
   gfc_check_f cf;
   gfc_simplify_f sf;
 {
   gfc_check_f cf;
   gfc_simplify_f sf;
@@ -370,8 +441,8 @@ add_sym_0s (const char *name, gfc_isym_id id, int standard, void (*resolve) (gfc
   sf.f1 = NULL;
   rf.s1 = resolve;
 
   sf.f1 = NULL;
   rf.s1 = resolve;
 
-  add_sym (name, id, NO_CLASS, ACTUAL_NO, BT_UNKNOWN, 0, standard, cf, sf, rf,
-          (void *) 0);
+  add_sym (name, id, CLASS_IMPURE, ACTUAL_NO, BT_UNKNOWN, 0, standard, cf, sf,
+          rf, (void *) 0);
 }
 
 
 }
 
 
@@ -381,7 +452,7 @@ add_sym_0s (const char *name, gfc_isym_id id, int standard, void (*resolve) (gfc
 static void
 add_sym_1 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
           int kind, int standard,
 static void
 add_sym_1 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
           int kind, int standard,
-          gfc_try (*check) (gfc_expr *),
+          bool (*check) (gfc_expr *),
           gfc_expr *(*simplify) (gfc_expr *),
           void (*resolve) (gfc_expr *, gfc_expr *),
           const char *a1, bt type1, int kind1, int optional1)
           gfc_expr *(*simplify) (gfc_expr *),
           void (*resolve) (gfc_expr *, gfc_expr *),
           const char *a1, bt type1, int kind1, int optional1)
@@ -400,37 +471,13 @@ add_sym_1 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt ty
 }
 
 
 }
 
 
-/* Add a symbol to the subroutine list where the subroutine takes
-   1 arguments.  */
-
-static void
-add_sym_1s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind, int standard,
-           gfc_try (*check) (gfc_expr *),
-           gfc_expr *(*simplify) (gfc_expr *),
-           void (*resolve) (gfc_code *),
-           const char *a1, bt type1, int kind1, int optional1)
-{
-  gfc_check_f cf;
-  gfc_simplify_f sf;
-  gfc_resolve_f rf;
-
-  cf.f1 = check;
-  sf.f1 = simplify;
-  rf.s1 = resolve;
-
-  add_sym (name, id, cl, ACTUAL_NO, type, kind, standard, cf, sf, rf,
-          a1, type1, kind1, optional1, INTENT_IN,
-          (void *) 0);
-}
-
-
 /* Add a symbol to the function list where the function takes
    1 arguments, specifying the intent of the argument.  */
 
 static void
 add_sym_1_intent (const char *name, gfc_isym_id id, enum klass cl,
                  int actual_ok, bt type, int kind, int standard,
 /* Add a symbol to the function list where the function takes
    1 arguments, specifying the intent of the argument.  */
 
 static void
 add_sym_1_intent (const char *name, gfc_isym_id id, enum klass cl,
                  int actual_ok, bt type, int kind, int standard,
-                 gfc_try (*check) (gfc_expr *),
+                 bool (*check) (gfc_expr *),
                  gfc_expr *(*simplify) (gfc_expr *),
                  void (*resolve) (gfc_expr *, gfc_expr *),
                  const char *a1, bt type1, int kind1, int optional1,
                  gfc_expr *(*simplify) (gfc_expr *),
                  void (*resolve) (gfc_expr *, gfc_expr *),
                  const char *a1, bt type1, int kind1, int optional1,
@@ -454,13 +501,11 @@ add_sym_1_intent (const char *name, gfc_isym_id id, enum klass cl,
    1 arguments, specifying the intent of the argument.  */
 
 static void
    1 arguments, specifying the intent of the argument.  */
 
 static void
-add_sym_1s_intent (const char *name, gfc_isym_id id, enum klass cl, bt type,
-                  int kind, int standard,
-                  gfc_try (*check) (gfc_expr *),
-                  gfc_expr *(*simplify) (gfc_expr *),
-                  void (*resolve) (gfc_code *),
-                  const char *a1, bt type1, int kind1, int optional1,
-                  sym_intent intent1)
+add_sym_1s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
+           int standard, bool (*check) (gfc_expr *),
+           gfc_expr *(*simplify) (gfc_expr *), void (*resolve) (gfc_code *),
+           const char *a1, bt type1, int kind1, int optional1,
+           sym_intent intent1)
 {
   gfc_check_f cf;
   gfc_simplify_f sf;
 {
   gfc_check_f cf;
   gfc_simplify_f sf;
@@ -482,7 +527,7 @@ add_sym_1s_intent (const char *name, gfc_isym_id id, enum klass cl, bt type,
 static void
 add_sym_1m (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
            int kind, int standard,
 static void
 add_sym_1m (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
            int kind, int standard,
-           gfc_try (*check) (gfc_actual_arglist *),
+           bool (*check) (gfc_actual_arglist *),
            gfc_expr *(*simplify) (gfc_expr *),
            void (*resolve) (gfc_expr *, gfc_actual_arglist *),
            const char *a1, bt type1, int kind1, int optional1,
            gfc_expr *(*simplify) (gfc_expr *),
            void (*resolve) (gfc_expr *, gfc_actual_arglist *),
            const char *a1, bt type1, int kind1, int optional1,
@@ -509,7 +554,7 @@ add_sym_1m (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt t
 static void
 add_sym_2 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
           int kind, int standard,
 static void
 add_sym_2 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
           int kind, int standard,
-          gfc_try (*check) (gfc_expr *, gfc_expr *),
+          bool (*check) (gfc_expr *, gfc_expr *),
           gfc_expr *(*simplify) (gfc_expr *, gfc_expr *),
           void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *),
           const char *a1, bt type1, int kind1, int optional1,
           gfc_expr *(*simplify) (gfc_expr *, gfc_expr *),
           void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *),
           const char *a1, bt type1, int kind1, int optional1,
@@ -530,16 +575,18 @@ add_sym_2 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt ty
 }
 
 
 }
 
 
-/* Add a symbol to the subroutine list where the subroutine takes
-   2 arguments.  */
+/* Add a symbol to the function list where the function takes
+   2 arguments; same as add_sym_2 - but allows to specify the intent.  */
 
 static void
 
 static void
-add_sym_2s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind, int standard,
-           gfc_try (*check) (gfc_expr *, gfc_expr *),
-           gfc_expr *(*simplify) (gfc_expr *, gfc_expr *),
-           void (*resolve) (gfc_code *),
-           const char *a1, bt type1, int kind1, int optional1,
-           const char *a2, bt type2, int kind2, int optional2)
+add_sym_2_intent (const char *name, gfc_isym_id id, enum klass cl,
+                 int actual_ok, bt type, int kind, int standard,
+                 bool (*check) (gfc_expr *, gfc_expr *),
+                 gfc_expr *(*simplify) (gfc_expr *, gfc_expr *),
+                 void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *),
+                 const char *a1, bt type1, int kind1, int optional1,
+                 sym_intent intent1, const char *a2, bt type2, int kind2,
+                 int optional2, sym_intent intent2)
 {
   gfc_check_f cf;
   gfc_simplify_f sf;
 {
   gfc_check_f cf;
   gfc_simplify_f sf;
@@ -547,11 +594,11 @@ add_sym_2s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
 
   cf.f2 = check;
   sf.f2 = simplify;
 
   cf.f2 = check;
   sf.f2 = simplify;
-  rf.s1 = resolve;
+  rf.f2 = resolve;
 
 
-  add_sym (name, id, cl, ACTUAL_NO, type, kind, standard, cf, sf, rf,
-          a1, type1, kind1, optional1, INTENT_IN,
-          a2, type2, kind2, optional2, INTENT_IN,
+  add_sym (name, id, cl, actual_ok, type, kind, standard, cf, sf, rf,
+          a1, type1, kind1, optional1, intent1,
+          a2, type2, kind2, optional2, intent2,
           (void *) 0);
 }
 
           (void *) 0);
 }
 
@@ -560,14 +607,14 @@ add_sym_2s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
    2 arguments, specifying the intent of the arguments.  */
 
 static void
    2 arguments, specifying the intent of the arguments.  */
 
 static void
-add_sym_2s_intent (const char *name, gfc_isym_id id, enum klass cl, bt type,
-                  int kind, int standard,
-                  gfc_try (*check) (gfc_expr *, gfc_expr *),
-                  gfc_expr *(*simplify) (gfc_expr *, gfc_expr *),
-                  void (*resolve) (gfc_code *),
-                  const char *a1, bt type1, int kind1, int optional1,
-                  sym_intent intent1, const char *a2, bt type2, int kind2,
-                  int optional2, sym_intent intent2)
+add_sym_2s (const char *name, gfc_isym_id id, enum klass cl, bt type,
+           int kind, int standard,
+           bool (*check) (gfc_expr *, gfc_expr *),
+           gfc_expr *(*simplify) (gfc_expr *, gfc_expr *),
+           void (*resolve) (gfc_code *),
+           const char *a1, bt type1, int kind1, int optional1,
+           sym_intent intent1, const char *a2, bt type2, int kind2,
+           int optional2, sym_intent intent2)
 {
   gfc_check_f cf;
   gfc_simplify_f sf;
 {
   gfc_check_f cf;
   gfc_simplify_f sf;
@@ -590,7 +637,7 @@ add_sym_2s_intent (const char *name, gfc_isym_id id, enum klass cl, bt type,
 static void
 add_sym_3 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
           int kind, int standard,
 static void
 add_sym_3 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
           int kind, int standard,
-          gfc_try (*check) (gfc_expr *, gfc_expr *, gfc_expr *),
+          bool (*check) (gfc_expr *, gfc_expr *, gfc_expr *),
           gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
           void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
           const char *a1, bt type1, int kind1, int optional1,
           gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
           void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
           const char *a1, bt type1, int kind1, int optional1,
@@ -619,7 +666,7 @@ add_sym_3 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt ty
 static void
 add_sym_3ml (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
             int kind, int standard,
 static void
 add_sym_3ml (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
             int kind, int standard,
-            gfc_try (*check) (gfc_actual_arglist *),
+            bool (*check) (gfc_actual_arglist *),
             gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
             void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
             const char *a1, bt type1, int kind1, int optional1,
             gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
             void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
             const char *a1, bt type1, int kind1, int optional1,
@@ -648,7 +695,7 @@ add_sym_3ml (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt
 static void
 add_sym_3red (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
              int kind, int standard,
 static void
 add_sym_3red (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
              int kind, int standard,
-             gfc_try (*check) (gfc_actual_arglist *),
+             bool (*check) (gfc_actual_arglist *),
              gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
              void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
              const char *a1, bt type1, int kind1, int optional1,
              gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
              void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
              const char *a1, bt type1, int kind1, int optional1,
@@ -672,46 +719,18 @@ add_sym_3red (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt
 
 
 /* Add a symbol to the subroutine list where the subroutine takes
 
 
 /* Add a symbol to the subroutine list where the subroutine takes
-   3 arguments.  */
+   3 arguments, specifying the intent of the arguments.  */
 
 static void
 
 static void
-add_sym_3s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind, int standard,
-           gfc_try (*check) (gfc_expr *, gfc_expr *, gfc_expr *),
+add_sym_3s (const char *name, gfc_isym_id id, enum klass cl, bt type,
+           int kind, int standard,
+           bool (*check) (gfc_expr *, gfc_expr *, gfc_expr *),
            gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
            void (*resolve) (gfc_code *),
            const char *a1, bt type1, int kind1, int optional1,
            gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
            void (*resolve) (gfc_code *),
            const char *a1, bt type1, int kind1, int optional1,
-           const char *a2, bt type2, int kind2, int optional2,
-           const char *a3, bt type3, int kind3, int optional3)
-{
-  gfc_check_f cf;
-  gfc_simplify_f sf;
-  gfc_resolve_f rf;
-
-  cf.f3 = check;
-  sf.f3 = simplify;
-  rf.s1 = resolve;
-
-  add_sym (name, id, cl, ACTUAL_NO, type, kind, standard, cf, sf, rf,
-          a1, type1, kind1, optional1, INTENT_IN,
-          a2, type2, kind2, optional2, INTENT_IN,
-          a3, type3, kind3, optional3, INTENT_IN,
-          (void *) 0);
-}
-
-
-/* Add a symbol to the subroutine list where the subroutine takes
-   3 arguments, specifying the intent of the arguments.  */
-
-static void
-add_sym_3s_intent (const char *name, gfc_isym_id id, enum klass cl, bt type,
-                  int kind, int standard,
-                  gfc_try (*check) (gfc_expr *, gfc_expr *, gfc_expr *),
-                  gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *),
-                  void (*resolve) (gfc_code *),
-                  const char *a1, bt type1, int kind1, int optional1,
-                  sym_intent intent1, const char *a2, bt type2, int kind2,
-                  int optional2, sym_intent intent2, const char *a3, bt type3,
-                  int kind3, int optional3, sym_intent intent3)
+           sym_intent intent1, const char *a2, bt type2, int kind2,
+           int optional2, sym_intent intent2, const char *a3, bt type3,
+           int kind3, int optional3, sym_intent intent3)
 {
   gfc_check_f cf;
   gfc_simplify_f sf;
 {
   gfc_check_f cf;
   gfc_simplify_f sf;
@@ -735,7 +754,7 @@ add_sym_3s_intent (const char *name, gfc_isym_id id, enum klass cl, bt type,
 static void
 add_sym_4 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
           int kind, int standard,
 static void
 add_sym_4 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type,
           int kind, int standard,
-          gfc_try (*check) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
+          bool (*check) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
           gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *,
                                  gfc_expr *),
           void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
           gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *,
                                  gfc_expr *),
           void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
@@ -768,7 +787,7 @@ add_sym_4 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt ty
 static void
 add_sym_4s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
            int standard,
 static void
 add_sym_4s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
            int standard,
-           gfc_try (*check) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
+           bool (*check) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *),
            gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *,
                                   gfc_expr *),
            void (*resolve) (gfc_code *),
            gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *,
                                   gfc_expr *),
            void (*resolve) (gfc_code *),
@@ -801,7 +820,7 @@ add_sym_4s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
 static void
 add_sym_5s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
            int standard,
 static void
 add_sym_5s (const char *name, gfc_isym_id id, enum klass cl, bt type, int kind,
            int standard,
-           gfc_try (*check) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
+           bool (*check) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *,
                          gfc_expr *),
            gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *,
                                   gfc_expr *, gfc_expr *),
                          gfc_expr *),
            gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *,
                                   gfc_expr *, gfc_expr *),
@@ -857,6 +876,75 @@ find_sym (gfc_intrinsic_sym *start, int n, const char *name)
 }
 
 
 }
 
 
+gfc_isym_id
+gfc_isym_id_by_intmod (intmod_id from_intmod, int intmod_sym_id)
+{
+  if (from_intmod == INTMOD_NONE)
+    return (gfc_isym_id) intmod_sym_id;
+  else if (from_intmod == INTMOD_ISO_C_BINDING)
+    return (gfc_isym_id) c_interop_kinds_table[intmod_sym_id].value;
+  else if (from_intmod == INTMOD_ISO_FORTRAN_ENV)
+    switch (intmod_sym_id)
+      {
+#define NAMED_SUBROUTINE(a,b,c,d) \
+      case a: \
+       return (gfc_isym_id) c;
+#define NAMED_FUNCTION(a,b,c,d) \
+      case a: \
+       return (gfc_isym_id) c;
+#include "iso-fortran-env.def"
+      default:
+       gcc_unreachable ();
+      }
+  else
+    gcc_unreachable ();
+  return (gfc_isym_id) 0;
+}
+
+
+gfc_isym_id
+gfc_isym_id_by_intmod_sym (gfc_symbol *sym)
+{
+  return gfc_isym_id_by_intmod (sym->from_intmod, sym->intmod_sym_id);
+}
+
+
+gfc_intrinsic_sym *
+gfc_intrinsic_subroutine_by_id (gfc_isym_id id)
+{
+  gfc_intrinsic_sym *start = subroutines;
+  int n = nsub;
+
+  while (true)
+    {
+      gcc_assert (n > 0);
+      if (id == start->id)
+       return start;
+
+      start++;
+      n--;
+    }
+}
+
+
+gfc_intrinsic_sym *
+gfc_intrinsic_function_by_id (gfc_isym_id id)
+{
+  gfc_intrinsic_sym *start = functions;
+  int n = nfunc;
+
+  while (true)
+    {
+      gcc_assert (n > 0);
+      if (id == start->id)
+       return start;
+
+      start++;
+      n--;
+    }
+}
+
+
 /* Given a name, find a function in the intrinsic function table.
    Returns NULL if not found.  */
 
 /* Given a name, find a function in the intrinsic function table.
    Returns NULL if not found.  */
 
@@ -866,10 +954,10 @@ gfc_find_function (const char *name)
   gfc_intrinsic_sym *sym;
 
   sym = find_sym (functions, nfunc, name);
   gfc_intrinsic_sym *sym;
 
   sym = find_sym (functions, nfunc, name);
-  if (!sym)
+  if (!sym || sym->from_module)
     sym = find_sym (conversion, nconv, name);
 
     sym = find_sym (conversion, nconv, name);
 
-  return sym;
+  return (!sym || sym->from_module) ? NULL : sym;
 }
 
 
 }
 
 
@@ -879,7 +967,9 @@ gfc_find_function (const char *name)
 gfc_intrinsic_sym *
 gfc_find_subroutine (const char *name)
 {
 gfc_intrinsic_sym *
 gfc_find_subroutine (const char *name)
 {
-  return find_sym (subroutines, nsub, name);
+  gfc_intrinsic_sym *sym;
+  sym = find_sym (subroutines, nsub, name);
+  return (!sym || sym->from_module) ? NULL : sym;
 }
 
 
 }
 
 
@@ -892,7 +982,7 @@ gfc_generic_intrinsic (const char *name)
   gfc_intrinsic_sym *sym;
 
   sym = gfc_find_function (name);
   gfc_intrinsic_sym *sym;
 
   sym = gfc_find_function (name);
-  return (sym == NULL) ? 0 : sym->generic;
+  return (!sym || sym->from_module) ? 0 : sym->generic;
 }
 
 
 }
 
 
@@ -905,7 +995,7 @@ gfc_specific_intrinsic (const char *name)
   gfc_intrinsic_sym *sym;
 
   sym = gfc_find_function (name);
   gfc_intrinsic_sym *sym;
 
   sym = gfc_find_function (name);
-  return (sym == NULL) ? 0 : sym->specific;
+  return (!sym || sym->from_module) ? 0 : sym->specific;
 }
 
 
 }
 
 
@@ -927,9 +1017,9 @@ gfc_intrinsic_actual_ok (const char *name, const bool subroutine_flag)
 }
 
 
 }
 
 
-/* Given a symbol, find out if it is (and is to be treated) an intrinsic.  If
-   it's name refers to an intrinsic but this intrinsic is not included in the
-   selected standard, this returns FALSE and sets the symbol's external
+/* Given a symbol, find out if it is (and is to be treated as) an intrinsic.
+   If its name refers to an intrinsic, but this intrinsic is not included in
+   the selected standard, this returns FALSE and sets the symbol's external
    attribute.  */
 
 bool
    attribute.  */
 
 bool
@@ -938,10 +1028,13 @@ gfc_is_intrinsic (gfc_symbol* sym, int subroutine_flag, locus loc)
   gfc_intrinsic_sym* isym;
   const char* symstd;
 
   gfc_intrinsic_sym* isym;
   const char* symstd;
 
-  /* If INTRINSIC/EXTERNAL state is already known, return.  */
+  /* If INTRINSIC attribute is already known, return.  */
   if (sym->attr.intrinsic)
     return true;
   if (sym->attr.intrinsic)
     return true;
-  if (sym->attr.external)
+
+  /* Check for attributes which prevent the symbol from being INTRINSIC.  */
+  if (sym->attr.external || sym->attr.contained
+      || sym->attr.if_source == IFSRC_IFBODY)
     return false;
 
   if (subroutine_flag)
     return false;
 
   if (subroutine_flag)
@@ -954,19 +1047,16 @@ gfc_is_intrinsic (gfc_symbol* sym, int subroutine_flag, locus loc)
     return false;
 
   /* See if this intrinsic is allowed in the current standard.  */
     return false;
 
   /* See if this intrinsic is allowed in the current standard.  */
-  if (gfc_check_intrinsic_standard (isym, &symstd, false, loc) == FAILURE)
+  if (!gfc_check_intrinsic_standard (isym, &symstd, false, loc)
+      && !sym->attr.artificial)
     {
     {
-      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);
-       }
+      if (sym->attr.proc == PROC_UNKNOWN && warn_intrinsics_std)
+       gfc_warning_now (OPT_Wintrinsics_std, "The intrinsic %qs at %L is not "
+                        "included in the selected standard but %s and %qs 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);
 
       return false;
     }
 
       return false;
     }
@@ -996,7 +1086,7 @@ make_generic (const char *name, gfc_isym_id id, int standard ATTRIBUTE_UNUSED)
 
   g = gfc_find_function (name);
   if (g == NULL)
 
   g = gfc_find_function (name);
   if (g == NULL)
-    gfc_internal_error ("make_generic(): Can't find generic symbol '%s'",
+    gfc_internal_error ("make_generic(): Can't find generic symbol %qs",
                        name);
 
   gcc_assert (g->id == id);
                        name);
 
   gcc_assert (g->id == id);
@@ -1061,6 +1151,39 @@ make_noreturn (void)
 }
 
 
 }
 
 
+/* Mark current intrinsic as module intrinsic.  */
+static void
+make_from_module (void)
+{
+  if (sizing == SZ_NOTHING)
+    next_sym[-1].from_module = 1;
+}
+
+/* Set the attr.value of the current procedure.  */
+
+static void
+set_attr_value (int n, ...)
+{
+  gfc_intrinsic_arg *arg;
+  va_list argp;
+  int i;
+
+  if (sizing != SZ_NOTHING)
+    return;
+
+  va_start (argp, n);
+  arg = next_sym[-1].formal;
+
+  for (i = 0; i < n; i++)
+    {
+      gcc_assert (arg != NULL);
+      arg->value = va_arg (argp, int);
+      arg = arg->next;
+    }
+  va_end (argp);
+}
+
+
 /* Add intrinsic functions.  */
 
 static void
 /* Add intrinsic functions.  */
 
 static void
@@ -1082,7 +1205,7 @@ add_functions (void)
     *z = "z", *ln = "len", *ut = "unit", *han = "handler",
     *num = "number", *tm = "time", *nm = "name", *md = "mode",
     *vl = "values", *p1 = "path1", *p2 = "path2", *com = "command",
     *z = "z", *ln = "len", *ut = "unit", *han = "handler",
     *num = "number", *tm = "time", *nm = "name", *md = "mode",
     *vl = "values", *p1 = "path1", *p2 = "path2", *com = "command",
-    *ca = "coarray", *sub = "sub";
+    *ca = "coarray", *sub = "sub", *dist = "distance", *failed="failed";
 
   int di, dr, dd, dl, dc, dz, ii;
 
 
   int di, dr, dd, dl, dc, dz, ii;
 
@@ -1120,8 +1243,8 @@ add_functions (void)
 
   /* The checking function for ACCESS is called gfc_check_access_func
      because the name gfc_check_access is already used in module.c.  */
 
   /* The checking function for ACCESS is called gfc_check_access_func
      because the name gfc_check_access is already used in module.c.  */
-  add_sym_2 ("access", GFC_ISYM_ACCESS, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_access_func, NULL, gfc_resolve_access,
+  add_sym_2 ("access", GFC_ISYM_ACCESS, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, gfc_check_access_func, NULL, gfc_resolve_access,
             nm, BT_CHARACTER, dc, REQUIRED, md, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("access", GFC_ISYM_ACCESS, GFC_STD_GNU);
             nm, BT_CHARACTER, dc, REQUIRED, md, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("access", GFC_ISYM_ACCESS, GFC_STD_GNU);
@@ -1312,6 +1435,12 @@ add_functions (void)
             gfc_check_besn, gfc_simplify_bessel_jn, gfc_resolve_besn,
             n, BT_INTEGER, di, REQUIRED, x, BT_REAL, dd, REQUIRED);
 
             gfc_check_besn, gfc_simplify_bessel_jn, gfc_resolve_besn,
             n, BT_INTEGER, di, REQUIRED, x, BT_REAL, dd, REQUIRED);
 
+  add_sym_3 ("bessel_jn", GFC_ISYM_JN2, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F2008,
+            gfc_check_bessel_n2, gfc_simplify_bessel_jn2, gfc_resolve_bessel_n2,
+            "n1", BT_INTEGER, di, REQUIRED,"n2", BT_INTEGER, di, REQUIRED,
+            x, BT_REAL, dr, REQUIRED);
+  set_attr_value (3, true, true, true);
+
   make_generic ("bessel_jn", GFC_ISYM_JN, GFC_STD_F2008);
 
   add_sym_1 ("besy0", GFC_ISYM_Y0, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_GNU,
   make_generic ("bessel_jn", GFC_ISYM_JN, GFC_STD_F2008);
 
   add_sym_1 ("besy0", GFC_ISYM_Y0, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_GNU,
@@ -1348,16 +1477,50 @@ add_functions (void)
             gfc_check_besn, gfc_simplify_bessel_yn, gfc_resolve_besn,
             n, BT_INTEGER, di, REQUIRED, x, BT_REAL, dd, REQUIRED);
 
             gfc_check_besn, gfc_simplify_bessel_yn, gfc_resolve_besn,
             n, BT_INTEGER, di, REQUIRED, x, BT_REAL, dd, REQUIRED);
 
+  add_sym_3 ("bessel_yn", GFC_ISYM_YN2, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F2008,
+            gfc_check_bessel_n2, gfc_simplify_bessel_yn2, gfc_resolve_bessel_n2,
+            "n1", BT_INTEGER, di, REQUIRED,"n2", BT_INTEGER, di, REQUIRED,
+             x, BT_REAL, dr, REQUIRED);
+  set_attr_value (3, true, true, true);
+
   make_generic ("bessel_yn", GFC_ISYM_YN, GFC_STD_F2008);
 
   make_generic ("bessel_yn", GFC_ISYM_YN, GFC_STD_F2008);
 
+  add_sym_2 ("bge", GFC_ISYM_BGE, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_LOGICAL, dl, GFC_STD_F2008,
+            gfc_check_bge_bgt_ble_blt, gfc_simplify_bge, NULL,
+            i, BT_INTEGER, di, REQUIRED, j, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("bge", GFC_ISYM_BGE, GFC_STD_F2008);
+
+  add_sym_2 ("bgt", GFC_ISYM_BGT, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_LOGICAL, dl, GFC_STD_F2008,
+            gfc_check_bge_bgt_ble_blt, gfc_simplify_bgt, NULL,
+            i, BT_INTEGER, di, REQUIRED, j, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("bgt", GFC_ISYM_BGT, GFC_STD_F2008);
+
   add_sym_1 ("bit_size", GFC_ISYM_BIT_SIZE, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
             gfc_check_i, gfc_simplify_bit_size, NULL,
             i, BT_INTEGER, di, REQUIRED);
 
   make_generic ("bit_size", GFC_ISYM_BIT_SIZE, GFC_STD_F95);
 
   add_sym_1 ("bit_size", GFC_ISYM_BIT_SIZE, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
             gfc_check_i, gfc_simplify_bit_size, NULL,
             i, BT_INTEGER, di, REQUIRED);
 
   make_generic ("bit_size", GFC_ISYM_BIT_SIZE, GFC_STD_F95);
 
+  add_sym_2 ("ble", GFC_ISYM_BLE, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_LOGICAL, dl, GFC_STD_F2008,
+            gfc_check_bge_bgt_ble_blt, gfc_simplify_ble, NULL,
+            i, BT_INTEGER, di, REQUIRED, j, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("ble", GFC_ISYM_BLE, GFC_STD_F2008);
+
+  add_sym_2 ("blt", GFC_ISYM_BLT, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_LOGICAL, dl, GFC_STD_F2008,
+            gfc_check_bge_bgt_ble_blt, gfc_simplify_blt, NULL,
+            i, BT_INTEGER, di, REQUIRED, j, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("blt", GFC_ISYM_BLT, GFC_STD_F2008);
+
   add_sym_2 ("btest", GFC_ISYM_BTEST, CLASS_ELEMENTAL, ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_F95,
   add_sym_2 ("btest", GFC_ISYM_BTEST, CLASS_ELEMENTAL, ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_F95,
-            gfc_check_btest, gfc_simplify_btest, gfc_resolve_btest,
+            gfc_check_bitfcn, gfc_simplify_btest, gfc_resolve_btest,
             i, BT_INTEGER, di, REQUIRED, pos, BT_INTEGER, di, REQUIRED);
 
   make_generic ("btest", GFC_ISYM_BTEST, GFC_STD_F95);
             i, BT_INTEGER, di, REQUIRED, pos, BT_INTEGER, di, REQUIRED);
 
   make_generic ("btest", GFC_ISYM_BTEST, GFC_STD_F95);
@@ -1374,14 +1537,14 @@ add_functions (void)
 
   make_generic ("char", GFC_ISYM_CHAR, GFC_STD_F77);
 
 
   make_generic ("char", GFC_ISYM_CHAR, GFC_STD_F77);
 
-  add_sym_1 ("chdir", GFC_ISYM_CHDIR, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+  add_sym_1 ("chdir", GFC_ISYM_CHDIR, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER, di,
             GFC_STD_GNU, gfc_check_chdir, NULL, gfc_resolve_chdir,
             nm, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("chdir", GFC_ISYM_CHDIR, GFC_STD_GNU);
 
             GFC_STD_GNU, gfc_check_chdir, NULL, gfc_resolve_chdir,
             nm, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("chdir", GFC_ISYM_CHDIR, GFC_STD_GNU);
 
-  add_sym_2 ("chmod", GFC_ISYM_CHMOD, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_chmod, NULL, gfc_resolve_chmod,
+  add_sym_2 ("chmod", GFC_ISYM_CHMOD, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, gfc_check_chmod, NULL, gfc_resolve_chmod,
             nm, BT_CHARACTER, dc, REQUIRED, md, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("chmod", GFC_ISYM_CHMOD, GFC_STD_GNU);
             nm, BT_CHARACTER, dc, REQUIRED, md, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("chmod", GFC_ISYM_CHMOD, GFC_STD_GNU);
@@ -1469,9 +1632,9 @@ add_functions (void)
 
   make_generic ("cshift", GFC_ISYM_CSHIFT, GFC_STD_F95);
 
 
   make_generic ("cshift", GFC_ISYM_CSHIFT, GFC_STD_F95);
 
-  add_sym_1 ("ctime", GFC_ISYM_CTIME, NO_CLASS, ACTUAL_NO, BT_CHARACTER, 0, GFC_STD_GNU,
-             gfc_check_ctime, NULL, gfc_resolve_ctime,
-             tm, BT_INTEGER, di, REQUIRED);
+  add_sym_1 ("ctime", GFC_ISYM_CTIME, CLASS_IMPURE, ACTUAL_NO, BT_CHARACTER,
+            0, GFC_STD_GNU, gfc_check_ctime, NULL, gfc_resolve_ctime,
+            tm, BT_INTEGER, di, REQUIRED);
 
   make_generic ("ctime", GFC_ISYM_CTIME, GFC_STD_GNU);
 
 
   make_generic ("ctime", GFC_ISYM_CTIME, GFC_STD_GNU);
 
@@ -1479,8 +1642,6 @@ add_functions (void)
             gfc_check_dble, gfc_simplify_dble, gfc_resolve_dble,
             a, BT_REAL, dr, REQUIRED);
 
             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,
   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,
@@ -1515,16 +1676,34 @@ add_functions (void)
 
   make_generic ("dprod", GFC_ISYM_DPROD, GFC_STD_F77);
 
 
   make_generic ("dprod", GFC_ISYM_DPROD, GFC_STD_F77);
 
-  add_sym_1 ("dreal", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dd, GFC_STD_GNU,
-            NULL, NULL, NULL,
+  add_sym_1 ("dreal", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_REAL, dd, GFC_STD_GNU, NULL, gfc_simplify_dreal, NULL,
             a, BT_COMPLEX, dd, REQUIRED);
 
   make_generic ("dreal", GFC_ISYM_REAL, GFC_STD_GNU);
 
             a, BT_COMPLEX, dd, REQUIRED);
 
   make_generic ("dreal", GFC_ISYM_REAL, GFC_STD_GNU);
 
+  add_sym_3 ("dshiftl", GFC_ISYM_DSHIFTL, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_dshift, gfc_simplify_dshiftl, gfc_resolve_dshift,
+            i, BT_INTEGER, di, REQUIRED,
+            j, BT_INTEGER, di, REQUIRED,
+            sh, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("dshiftl", GFC_ISYM_DSHIFTL, GFC_STD_F2008);
+
+  add_sym_3 ("dshiftr", GFC_ISYM_DSHIFTR, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_dshift, gfc_simplify_dshiftr, gfc_resolve_dshift,
+            i, BT_INTEGER, di, REQUIRED,
+            j, BT_INTEGER, di, REQUIRED,
+            sh, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("dshiftr", GFC_ISYM_DSHIFTR, GFC_STD_F2008);
+
   add_sym_4 ("eoshift", GFC_ISYM_EOSHIFT, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
             gfc_check_eoshift, NULL, gfc_resolve_eoshift,
   add_sym_4 ("eoshift", GFC_ISYM_EOSHIFT, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
             gfc_check_eoshift, NULL, gfc_resolve_eoshift,
-            ar, BT_REAL, dr, 0, sh, BT_INTEGER, ii, REQUIRED,
-            bd, BT_REAL, dr, 1, dm, BT_INTEGER, ii, OPTIONAL);
+            ar, BT_REAL, dr, REQUIRED, sh, BT_INTEGER, ii, REQUIRED,
+            bd, BT_REAL, dr, OPTIONAL, dm, BT_INTEGER, ii, OPTIONAL);
 
   make_generic ("eoshift", GFC_ISYM_EOSHIFT, GFC_STD_F95);
 
 
   make_generic ("eoshift", GFC_ISYM_EOSHIFT, GFC_STD_F95);
 
@@ -1563,14 +1742,14 @@ add_functions (void)
   make_generic ("erfc_scaled", GFC_ISYM_ERFC_SCALED, GFC_STD_F2008);
 
   /* G77 compatibility */
   make_generic ("erfc_scaled", GFC_ISYM_ERFC_SCALED, GFC_STD_F2008);
 
   /* G77 compatibility */
-  add_sym_1 ("dtime", GFC_ISYM_DTIME, NO_CLASS, ACTUAL_NO, BT_REAL, 4,  GFC_STD_GNU,
-            gfc_check_dtime_etime, NULL, NULL,
+  add_sym_1 ("dtime", GFC_ISYM_DTIME, CLASS_IMPURE, ACTUAL_NO, BT_REAL,
+            4, GFC_STD_GNU, gfc_check_dtime_etime, NULL, NULL,
             x, BT_REAL, 4, REQUIRED);
 
   make_generic ("dtime", GFC_ISYM_DTIME, GFC_STD_GNU);
 
             x, BT_REAL, 4, REQUIRED);
 
   make_generic ("dtime", GFC_ISYM_DTIME, GFC_STD_GNU);
 
-  add_sym_1 ("etime", GFC_ISYM_ETIME, NO_CLASS, ACTUAL_NO, BT_REAL, 4,  GFC_STD_GNU,
-            gfc_check_dtime_etime, NULL, NULL,
+  add_sym_1 ("etime", GFC_ISYM_ETIME, CLASS_IMPURE, ACTUAL_NO, BT_REAL,
+            4, GFC_STD_GNU, gfc_check_dtime_etime, NULL, NULL,
             x, BT_REAL, 4, REQUIRED);
 
   make_generic ("etime", GFC_ISYM_ETIME, GFC_STD_GNU);
             x, BT_REAL, 4, REQUIRED);
 
   make_generic ("etime", GFC_ISYM_ETIME, GFC_STD_GNU);
@@ -1603,12 +1782,13 @@ add_functions (void)
 
   add_sym_2 ("extends_type_of", GFC_ISYM_EXTENDS_TYPE_OF, CLASS_INQUIRY,
             ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_F2003,
 
   add_sym_2 ("extends_type_of", GFC_ISYM_EXTENDS_TYPE_OF, CLASS_INQUIRY,
             ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_F2003,
-            gfc_check_same_type_as, NULL, gfc_resolve_extends_type_of,
+            gfc_check_same_type_as, gfc_simplify_extends_type_of,
+            gfc_resolve_extends_type_of,
             a, BT_UNKNOWN, 0, REQUIRED,
             mo, BT_UNKNOWN, 0, REQUIRED);
 
             a, BT_UNKNOWN, 0, REQUIRED,
             mo, BT_UNKNOWN, 0, REQUIRED);
 
-  add_sym_0 ("fdate",  GFC_ISYM_FDATE, NO_CLASS, ACTUAL_NO, BT_CHARACTER, dc, GFC_STD_GNU,
-            NULL, NULL, gfc_resolve_fdate);
+  add_sym_0 ("fdate",  GFC_ISYM_FDATE, CLASS_IMPURE, ACTUAL_NO, BT_CHARACTER,
+            dc, GFC_STD_GNU, NULL, NULL, gfc_resolve_fdate);
 
   make_generic ("fdate", GFC_ISYM_FDATE, GFC_STD_GNU);
 
 
   make_generic ("fdate", GFC_ISYM_FDATE, GFC_STD_GNU);
 
@@ -1619,8 +1799,8 @@ add_functions (void)
   make_generic ("floor", GFC_ISYM_FLOOR, GFC_STD_F95);
 
   /* G77 compatible fnum */
   make_generic ("floor", GFC_ISYM_FLOOR, GFC_STD_F95);
 
   /* G77 compatible fnum */
-  add_sym_1 ("fnum", GFC_ISYM_FNUM, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_fnum, NULL, gfc_resolve_fnum,
+  add_sym_1 ("fnum", GFC_ISYM_FNUM, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, gfc_check_fnum, NULL, gfc_resolve_fnum,
             ut, BT_INTEGER, di, REQUIRED);
 
   make_generic ("fnum", GFC_ISYM_FNUM, GFC_STD_GNU);
             ut, BT_INTEGER, di, REQUIRED);
 
   make_generic ("fnum", GFC_ISYM_FNUM, GFC_STD_GNU);
@@ -1631,38 +1811,42 @@ add_functions (void)
 
   make_generic ("fraction", GFC_ISYM_FRACTION, GFC_STD_F95);
 
 
   make_generic ("fraction", GFC_ISYM_FRACTION, GFC_STD_F95);
 
-  add_sym_2 ("fstat", GFC_ISYM_FSTAT, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
-            GFC_STD_GNU, gfc_check_fstat, NULL, gfc_resolve_fstat,
-            ut, BT_INTEGER, di, REQUIRED, vl, BT_INTEGER, di, REQUIRED);
+  add_sym_2_intent ("fstat", GFC_ISYM_FSTAT, CLASS_IMPURE, ACTUAL_NO,
+                   BT_INTEGER, di, GFC_STD_GNU,
+                   gfc_check_fstat, NULL, gfc_resolve_fstat,
+                   ut, BT_INTEGER, di, REQUIRED, INTENT_IN,
+                   vl, BT_INTEGER, di, REQUIRED, INTENT_OUT);
 
   make_generic ("fstat", GFC_ISYM_FSTAT, GFC_STD_GNU);
 
 
   make_generic ("fstat", GFC_ISYM_FSTAT, GFC_STD_GNU);
 
-  add_sym_1 ("ftell", GFC_ISYM_FTELL, NO_CLASS, ACTUAL_NO, BT_INTEGER, ii, GFC_STD_GNU,
-            gfc_check_ftell, NULL, gfc_resolve_ftell,
+  add_sym_1 ("ftell", GFC_ISYM_FTELL, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            ii, GFC_STD_GNU, gfc_check_ftell, NULL, gfc_resolve_ftell,
             ut, BT_INTEGER, di, REQUIRED);
 
   make_generic ("ftell", GFC_ISYM_FTELL, GFC_STD_GNU);
 
             ut, BT_INTEGER, di, REQUIRED);
 
   make_generic ("ftell", GFC_ISYM_FTELL, GFC_STD_GNU);
 
-  add_sym_2 ("fgetc", GFC_ISYM_FGETC, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_fgetputc, NULL, gfc_resolve_fgetc,
-            ut, BT_INTEGER, di, REQUIRED, c, BT_CHARACTER, dc, REQUIRED);
+  add_sym_2_intent ("fgetc", GFC_ISYM_FGETC, CLASS_IMPURE, ACTUAL_NO,
+                   BT_INTEGER, di, GFC_STD_GNU,
+                   gfc_check_fgetputc, NULL, gfc_resolve_fgetc,
+                   ut, BT_INTEGER, di, REQUIRED, INTENT_IN,
+                   c, BT_CHARACTER, dc, REQUIRED, INTENT_OUT);
 
   make_generic ("fgetc", GFC_ISYM_FGETC, GFC_STD_GNU);
 
 
   make_generic ("fgetc", GFC_ISYM_FGETC, GFC_STD_GNU);
 
-  add_sym_1 ("fget", GFC_ISYM_FGET, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_fgetput, NULL, gfc_resolve_fget,
-            c, BT_CHARACTER, dc, REQUIRED);
+  add_sym_1_intent ("fget", GFC_ISYM_FGET, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, gfc_check_fgetput, NULL, gfc_resolve_fget,
+            c, BT_CHARACTER, dc, REQUIRED, INTENT_OUT);
 
   make_generic ("fget", GFC_ISYM_FGET, GFC_STD_GNU);
 
 
   make_generic ("fget", GFC_ISYM_FGET, GFC_STD_GNU);
 
-  add_sym_2 ("fputc", GFC_ISYM_FPUTC, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_fgetputc, NULL, gfc_resolve_fputc,
+  add_sym_2 ("fputc", GFC_ISYM_FPUTC, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, gfc_check_fgetputc, NULL, gfc_resolve_fputc,
             ut, BT_INTEGER, di, REQUIRED, c, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("fputc", GFC_ISYM_FPUTC, GFC_STD_GNU);
 
             ut, BT_INTEGER, di, REQUIRED, c, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("fputc", GFC_ISYM_FPUTC, GFC_STD_GNU);
 
-  add_sym_1 ("fput", GFC_ISYM_FPUT, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_fgetput, NULL, gfc_resolve_fput,
+  add_sym_1 ("fput", GFC_ISYM_FPUT, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, gfc_check_fgetput, NULL, gfc_resolve_fput,
             c, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("fput", GFC_ISYM_FPUT, GFC_STD_GNU);
             c, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("fput", GFC_ISYM_FPUT, GFC_STD_GNU);
@@ -1678,30 +1862,31 @@ add_functions (void)
   make_generic ("gamma", GFC_ISYM_TGAMMA, GFC_STD_F2008);
 
   /* Unix IDs (g77 compatibility)  */
   make_generic ("gamma", GFC_ISYM_TGAMMA, GFC_STD_F2008);
 
   /* Unix IDs (g77 compatibility)  */
-  add_sym_1 ("getcwd", GFC_ISYM_GETCWD, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,  GFC_STD_GNU,
-            NULL, NULL, gfc_resolve_getcwd,
+  add_sym_1 ("getcwd", GFC_ISYM_GETCWD, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di,  GFC_STD_GNU, NULL, NULL, gfc_resolve_getcwd,
             c, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("getcwd", GFC_ISYM_GETCWD, GFC_STD_GNU);
 
             c, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("getcwd", GFC_ISYM_GETCWD, GFC_STD_GNU);
 
-  add_sym_0 ("getgid", GFC_ISYM_GETGID, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            NULL, NULL, gfc_resolve_getgid);
+  add_sym_0 ("getgid", GFC_ISYM_GETGID, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, NULL, NULL, gfc_resolve_getgid);
 
   make_generic ("getgid", GFC_ISYM_GETGID, GFC_STD_GNU);
 
 
   make_generic ("getgid", GFC_ISYM_GETGID, GFC_STD_GNU);
 
-  add_sym_0 ("getpid", GFC_ISYM_GETPID, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU, 
-            NULL, NULL, gfc_resolve_getpid);
+  add_sym_0 ("getpid", GFC_ISYM_GETPID, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, NULL, NULL, gfc_resolve_getpid);
 
   make_generic ("getpid", GFC_ISYM_GETPID, GFC_STD_GNU);
 
 
   make_generic ("getpid", GFC_ISYM_GETPID, GFC_STD_GNU);
 
-  add_sym_0 ("getuid", GFC_ISYM_GETUID, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU, 
-            NULL, NULL, gfc_resolve_getuid);
+  add_sym_0 ("getuid", GFC_ISYM_GETUID, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, NULL, NULL, gfc_resolve_getuid);
 
   make_generic ("getuid", GFC_ISYM_GETUID, GFC_STD_GNU);
 
 
   make_generic ("getuid", GFC_ISYM_GETUID, GFC_STD_GNU);
 
-  add_sym_1 ("hostnm", GFC_ISYM_HOSTNM, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_hostnm, NULL, gfc_resolve_hostnm,
-            a, BT_CHARACTER, dc, REQUIRED);
+  add_sym_1_intent ("hostnm", GFC_ISYM_HOSTNM, CLASS_IMPURE, ACTUAL_NO,
+                   BT_INTEGER, di, GFC_STD_GNU,
+                   gfc_check_hostnm, NULL, gfc_resolve_hostnm,
+                   c, BT_CHARACTER, dc, REQUIRED, INTENT_OUT);
 
   make_generic ("hostnm", GFC_ISYM_HOSTNM, GFC_STD_GNU);
 
 
   make_generic ("hostnm", GFC_ISYM_HOSTNM, GFC_STD_GNU);
 
@@ -1731,19 +1916,33 @@ add_functions (void)
 
   make_generic ("iand", GFC_ISYM_IAND, GFC_STD_F95);
 
 
   make_generic ("iand", GFC_ISYM_IAND, GFC_STD_F95);
 
-  add_sym_2 ("and", GFC_ISYM_AND, NO_CLASS, ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_GNU,
-            gfc_check_and, gfc_simplify_and, gfc_resolve_and,
+  add_sym_2 ("and", GFC_ISYM_AND, CLASS_IMPURE, ACTUAL_NO, BT_LOGICAL,
+            dl, GFC_STD_GNU, gfc_check_and, gfc_simplify_and, gfc_resolve_and,
             i, BT_UNKNOWN, 0, REQUIRED, j, BT_UNKNOWN, 0, REQUIRED);
 
   make_generic ("and", GFC_ISYM_AND, GFC_STD_GNU);
 
             i, BT_UNKNOWN, 0, REQUIRED, j, BT_UNKNOWN, 0, REQUIRED);
 
   make_generic ("and", GFC_ISYM_AND, GFC_STD_GNU);
 
-  add_sym_0 ("iargc", GFC_ISYM_IARGC, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            NULL, NULL, NULL);
+  add_sym_3red ("iall", GFC_ISYM_IALL, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F2008,
+               gfc_check_transf_bit_intrins, gfc_simplify_iall, gfc_resolve_iall,
+               ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
+               msk, BT_LOGICAL, dl, OPTIONAL);
+
+  make_generic ("iall", GFC_ISYM_IALL, GFC_STD_F2008);
+
+  add_sym_3red ("iany", GFC_ISYM_IANY, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F2008,
+               gfc_check_transf_bit_intrins, gfc_simplify_iany, gfc_resolve_iany,
+               ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
+               msk, BT_LOGICAL, dl, OPTIONAL);
+
+  make_generic ("iany", GFC_ISYM_IANY, GFC_STD_F2008);
+
+  add_sym_0 ("iargc", GFC_ISYM_IARGC, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, NULL, NULL, NULL);
 
   make_generic ("iargc", GFC_ISYM_IARGC, GFC_STD_GNU);
 
   add_sym_2 ("ibclr", GFC_ISYM_IBCLR, CLASS_ELEMENTAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
 
   make_generic ("iargc", GFC_ISYM_IARGC, GFC_STD_GNU);
 
   add_sym_2 ("ibclr", GFC_ISYM_IBCLR, CLASS_ELEMENTAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
-            gfc_check_ibclr, gfc_simplify_ibclr, gfc_resolve_ibclr,
+            gfc_check_bitfcn, gfc_simplify_ibclr, gfc_resolve_ibclr,
             i, BT_INTEGER, di, REQUIRED, pos, BT_INTEGER, di, REQUIRED);
 
   make_generic ("ibclr", GFC_ISYM_IBCLR, GFC_STD_F95);
             i, BT_INTEGER, di, REQUIRED, pos, BT_INTEGER, di, REQUIRED);
 
   make_generic ("ibclr", GFC_ISYM_IBCLR, GFC_STD_F95);
@@ -1756,7 +1955,7 @@ add_functions (void)
   make_generic ("ibits", GFC_ISYM_IBITS, GFC_STD_F95);
 
   add_sym_2 ("ibset", GFC_ISYM_IBSET, CLASS_ELEMENTAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
   make_generic ("ibits", GFC_ISYM_IBITS, GFC_STD_F95);
 
   add_sym_2 ("ibset", GFC_ISYM_IBSET, CLASS_ELEMENTAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
-            gfc_check_ibset, gfc_simplify_ibset, gfc_resolve_ibset,
+            gfc_check_bitfcn, gfc_simplify_ibset, gfc_resolve_ibset,
             i, BT_INTEGER, di, REQUIRED, pos, BT_INTEGER, di, REQUIRED);
 
   make_generic ("ibset", GFC_ISYM_IBSET, GFC_STD_F95);
             i, BT_INTEGER, di, REQUIRED, pos, BT_INTEGER, di, REQUIRED);
 
   make_generic ("ibset", GFC_ISYM_IBSET, GFC_STD_F95);
@@ -1774,19 +1973,19 @@ add_functions (void)
 
   make_generic ("ieor", GFC_ISYM_IEOR, GFC_STD_F95);
 
 
   make_generic ("ieor", GFC_ISYM_IEOR, GFC_STD_F95);
 
-  add_sym_2 ("xor", GFC_ISYM_XOR, NO_CLASS, ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_GNU,
-            gfc_check_and, gfc_simplify_xor, gfc_resolve_xor,
+  add_sym_2 ("xor", GFC_ISYM_XOR, CLASS_IMPURE, ACTUAL_NO, BT_LOGICAL,
+            dl, GFC_STD_GNU, gfc_check_and, gfc_simplify_xor, gfc_resolve_xor,
             i, BT_UNKNOWN, 0, REQUIRED, j, BT_UNKNOWN, 0, REQUIRED);
 
   make_generic ("xor", GFC_ISYM_XOR, GFC_STD_GNU);
 
             i, BT_UNKNOWN, 0, REQUIRED, j, BT_UNKNOWN, 0, REQUIRED);
 
   make_generic ("xor", GFC_ISYM_XOR, GFC_STD_GNU);
 
-  add_sym_0 ("ierrno", GFC_ISYM_IERRNO, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            NULL, NULL, gfc_resolve_ierrno);
+  add_sym_0 ("ierrno", GFC_ISYM_IERRNO, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, NULL, NULL, gfc_resolve_ierrno);
 
   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,
 
   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, NULL,
+            gfc_check_image_index, gfc_simplify_image_index, gfc_resolve_image_index,
             ca, BT_REAL, dr, REQUIRED, sub, BT_INTEGER, ii, REQUIRED);
 
   /* The resolution function for INDEX is called gfc_resolve_index_func
             ca, BT_REAL, dr, REQUIRED, sub, BT_INTEGER, ii, REQUIRED);
 
   /* The resolution function for INDEX is called gfc_resolve_index_func
@@ -1839,21 +2038,28 @@ add_functions (void)
 
   make_generic ("ior", GFC_ISYM_IOR, GFC_STD_F95);
 
 
   make_generic ("ior", GFC_ISYM_IOR, GFC_STD_F95);
 
-  add_sym_2 ("or", GFC_ISYM_OR, NO_CLASS, ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_GNU,
-            gfc_check_and, gfc_simplify_or, gfc_resolve_or,
+  add_sym_2 ("or", GFC_ISYM_OR, CLASS_IMPURE, ACTUAL_NO, BT_LOGICAL,
+            dl, GFC_STD_GNU, gfc_check_and, gfc_simplify_or, gfc_resolve_or,
             i, BT_UNKNOWN, 0, REQUIRED, j, BT_UNKNOWN, 0, REQUIRED);
 
   make_generic ("or", GFC_ISYM_OR, GFC_STD_GNU);
 
             i, BT_UNKNOWN, 0, REQUIRED, j, BT_UNKNOWN, 0, REQUIRED);
 
   make_generic ("or", GFC_ISYM_OR, GFC_STD_GNU);
 
+  add_sym_3red ("iparity", GFC_ISYM_IPARITY, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F2008,
+               gfc_check_transf_bit_intrins, gfc_simplify_iparity, gfc_resolve_iparity,
+               ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
+               msk, BT_LOGICAL, dl, OPTIONAL);
+
+  make_generic ("iparity", GFC_ISYM_IPARITY, GFC_STD_F2008);
+
   /* The following function is for G77 compatibility.  */
   /* The following function is for G77 compatibility.  */
-  add_sym_1 ("irand", GFC_ISYM_IRAND, NO_CLASS, ACTUAL_NO, BT_INTEGER, 4, GFC_STD_GNU,
-            gfc_check_irand, NULL, NULL,
+  add_sym_1 ("irand", GFC_ISYM_IRAND, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            4, GFC_STD_GNU, gfc_check_irand, NULL, NULL,
             i, BT_INTEGER, 4, OPTIONAL);
 
   make_generic ("irand", GFC_ISYM_IRAND, GFC_STD_GNU);
 
             i, BT_INTEGER, 4, OPTIONAL);
 
   make_generic ("irand", GFC_ISYM_IRAND, GFC_STD_GNU);
 
-  add_sym_1 ("isatty", GFC_ISYM_ISATTY, NO_CLASS, ACTUAL_NO, BT_LOGICAL, dl, GFC_STD_GNU,
-            gfc_check_isatty, NULL, gfc_resolve_isatty,
+  add_sym_1 ("isatty", GFC_ISYM_ISATTY, CLASS_IMPURE, ACTUAL_NO, BT_LOGICAL,
+            dl, GFC_STD_GNU, gfc_check_isatty, NULL, gfc_resolve_isatty,
             ut, BT_INTEGER, di, REQUIRED);
 
   make_generic ("isatty", GFC_ISYM_ISATTY, GFC_STD_GNU);
             ut, BT_INTEGER, di, REQUIRED);
 
   make_generic ("isatty", GFC_ISYM_ISATTY, GFC_STD_GNU);
@@ -1879,14 +2085,16 @@ add_functions (void)
 
   make_generic ("isnan", GFC_ISYM_ISNAN, GFC_STD_GNU);
 
 
   make_generic ("isnan", GFC_ISYM_ISNAN, GFC_STD_GNU);
 
-  add_sym_2 ("rshift", GFC_ISYM_RSHIFT, CLASS_ELEMENTAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_ishft, NULL, gfc_resolve_rshift,
+  add_sym_2 ("rshift", GFC_ISYM_RSHIFT, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_GNU,
+            gfc_check_ishft, gfc_simplify_rshift, gfc_resolve_rshift,
             i, BT_INTEGER, di, REQUIRED, sh, BT_INTEGER, di, REQUIRED);
 
   make_generic ("rshift", GFC_ISYM_RSHIFT, GFC_STD_GNU);
 
             i, BT_INTEGER, di, REQUIRED, sh, BT_INTEGER, di, REQUIRED);
 
   make_generic ("rshift", GFC_ISYM_RSHIFT, GFC_STD_GNU);
 
-  add_sym_2 ("lshift", GFC_ISYM_LSHIFT, CLASS_ELEMENTAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_ishft, NULL, gfc_resolve_lshift,
+  add_sym_2 ("lshift", GFC_ISYM_LSHIFT, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_GNU,
+            gfc_check_ishft, gfc_simplify_lshift, gfc_resolve_lshift,
             i, BT_INTEGER, di, REQUIRED, sh, BT_INTEGER, di, REQUIRED);
 
   make_generic ("lshift", GFC_ISYM_LSHIFT, GFC_STD_GNU);
             i, BT_INTEGER, di, REQUIRED, sh, BT_INTEGER, di, REQUIRED);
 
   make_generic ("lshift", GFC_ISYM_LSHIFT, GFC_STD_GNU);
@@ -1904,8 +2112,8 @@ add_functions (void)
 
   make_generic ("ishftc", GFC_ISYM_ISHFTC, GFC_STD_F95);
 
 
   make_generic ("ishftc", GFC_ISYM_ISHFTC, GFC_STD_F95);
 
-  add_sym_2 ("kill", GFC_ISYM_KILL, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_kill, NULL, gfc_resolve_kill,
+  add_sym_2 ("kill", GFC_ISYM_KILL, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, gfc_check_kill, NULL, gfc_resolve_kill,
             a, BT_INTEGER, di, REQUIRED, b, BT_INTEGER, di, REQUIRED);
 
   make_generic ("kill", GFC_ISYM_KILL, GFC_STD_GNU);
             a, BT_INTEGER, di, REQUIRED, b, BT_INTEGER, di, REQUIRED);
 
   make_generic ("kill", GFC_ISYM_KILL, GFC_STD_GNU);
@@ -1925,12 +2133,12 @@ add_functions (void)
   make_generic ("lbound", GFC_ISYM_LBOUND, GFC_STD_F95);
 
   add_sym_3 ("lcobound", GFC_ISYM_LCOBOUND, CLASS_INQUIRY, ACTUAL_NO,
   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_F95,
-            gfc_check_lcobound, gfc_simplify_lcobound, NULL,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_lcobound, gfc_simplify_lcobound, gfc_resolve_lcobound,
             ca, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
             kind, BT_INTEGER, di, OPTIONAL);
 
             ca, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
             kind, BT_INTEGER, di, OPTIONAL);
 
-  make_generic ("lcobound", GFC_ISYM_LCOBOUND, GFC_STD_F95);
+  make_generic ("lcobound", GFC_ISYM_LCOBOUND, GFC_STD_F2008);
 
   add_sym_1 ("leadz", GFC_ISYM_LEADZ, CLASS_ELEMENTAL, ACTUAL_NO,
             BT_INTEGER, di, GFC_STD_F2008,
 
   add_sym_1 ("leadz", GFC_ISYM_LEADZ, CLASS_ELEMENTAL, ACTUAL_NO,
             BT_INTEGER, di, GFC_STD_F2008,
@@ -1997,7 +2205,7 @@ add_functions (void)
 
   make_generic ("llt", GFC_ISYM_LLT, GFC_STD_F77);
 
 
   make_generic ("llt", GFC_ISYM_LLT, GFC_STD_F77);
 
-  add_sym_2 ("link", GFC_ISYM_LINK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+  add_sym_2 ("link", GFC_ISYM_LINK, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER, di,
             GFC_STD_GNU, gfc_check_link, NULL, gfc_resolve_link,
             p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER, dc, REQUIRED);
 
             GFC_STD_GNU, gfc_check_link, NULL, gfc_resolve_link,
             p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER, dc, REQUIRED);
 
@@ -2047,18 +2255,36 @@ add_functions (void)
 
   make_generic ("logical", GFC_ISYM_LOGICAL, GFC_STD_F95);
 
 
   make_generic ("logical", GFC_ISYM_LOGICAL, GFC_STD_F95);
 
-  add_sym_2 ("lstat", GFC_ISYM_LSTAT, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
-            GFC_STD_GNU, gfc_check_stat, NULL, gfc_resolve_lstat,
-            nm, BT_CHARACTER, dc, REQUIRED, vl, BT_INTEGER, di, REQUIRED);
+  add_sym_2_intent ("lstat", GFC_ISYM_LSTAT, CLASS_IMPURE, ACTUAL_NO,
+                   BT_INTEGER, di, GFC_STD_GNU,
+                   gfc_check_stat, NULL, gfc_resolve_lstat,
+                   nm, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+                   vl, BT_INTEGER, di, REQUIRED, INTENT_OUT);
 
   make_generic ("lstat", GFC_ISYM_LSTAT, GFC_STD_GNU);
 
 
   make_generic ("lstat", GFC_ISYM_LSTAT, GFC_STD_GNU);
 
-  add_sym_1 ("malloc", GFC_ISYM_MALLOC, NO_CLASS, ACTUAL_NO, BT_INTEGER, ii,
+  add_sym_1 ("malloc", GFC_ISYM_MALLOC, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER, ii,
             GFC_STD_GNU, gfc_check_malloc, NULL, gfc_resolve_malloc,
             sz, BT_INTEGER, di, REQUIRED);
 
   make_generic ("malloc", GFC_ISYM_MALLOC, GFC_STD_GNU);
 
             GFC_STD_GNU, gfc_check_malloc, NULL, gfc_resolve_malloc,
             sz, BT_INTEGER, di, REQUIRED);
 
   make_generic ("malloc", GFC_ISYM_MALLOC, GFC_STD_GNU);
 
+  add_sym_2 ("maskl", GFC_ISYM_MASKL, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_mask, gfc_simplify_maskl, gfc_resolve_mask,
+            i, BT_INTEGER, di, REQUIRED,
+            kind, BT_INTEGER, di, OPTIONAL);
+
+  make_generic ("maskl", GFC_ISYM_MASKL, GFC_STD_F2008);
+
+  add_sym_2 ("maskr", GFC_ISYM_MASKR, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_mask, gfc_simplify_maskr, gfc_resolve_mask,
+            i, BT_INTEGER, di, REQUIRED,
+            kind, BT_INTEGER, di, OPTIONAL);
+
+  make_generic ("maskr", GFC_ISYM_MASKR, GFC_STD_F2008);
+
   add_sym_2 ("matmul", GFC_ISYM_MATMUL, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
             gfc_check_matmul, gfc_simplify_matmul, gfc_resolve_matmul,
             ma, BT_REAL, dr, REQUIRED, mb, BT_REAL, dr, REQUIRED);
   add_sym_2 ("matmul", GFC_ISYM_MATMUL, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
             gfc_check_matmul, gfc_simplify_matmul, gfc_resolve_matmul,
             ma, BT_REAL, dr, REQUIRED, mb, BT_REAL, dr, REQUIRED);
@@ -2114,13 +2340,13 @@ add_functions (void)
 
   make_generic ("maxval", GFC_ISYM_MAXVAL, GFC_STD_F95);
 
 
   make_generic ("maxval", GFC_ISYM_MAXVAL, GFC_STD_F95);
 
-  add_sym_0 ("mclock", GFC_ISYM_MCLOCK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+  add_sym_0 ("mclock", GFC_ISYM_MCLOCK, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER, di,
             GFC_STD_GNU, NULL, NULL, gfc_resolve_mclock);
 
   make_generic ("mclock", GFC_ISYM_MCLOCK, GFC_STD_GNU);
 
             GFC_STD_GNU, NULL, NULL, gfc_resolve_mclock);
 
   make_generic ("mclock", GFC_ISYM_MCLOCK, GFC_STD_GNU);
 
-  add_sym_0 ("mclock8", GFC_ISYM_MCLOCK8, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
-            GFC_STD_GNU, NULL, NULL, gfc_resolve_mclock8);
+  add_sym_0 ("mclock8", GFC_ISYM_MCLOCK8, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, NULL, NULL, gfc_resolve_mclock8);
 
   make_generic ("mclock8", GFC_ISYM_MCLOCK8, GFC_STD_GNU);
 
 
   make_generic ("mclock8", GFC_ISYM_MCLOCK8, GFC_STD_GNU);
 
@@ -2131,6 +2357,16 @@ add_functions (void)
 
   make_generic ("merge", GFC_ISYM_MERGE, GFC_STD_F95);
 
 
   make_generic ("merge", GFC_ISYM_MERGE, GFC_STD_F95);
 
+  add_sym_3 ("merge_bits", GFC_ISYM_MERGE_BITS, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_merge_bits, gfc_simplify_merge_bits,
+            gfc_resolve_merge_bits,
+            i, BT_INTEGER, di, REQUIRED,
+            j, BT_INTEGER, di, REQUIRED,
+            msk, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("merge_bits", GFC_ISYM_MERGE_BITS, GFC_STD_F2008);
+
   /* Note: amin0 is equivalent to real(min), min1 is equivalent to
      int(min).  */
 
   /* Note: amin0 is equivalent to real(min), min1 is equivalent to
      int(min).  */
 
@@ -2228,14 +2464,24 @@ add_functions (void)
 
   make_generic ("not", GFC_ISYM_NOT, GFC_STD_F95);
 
 
   make_generic ("not", GFC_ISYM_NOT, GFC_STD_F95);
 
+  add_sym_2 ("norm2", GFC_ISYM_NORM2, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr,
+            GFC_STD_F2008, gfc_check_norm2, gfc_simplify_norm2, gfc_resolve_norm2,
+            x, BT_REAL, dr, REQUIRED,
+            dm, BT_INTEGER, ii, OPTIONAL);
+
+  make_generic ("norm2", GFC_ISYM_NORM2, GFC_STD_F2008);
+
   add_sym_1 ("null", GFC_ISYM_NULL, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
             gfc_check_null, gfc_simplify_null, NULL,
             mo, BT_INTEGER, di, OPTIONAL);
 
   make_generic ("null", GFC_ISYM_NULL, GFC_STD_F95);
 
   add_sym_1 ("null", GFC_ISYM_NULL, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
             gfc_check_null, gfc_simplify_null, NULL,
             mo, BT_INTEGER, di, OPTIONAL);
 
   make_generic ("null", GFC_ISYM_NULL, GFC_STD_F95);
 
-  add_sym_0 ("num_images", GFC_ISYM_NUMIMAGES, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F2008,
-            NULL, gfc_simplify_num_images, NULL);
+  add_sym_2 ("num_images", GFC_ISYM_NUM_IMAGES, CLASS_INQUIRY, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_num_images, gfc_simplify_num_images, NULL,
+            dist, BT_INTEGER, di, OPTIONAL,
+            failed, BT_LOGICAL, dl, OPTIONAL);
 
   add_sym_3 ("pack", GFC_ISYM_PACK, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
             gfc_check_pack, gfc_simplify_pack, gfc_resolve_pack,
 
   add_sym_3 ("pack", GFC_ISYM_PACK, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
             gfc_check_pack, gfc_simplify_pack, gfc_resolve_pack,
@@ -2244,6 +2490,28 @@ add_functions (void)
 
   make_generic ("pack", GFC_ISYM_PACK, GFC_STD_F95);
 
 
   make_generic ("pack", GFC_ISYM_PACK, GFC_STD_F95);
 
+
+  add_sym_2 ("parity", GFC_ISYM_PARITY, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_LOGICAL, dl,
+            GFC_STD_F2008, gfc_check_parity, gfc_simplify_parity, gfc_resolve_parity,
+            msk, BT_LOGICAL, dl, REQUIRED,
+            dm, BT_INTEGER, ii, OPTIONAL);
+
+  make_generic ("parity", GFC_ISYM_PARITY, GFC_STD_F2008);
+
+  add_sym_1 ("popcnt", GFC_ISYM_POPCNT, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_i, gfc_simplify_popcnt, NULL,
+            i, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("popcnt", GFC_ISYM_POPCNT, GFC_STD_F2008);
+
+  add_sym_1 ("poppar", GFC_ISYM_POPPAR, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_i, gfc_simplify_poppar, NULL,
+            i, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("poppar", GFC_ISYM_POPPAR, GFC_STD_F2008);
+
   add_sym_1 ("precision", GFC_ISYM_PRECISION, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
             gfc_check_precision, gfc_simplify_precision, NULL,
             x, BT_UNKNOWN, 0, REQUIRED);
   add_sym_1 ("precision", GFC_ISYM_PRECISION, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
             gfc_check_precision, gfc_simplify_precision, NULL,
             x, BT_UNKNOWN, 0, REQUIRED);
@@ -2270,8 +2538,8 @@ add_functions (void)
   make_generic ("radix", GFC_ISYM_RADIX, GFC_STD_F95);
 
   /* The following function is for G77 compatibility.  */
   make_generic ("radix", GFC_ISYM_RADIX, GFC_STD_F95);
 
   /* The following function is for G77 compatibility.  */
-  add_sym_1 ("rand", GFC_ISYM_RAND, NO_CLASS, ACTUAL_NO, BT_REAL, 4, GFC_STD_GNU,
-            gfc_check_rand, NULL, NULL,
+  add_sym_1 ("rand", GFC_ISYM_RAND, CLASS_IMPURE, ACTUAL_NO, BT_REAL,
+            4, GFC_STD_GNU, gfc_check_rand, NULL, NULL,
             i, BT_INTEGER, 4, OPTIONAL);
 
   /* Compatibility with HP FORTRAN 77/iX Reference.  Note, rand() and ran()
             i, BT_INTEGER, 4, OPTIONAL);
 
   /* Compatibility with HP FORTRAN 77/iX Reference.  Note, rand() and ran()
@@ -2286,6 +2554,11 @@ add_functions (void)
 
   make_generic ("range", GFC_ISYM_RANGE, GFC_STD_F95);
 
 
   make_generic ("range", GFC_ISYM_RANGE, GFC_STD_F95);
 
+  add_sym_1 ("rank", GFC_ISYM_RANK, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, di,
+            GFC_STD_F2008_TS, gfc_check_rank, gfc_simplify_rank, gfc_resolve_rank,
+            a, BT_REAL, dr, REQUIRED);
+  make_generic ("rank", GFC_ISYM_RANK, GFC_STD_F2008_TS);
+
   add_sym_2 ("real", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F77,
             gfc_check_real, gfc_simplify_real, gfc_resolve_real,
             a, BT_UNKNOWN, dr, REQUIRED, kind, BT_INTEGER, di, OPTIONAL);
   add_sym_2 ("real", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F77,
             gfc_check_real, gfc_simplify_real, gfc_resolve_real,
             a, BT_UNKNOWN, dr, REQUIRED, kind, BT_INTEGER, di, OPTIONAL);
@@ -2296,16 +2569,20 @@ 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,
             a, BT_UNKNOWN, dr, REQUIRED);
 
   add_sym_1 ("float", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F77,
-            gfc_check_i, gfc_simplify_float, NULL,
+            gfc_check_float, gfc_simplify_float, NULL,
             a, BT_INTEGER, di, REQUIRED);
 
             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,
   add_sym_1 ("sngl", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F77,
-            NULL, gfc_simplify_sngl, NULL,
+            gfc_check_sngl, gfc_simplify_sngl, NULL,
             a, BT_REAL, dd, REQUIRED);
 
   make_generic ("real", GFC_ISYM_REAL, GFC_STD_F77);
 
             a, BT_REAL, dd, REQUIRED);
 
   make_generic ("real", GFC_ISYM_REAL, GFC_STD_F77);
 
-  add_sym_2 ("rename", GFC_ISYM_RENAME, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+  add_sym_2 ("rename", GFC_ISYM_RENAME, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER, di,
             GFC_STD_GNU, gfc_check_rename, NULL, gfc_resolve_rename,
             p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER, dc, REQUIRED);
 
             GFC_STD_GNU, gfc_check_rename, NULL, gfc_resolve_rename,
             p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER, dc, REQUIRED);
 
@@ -2332,7 +2609,7 @@ add_functions (void)
 
   add_sym_2 ("same_type_as", GFC_ISYM_SAME_TYPE_AS, CLASS_INQUIRY, ACTUAL_NO,
             BT_LOGICAL, dl, GFC_STD_F2003,
 
   add_sym_2 ("same_type_as", GFC_ISYM_SAME_TYPE_AS, CLASS_INQUIRY, ACTUAL_NO,
             BT_LOGICAL, dl, GFC_STD_F2003,
-            gfc_check_same_type_as, NULL, NULL,
+            gfc_check_same_type_as, gfc_simplify_same_type_as, NULL,
             a, BT_UNKNOWN, 0, REQUIRED,
             b, BT_UNKNOWN, 0, REQUIRED);
 
             a, BT_UNKNOWN, 0, REQUIRED,
             b, BT_UNKNOWN, 0, REQUIRED);
 
@@ -2351,14 +2628,14 @@ add_functions (void)
   make_generic ("scan", GFC_ISYM_SCAN, GFC_STD_F95);
 
   /* Added for G77 compatibility garbage.  */
   make_generic ("scan", GFC_ISYM_SCAN, GFC_STD_F95);
 
   /* Added for G77 compatibility garbage.  */
-  add_sym_0 ("second", GFC_ISYM_SECOND, NO_CLASS, ACTUAL_NO, BT_REAL, 4, GFC_STD_GNU,
-            NULL, NULL, NULL);
+  add_sym_0 ("second", GFC_ISYM_SECOND, CLASS_IMPURE, ACTUAL_NO, BT_REAL,
+            4, GFC_STD_GNU, NULL, NULL, NULL);
 
   make_generic ("second", GFC_ISYM_SECOND, GFC_STD_GNU);
 
   /* Added for G77 compatibility.  */
 
   make_generic ("second", GFC_ISYM_SECOND, GFC_STD_GNU);
 
   /* Added for G77 compatibility.  */
-  add_sym_1 ("secnds", GFC_ISYM_SECNDS, NO_CLASS, ACTUAL_NO, BT_REAL, dr, GFC_STD_GNU,
-            gfc_check_secnds, NULL, gfc_resolve_secnds,
+  add_sym_1 ("secnds", GFC_ISYM_SECNDS, CLASS_IMPURE, ACTUAL_NO, BT_REAL,
+            dr, GFC_STD_GNU, gfc_check_secnds, NULL, gfc_resolve_secnds,
             x, BT_REAL, dr, REQUIRED);
 
   make_generic ("secnds", GFC_ISYM_SECNDS, GFC_STD_GNU);
             x, BT_REAL, dr, REQUIRED);
 
   make_generic ("secnds", GFC_ISYM_SECNDS, GFC_STD_GNU);
@@ -2376,10 +2653,11 @@ add_functions (void)
 
   make_generic ("selected_int_kind", GFC_ISYM_SI_KIND, GFC_STD_F95);
 
 
   make_generic ("selected_int_kind", GFC_ISYM_SI_KIND, GFC_STD_F95);
 
-  add_sym_2 ("selected_real_kind", GFC_ISYM_SR_KIND, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_INTEGER, di,
+  add_sym_3 ("selected_real_kind", GFC_ISYM_SR_KIND, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_INTEGER, di,
             GFC_STD_F95, gfc_check_selected_real_kind,
             gfc_simplify_selected_real_kind, NULL,
             GFC_STD_F95, gfc_check_selected_real_kind,
             gfc_simplify_selected_real_kind, NULL,
-            p, BT_INTEGER, di, OPTIONAL, r, BT_INTEGER, di, OPTIONAL);
+            p, BT_INTEGER, di, OPTIONAL, r, BT_INTEGER, di, OPTIONAL,
+            "radix", BT_INTEGER, di, OPTIONAL);
 
   make_generic ("selected_real_kind", GFC_ISYM_SR_KIND, GFC_STD_F95);
 
 
   make_generic ("selected_real_kind", GFC_ISYM_SR_KIND, GFC_STD_F95);
 
@@ -2390,12 +2668,37 @@ add_functions (void)
 
   make_generic ("set_exponent", GFC_ISYM_SET_EXPONENT, GFC_STD_F95);
 
 
   make_generic ("set_exponent", GFC_ISYM_SET_EXPONENT, GFC_STD_F95);
 
-  add_sym_1 ("shape", GFC_ISYM_SHAPE, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
+  add_sym_2 ("shape", GFC_ISYM_SHAPE, CLASS_INQUIRY, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95,
             gfc_check_shape, gfc_simplify_shape, gfc_resolve_shape,
             gfc_check_shape, gfc_simplify_shape, gfc_resolve_shape,
-            src, BT_REAL, dr, REQUIRED);
+            src, BT_REAL, dr, REQUIRED,
+            kind, BT_INTEGER, di, OPTIONAL);
 
   make_generic ("shape", GFC_ISYM_SHAPE, GFC_STD_F95);
 
 
   make_generic ("shape", GFC_ISYM_SHAPE, GFC_STD_F95);
 
+  add_sym_2 ("shifta", GFC_ISYM_SHIFTA, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_shift, gfc_simplify_shifta, gfc_resolve_shift,
+            i, BT_INTEGER, di, REQUIRED,
+            sh, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("shifta", GFC_ISYM_SHIFTA, GFC_STD_F2008);
+
+  add_sym_2 ("shiftl", GFC_ISYM_SHIFTL, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_shift, gfc_simplify_shiftl, gfc_resolve_shift,
+            i, BT_INTEGER, di, REQUIRED,
+            sh, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("shiftl", GFC_ISYM_SHIFTL, GFC_STD_F2008);
+
+  add_sym_2 ("shiftr", GFC_ISYM_SHIFTR, CLASS_ELEMENTAL, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_shift, gfc_simplify_shiftr, gfc_resolve_shift,
+            i, BT_INTEGER, di, REQUIRED,
+            sh, BT_INTEGER, di, REQUIRED);
+
+  make_generic ("shiftr", GFC_ISYM_SHIFTR, GFC_STD_F2008);
+
   add_sym_2 ("sign", GFC_ISYM_SIGN, CLASS_ELEMENTAL, ACTUAL_YES, BT_REAL, dr, GFC_STD_F77,
             gfc_check_sign, gfc_simplify_sign, gfc_resolve_sign,
             a, BT_REAL, dr, REQUIRED, b, BT_REAL, dr, REQUIRED);
   add_sym_2 ("sign", GFC_ISYM_SIGN, CLASS_ELEMENTAL, ACTUAL_YES, BT_REAL, dr, GFC_STD_F77,
             gfc_check_sign, gfc_simplify_sign, gfc_resolve_sign,
             a, BT_REAL, dr, REQUIRED, b, BT_REAL, dr, REQUIRED);
@@ -2410,9 +2713,9 @@ add_functions (void)
 
   make_generic ("sign", GFC_ISYM_SIGN, GFC_STD_F77);
 
 
   make_generic ("sign", GFC_ISYM_SIGN, GFC_STD_F77);
 
-  add_sym_2 ("signal", GFC_ISYM_SIGNAL, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_signal, NULL, gfc_resolve_signal,
-            num, BT_INTEGER, di, REQUIRED, han, BT_UNKNOWN, 0, REQUIRED);
+  add_sym_2 ("signal", GFC_ISYM_SIGNAL, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, gfc_check_signal, NULL, gfc_resolve_signal,
+            num, BT_INTEGER, di, REQUIRED, han, BT_VOID, 0, REQUIRED);
 
   make_generic ("signal", GFC_ISYM_SIGNAL, GFC_STD_GNU);
 
 
   make_generic ("signal", GFC_ISYM_SIGNAL, GFC_STD_GNU);
 
@@ -2454,12 +2757,56 @@ add_functions (void)
 
   make_generic ("size", GFC_ISYM_SIZE, GFC_STD_F95);
 
 
   make_generic ("size", GFC_ISYM_SIZE, GFC_STD_F95);
 
-  add_sym_1 ("sizeof", GFC_ISYM_SIZEOF, NO_CLASS, ACTUAL_NO, BT_INTEGER, ii,
-            GFC_STD_GNU, gfc_check_sizeof, NULL, NULL,
+  /* Obtain the stride for a given dimensions; to be used only internally.
+     "make_from_module" makes it inaccessible for external users.  */
+  add_sym_2 (GFC_PREFIX ("stride"), GFC_ISYM_STRIDE, CLASS_INQUIRY, ACTUAL_NO,
+            BT_INTEGER, gfc_index_integer_kind, GFC_STD_GNU,
+            NULL, NULL, gfc_resolve_stride,
+            ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL);
+  make_from_module();
+
+  add_sym_1 ("sizeof", GFC_ISYM_SIZEOF, CLASS_INQUIRY, ACTUAL_NO,
+            BT_INTEGER, ii, GFC_STD_GNU,
+            gfc_check_sizeof, gfc_simplify_sizeof, NULL,
             x, BT_UNKNOWN, 0, REQUIRED);
 
   make_generic ("sizeof", GFC_ISYM_SIZEOF, GFC_STD_GNU);
             x, BT_UNKNOWN, 0, REQUIRED);
 
   make_generic ("sizeof", GFC_ISYM_SIZEOF, GFC_STD_GNU);
-  make_alias ("c_sizeof", GFC_STD_F2008);
+
+  /* The following functions are part of ISO_C_BINDING.  */
+  add_sym_2 ("c_associated", GFC_ISYM_C_ASSOCIATED, CLASS_INQUIRY, ACTUAL_NO,
+            BT_LOGICAL, dl, GFC_STD_F2003, gfc_check_c_associated, NULL, NULL,
+            "C_PTR_1", BT_VOID, 0, REQUIRED,
+            "C_PTR_2", BT_VOID, 0, OPTIONAL);
+  make_from_module();
+
+  add_sym_1 ("c_loc", GFC_ISYM_C_LOC, CLASS_INQUIRY, ACTUAL_NO,
+            BT_VOID, 0, GFC_STD_F2003,
+            gfc_check_c_loc, NULL, gfc_resolve_c_loc,
+            x, BT_UNKNOWN, 0, REQUIRED);
+  make_from_module();
+
+  add_sym_1 ("c_funloc", GFC_ISYM_C_FUNLOC, CLASS_INQUIRY, ACTUAL_NO,
+            BT_VOID, 0, GFC_STD_F2003,
+            gfc_check_c_funloc, NULL, gfc_resolve_c_funloc,
+            x, BT_UNKNOWN, 0, REQUIRED);
+  make_from_module();
+
+  add_sym_1 ("c_sizeof", GFC_ISYM_C_SIZEOF, CLASS_INQUIRY, ACTUAL_NO,
+            BT_INTEGER, gfc_index_integer_kind, GFC_STD_F2008,
+            gfc_check_c_sizeof, gfc_simplify_sizeof, NULL,
+            x, BT_UNKNOWN, 0, REQUIRED);
+  make_from_module();
+
+  /* COMPILER_OPTIONS and COMPILER_VERSION are part of ISO_FORTRAN_ENV.  */  
+  add_sym_0 ("compiler_options", GFC_ISYM_COMPILER_OPTIONS, CLASS_INQUIRY,
+            ACTUAL_NO, BT_CHARACTER, dc, GFC_STD_F2008,
+            NULL, gfc_simplify_compiler_options, NULL);
+  make_from_module();
+
+  add_sym_0 ("compiler_version", GFC_ISYM_COMPILER_VERSION, CLASS_INQUIRY,
+            ACTUAL_NO, BT_CHARACTER, dc, GFC_STD_F2008,
+            NULL, gfc_simplify_compiler_version, NULL);
+  make_from_module();
 
   add_sym_1 ("spacing", GFC_ISYM_SPACING, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
             gfc_check_x, gfc_simplify_spacing, gfc_resolve_spacing,
 
   add_sym_1 ("spacing", GFC_ISYM_SPACING, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
             gfc_check_x, gfc_simplify_spacing, gfc_resolve_spacing,
@@ -2494,12 +2841,21 @@ add_functions (void)
 
   make_generic ("sqrt", GFC_ISYM_SQRT, GFC_STD_F77);
 
 
   make_generic ("sqrt", GFC_ISYM_SQRT, GFC_STD_F77);
 
-  add_sym_2 ("stat", GFC_ISYM_STAT, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
-            GFC_STD_GNU, gfc_check_stat, NULL, gfc_resolve_stat,
-            nm, BT_CHARACTER, dc, REQUIRED, vl, BT_INTEGER, di, REQUIRED);
+  add_sym_2_intent ("stat", GFC_ISYM_STAT, CLASS_IMPURE, ACTUAL_NO,
+                   BT_INTEGER, di, GFC_STD_GNU,
+                   gfc_check_stat, NULL, gfc_resolve_stat,
+                   nm, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+                   vl, BT_INTEGER, di, REQUIRED, INTENT_OUT);
 
   make_generic ("stat", GFC_ISYM_STAT, GFC_STD_GNU);
 
 
   make_generic ("stat", GFC_ISYM_STAT, GFC_STD_GNU);
 
+  add_sym_2 ("storage_size", GFC_ISYM_STORAGE_SIZE, CLASS_INQUIRY, ACTUAL_NO,
+            BT_INTEGER, di, GFC_STD_F2008,
+            gfc_check_storage_size, gfc_simplify_storage_size,
+            gfc_resolve_storage_size,
+            a, BT_UNKNOWN, 0, REQUIRED,
+            kind, BT_INTEGER, di, OPTIONAL);
+  
   add_sym_3red ("sum", GFC_ISYM_SUM, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
                gfc_check_product_sum, gfc_simplify_sum, gfc_resolve_sum,
                ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
   add_sym_3red ("sum", GFC_ISYM_SUM, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95,
                gfc_check_product_sum, gfc_simplify_sum, gfc_resolve_sum,
                ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
@@ -2507,13 +2863,13 @@ add_functions (void)
 
   make_generic ("sum", GFC_ISYM_SUM, GFC_STD_F95);
 
 
   make_generic ("sum", GFC_ISYM_SUM, GFC_STD_F95);
 
-  add_sym_2 ("symlnk", GFC_ISYM_SYMLNK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+  add_sym_2 ("symlnk", GFC_ISYM_SYMLNK, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER, di,
             GFC_STD_GNU, gfc_check_symlnk, NULL, gfc_resolve_symlnk,
             p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("symlnk", GFC_ISYM_SYMLNK, GFC_STD_GNU);
 
             GFC_STD_GNU, gfc_check_symlnk, NULL, gfc_resolve_symlnk,
             p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("symlnk", GFC_ISYM_SYMLNK, GFC_STD_GNU);
 
-  add_sym_1 ("system", GFC_ISYM_SYSTEM, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+  add_sym_1 ("system", GFC_ISYM_SYSTEM, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER, di,
             GFC_STD_GNU, NULL, NULL, NULL,
             com, BT_CHARACTER, dc, REQUIRED);
 
             GFC_STD_GNU, NULL, NULL, NULL,
             com, BT_CHARACTER, dc, REQUIRED);
 
@@ -2539,17 +2895,18 @@ add_functions (void)
 
   make_generic ("tanh", GFC_ISYM_TANH, GFC_STD_F77);
 
 
   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, NULL,
-            ca, BT_REAL, dr, OPTIONAL, dm, BT_INTEGER, ii, OPTIONAL);
+  add_sym_3 ("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,
+            ca, BT_REAL, dr, OPTIONAL, dm, BT_INTEGER, ii, OPTIONAL,
+            dist, BT_INTEGER, di, OPTIONAL);
 
 
-  add_sym_0 ("time", GFC_ISYM_TIME, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU, 
-            NULL, NULL, gfc_resolve_time);
+  add_sym_0 ("time", GFC_ISYM_TIME, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, NULL, NULL, gfc_resolve_time);
 
   make_generic ("time", GFC_ISYM_TIME, GFC_STD_GNU);
 
 
   make_generic ("time", GFC_ISYM_TIME, GFC_STD_GNU);
 
-  add_sym_0 ("time8", GFC_ISYM_TIME8, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU, 
-            NULL, NULL, gfc_resolve_time8);
+  add_sym_0 ("time8", GFC_ISYM_TIME8, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, NULL, NULL, gfc_resolve_time8);
 
   make_generic ("time8", GFC_ISYM_TIME8, GFC_STD_GNU);
 
 
   make_generic ("time8", GFC_ISYM_TIME8, GFC_STD_GNU);
 
@@ -2585,8 +2942,8 @@ add_functions (void)
 
   make_generic ("trim", GFC_ISYM_TRIM, GFC_STD_F95);
 
 
   make_generic ("trim", GFC_ISYM_TRIM, GFC_STD_F95);
 
-  add_sym_1 ("ttynam", GFC_ISYM_TTYNAM, NO_CLASS, ACTUAL_NO, BT_CHARACTER, 0, GFC_STD_GNU,
-            gfc_check_ttynam, NULL, gfc_resolve_ttynam,
+  add_sym_1 ("ttynam", GFC_ISYM_TTYNAM, CLASS_IMPURE, ACTUAL_NO, BT_CHARACTER,
+            0, GFC_STD_GNU, gfc_check_ttynam, NULL, gfc_resolve_ttynam,
             ut, BT_INTEGER, di, REQUIRED);
 
   make_generic ("ttynam", GFC_ISYM_TTYNAM, GFC_STD_GNU);
             ut, BT_INTEGER, di, REQUIRED);
 
   make_generic ("ttynam", GFC_ISYM_TTYNAM, GFC_STD_GNU);
@@ -2600,23 +2957,23 @@ add_functions (void)
   make_generic ("ubound", GFC_ISYM_UBOUND, GFC_STD_F95);
 
   add_sym_3 ("ucobound", GFC_ISYM_UCOBOUND, CLASS_INQUIRY, ACTUAL_NO,
   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_F95,
-            gfc_check_ucobound, gfc_simplify_ucobound, NULL,
-            ca, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
-            kind, BT_INTEGER, di, OPTIONAL);
+           BT_INTEGER, di, GFC_STD_F2008,
+           gfc_check_ucobound, gfc_simplify_ucobound, gfc_resolve_ucobound,
+           ca, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL,
+           kind, BT_INTEGER, di, OPTIONAL);
 
 
-  make_generic ("ucobound", GFC_ISYM_UCOBOUND, GFC_STD_F95);
+  make_generic ("ucobound", GFC_ISYM_UCOBOUND, GFC_STD_F2008);
 
   /* g77 compatibility for UMASK.  */
 
   /* g77 compatibility for UMASK.  */
-  add_sym_1 ("umask", GFC_ISYM_UMASK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di,
+  add_sym_1 ("umask", GFC_ISYM_UMASK, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER, di,
             GFC_STD_GNU, gfc_check_umask, NULL, gfc_resolve_umask,
             msk, BT_INTEGER, di, REQUIRED);
 
   make_generic ("umask", GFC_ISYM_UMASK, GFC_STD_GNU);
 
   /* g77 compatibility for UNLINK.  */
             GFC_STD_GNU, gfc_check_umask, NULL, gfc_resolve_umask,
             msk, BT_INTEGER, di, REQUIRED);
 
   make_generic ("umask", GFC_ISYM_UMASK, GFC_STD_GNU);
 
   /* g77 compatibility for UNLINK.  */
-  add_sym_1 ("unlink", GFC_ISYM_UNLINK, NO_CLASS, ACTUAL_NO, BT_INTEGER, di, GFC_STD_GNU,
-            gfc_check_unlink, NULL, gfc_resolve_unlink,
+  add_sym_1 ("unlink", GFC_ISYM_UNLINK, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER,
+            di, GFC_STD_GNU, gfc_check_unlink, NULL, gfc_resolve_unlink,
             "path", BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("unlink", GFC_ISYM_UNLINK, GFC_STD_GNU);
             "path", BT_CHARACTER, dc, REQUIRED);
 
   make_generic ("unlink", GFC_ISYM_UNLINK, GFC_STD_GNU);
@@ -2636,11 +2993,18 @@ add_functions (void)
 
   make_generic ("verify", GFC_ISYM_VERIFY, GFC_STD_F95);
     
 
   make_generic ("verify", GFC_ISYM_VERIFY, GFC_STD_F95);
     
-  add_sym_1 ("loc", GFC_ISYM_LOC, NO_CLASS, ACTUAL_NO, BT_INTEGER, ii,
+  add_sym_1 ("loc", GFC_ISYM_LOC, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER, ii,
             GFC_STD_GNU, gfc_check_loc, NULL, gfc_resolve_loc,
             x, BT_UNKNOWN, 0, REQUIRED);
                
   make_generic ("loc", GFC_ISYM_LOC, GFC_STD_GNU);
             GFC_STD_GNU, gfc_check_loc, NULL, gfc_resolve_loc,
             x, BT_UNKNOWN, 0, REQUIRED);
                
   make_generic ("loc", GFC_ISYM_LOC, GFC_STD_GNU);
+
+  /* The following function is internally used for coarray libray functions.
+     "make_from_module" makes it inaccessible for external users.  */
+  add_sym_1 (GFC_PREFIX ("caf_get"), GFC_ISYM_CAF_GET, CLASS_IMPURE, ACTUAL_NO,
+            BT_REAL, dr, GFC_STD_GNU, NULL, NULL, NULL,
+            x, BT_REAL, dr, REQUIRED);
+  make_from_module();
 }
 
 
 }
 
 
@@ -2651,7 +3015,7 @@ add_subroutines (void)
 {
   /* Argument names as in the standard (to be used as argument keywords).  */
   const char
 {
   /* Argument names as in the standard (to be used as argument keywords).  */
   const char
-    *h = "harvest", *dt = "date", *vl = "values", *pt = "put",
+    *a = "a", *h = "harvest", *dt = "date", *vl = "values", *pt = "put",
     *c = "count", *tm = "time", *tp = "topos", *gt = "get",
     *t = "to", *zn = "zone", *fp = "frompos", *cm = "count_max",
     *f = "from", *sz = "size", *ln = "len", *cr = "count_rate",
     *c = "count", *tm = "time", *tp = "topos", *gt = "get",
     *t = "to", *zn = "zone", *fp = "frompos", *cm = "count_max",
     *f = "from", *sz = "size", *ln = "len", *cr = "count_rate",
@@ -2660,7 +3024,8 @@ add_subroutines (void)
     *trim_name = "trim_name", *ut = "unit", *han = "handler",
     *sec = "seconds", *res = "result", *of = "offset", *md = "mode",
     *whence = "whence", *pos = "pos", *ptr = "ptr", *p1 = "path1",
     *trim_name = "trim_name", *ut = "unit", *han = "handler",
     *sec = "seconds", *res = "result", *of = "offset", *md = "mode",
     *whence = "whence", *pos = "pos", *ptr = "ptr", *p1 = "path1",
-    *p2 = "path2", *msk = "mask", *old = "old";
+    *p2 = "path2", *msk = "mask", *old = "old", *result_image = "result_image",
+    *stat = "stat", *errmsg = "errmsg";
 
   int di, dr, dc, dl, ii;
 
 
   int di, dr, dc, dl, ii;
 
@@ -2674,96 +3039,199 @@ add_subroutines (void)
 
   make_noreturn();
 
 
   make_noreturn();
 
-  add_sym_1s_intent ("cpu_time", GFC_ISYM_CPU_TIME, NO_CLASS, BT_UNKNOWN, 0,
-                    GFC_STD_F95, gfc_check_cpu_time, NULL,
-                    gfc_resolve_cpu_time,
-                    tm, BT_REAL, dr, REQUIRED, INTENT_OUT);
+  add_sym_3s ("atomic_define", GFC_ISYM_ATOMIC_DEF, CLASS_ATOMIC,
+             BT_UNKNOWN, 0, GFC_STD_F2008,
+             gfc_check_atomic_def, NULL, gfc_resolve_atomic_def,
+             "atom", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             "value", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_3s ("atomic_ref", GFC_ISYM_ATOMIC_REF, CLASS_ATOMIC,
+             BT_UNKNOWN, 0, GFC_STD_F2008,
+             gfc_check_atomic_ref, NULL, gfc_resolve_atomic_ref,
+             "value", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             "atom", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_5s ("atomic_cas", GFC_ISYM_ATOMIC_CAS, CLASS_ATOMIC,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_atomic_cas, NULL, NULL,
+             "atom", BT_INTEGER, di, REQUIRED, INTENT_INOUT,
+             "old", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             "compare", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             "new", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_3s ("atomic_add", GFC_ISYM_ATOMIC_ADD, CLASS_ATOMIC,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_atomic_op, NULL, NULL,
+             "atom", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             "value", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_3s ("atomic_and", GFC_ISYM_ATOMIC_AND, CLASS_ATOMIC,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_atomic_op, NULL, NULL,
+             "atom", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             "value", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_3s ("atomic_or", GFC_ISYM_ATOMIC_OR, CLASS_ATOMIC,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_atomic_op, NULL, NULL,
+             "atom", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             "value", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_3s ("atomic_xor", GFC_ISYM_ATOMIC_XOR, CLASS_ATOMIC,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_atomic_op, NULL, NULL,
+             "atom", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             "value", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_4s ("atomic_fetch_add", GFC_ISYM_ATOMIC_FETCH_ADD, CLASS_ATOMIC,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_atomic_fetch_op, NULL, NULL,
+             "atom", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             "value", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             "old", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_4s ("atomic_fetch_and", GFC_ISYM_ATOMIC_FETCH_AND, CLASS_ATOMIC,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_atomic_fetch_op, NULL, NULL,
+             "atom", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             "value", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             "old", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_4s ("atomic_fetch_or", GFC_ISYM_ATOMIC_FETCH_OR, CLASS_ATOMIC,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_atomic_fetch_op, NULL, NULL,
+             "atom", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             "value", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             "old", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_4s ("atomic_fetch_xor", GFC_ISYM_ATOMIC_FETCH_XOR, CLASS_ATOMIC,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_atomic_fetch_op, NULL, NULL,
+             "atom", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             "value", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             "old", BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_0s ("backtrace", GFC_ISYM_BACKTRACE, GFC_STD_GNU, NULL);
+
+  add_sym_1s ("cpu_time", GFC_ISYM_CPU_TIME, CLASS_IMPURE, BT_UNKNOWN, 0,
+             GFC_STD_F95, gfc_check_cpu_time, NULL, gfc_resolve_cpu_time,
+             tm, BT_REAL, dr, REQUIRED, INTENT_OUT);
 
   /* More G77 compatibility garbage.  */
 
   /* More G77 compatibility garbage.  */
-  add_sym_2s ("ctime", GFC_ISYM_CTIME, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_2s ("ctime", GFC_ISYM_CTIME, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_ctime_sub, NULL, gfc_resolve_ctime_sub,
              gfc_check_ctime_sub, NULL, gfc_resolve_ctime_sub,
-             tm, BT_INTEGER, di, REQUIRED, res, BT_CHARACTER, dc, REQUIRED);
+             tm, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             res, BT_CHARACTER, dc, REQUIRED, INTENT_OUT);
 
 
-  add_sym_1s ("idate", GFC_ISYM_IDATE, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_1s ("idate", GFC_ISYM_IDATE, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_itime_idate, NULL, gfc_resolve_idate,
              gfc_check_itime_idate, NULL, gfc_resolve_idate,
-             vl, BT_INTEGER, 4, REQUIRED);
+             vl, BT_INTEGER, 4, REQUIRED, INTENT_OUT);
 
 
-  add_sym_1s ("itime", GFC_ISYM_ITIME, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_1s ("itime", GFC_ISYM_ITIME, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_itime_idate, NULL, gfc_resolve_itime,
              gfc_check_itime_idate, NULL, gfc_resolve_itime,
-             vl, BT_INTEGER, 4, REQUIRED);
+             vl, BT_INTEGER, 4, REQUIRED, INTENT_OUT);
 
 
-  add_sym_2s ("ltime", GFC_ISYM_LTIME, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_2s ("ltime", GFC_ISYM_LTIME, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_ltime_gmtime, NULL, gfc_resolve_ltime,
              gfc_check_ltime_gmtime, NULL, gfc_resolve_ltime,
-             tm, BT_INTEGER, di, REQUIRED, vl, BT_INTEGER, di, REQUIRED);
+             tm, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             vl, BT_INTEGER, di, REQUIRED, INTENT_OUT);
 
 
-  add_sym_2s ("gmtime", GFC_ISYM_GMTIME, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_ltime_gmtime, NULL, gfc_resolve_gmtime,
-             tm, BT_INTEGER, di, REQUIRED, vl, BT_INTEGER, di, REQUIRED);
+  add_sym_2s ("gmtime", GFC_ISYM_GMTIME, CLASS_IMPURE, BT_UNKNOWN, 0,
+             GFC_STD_GNU, gfc_check_ltime_gmtime, NULL, gfc_resolve_gmtime,
+             tm, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             vl, BT_INTEGER, di, REQUIRED, INTENT_OUT);
 
 
-  add_sym_1s ("second", GFC_ISYM_SECOND, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_second_sub, NULL, gfc_resolve_second_sub,
-             tm, BT_REAL, dr, REQUIRED);
+  add_sym_1s ("second", GFC_ISYM_SECOND, CLASS_IMPURE, BT_UNKNOWN, 0,
+             GFC_STD_GNU, gfc_check_second_sub, NULL, gfc_resolve_second_sub,
+             tm, BT_REAL, dr, REQUIRED, INTENT_OUT);
 
 
-  add_sym_2s ("chdir", GFC_ISYM_CHDIR, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_2s ("chdir", GFC_ISYM_CHDIR, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_chdir_sub, NULL, gfc_resolve_chdir_sub,
              gfc_check_chdir_sub, NULL, gfc_resolve_chdir_sub,
-             name, BT_CHARACTER, dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
+             name, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_3s ("chmod", GFC_ISYM_CHMOD, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_3s ("chmod", GFC_ISYM_CHMOD, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_chmod_sub, NULL, gfc_resolve_chmod_sub,
              gfc_check_chmod_sub, NULL, gfc_resolve_chmod_sub,
-             name, BT_CHARACTER, dc, REQUIRED, md, BT_CHARACTER, dc, REQUIRED,
-             st, BT_INTEGER, di, OPTIONAL);
+             name, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             md, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_4s ("date_and_time", GFC_ISYM_DATE_AND_TIME, NO_CLASS, BT_UNKNOWN, 0,
-             GFC_STD_F95, gfc_check_date_and_time, NULL, NULL,
+  add_sym_4s ("date_and_time", GFC_ISYM_DATE_AND_TIME, CLASS_IMPURE, BT_UNKNOWN,
+             0, GFC_STD_F95, gfc_check_date_and_time, NULL, NULL,
              dt, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
              tm, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
              zn, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
              vl, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
   /* More G77 compatibility garbage.  */
              dt, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
              tm, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
              zn, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
              vl, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
   /* More G77 compatibility garbage.  */
-  add_sym_2s ("etime", GFC_ISYM_ETIME, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_2s ("etime", GFC_ISYM_ETIME, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_dtime_etime_sub, NULL, gfc_resolve_etime_sub,
              gfc_check_dtime_etime_sub, NULL, gfc_resolve_etime_sub,
-             vl, BT_REAL, 4, REQUIRED, tm, BT_REAL, 4, REQUIRED);
+             vl, BT_REAL, 4, REQUIRED, INTENT_OUT,
+             tm, BT_REAL, 4, REQUIRED, INTENT_OUT);
 
 
-  add_sym_2s ("dtime", GFC_ISYM_DTIME, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_2s ("dtime", GFC_ISYM_DTIME, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_dtime_etime_sub, NULL, gfc_resolve_dtime_sub,
              gfc_check_dtime_etime_sub, NULL, gfc_resolve_dtime_sub,
-             vl, BT_REAL, 4, REQUIRED, tm, BT_REAL, 4, REQUIRED);
-
-  add_sym_1s ("fdate", GFC_ISYM_FDATE, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+             vl, BT_REAL, 4, REQUIRED, INTENT_OUT,
+             tm, BT_REAL, 4, REQUIRED, INTENT_OUT);
+
+  add_sym_5s ("execute_command_line", GFC_ISYM_EXECUTE_COMMAND_LINE,
+             CLASS_IMPURE , BT_UNKNOWN, 0, GFC_STD_F2008,
+             NULL, NULL, gfc_resolve_execute_command_line,
+             "command", BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             "wait", BT_LOGICAL, dl, OPTIONAL, INTENT_IN,
+             "exitstat", BT_INTEGER, di, OPTIONAL, INTENT_INOUT,
+             "cmdstat", BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+             "cmdmsg", BT_CHARACTER, dc, OPTIONAL, INTENT_INOUT);
+
+  add_sym_1s ("fdate", GFC_ISYM_FDATE, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_fdate_sub, NULL, gfc_resolve_fdate_sub,
              gfc_check_fdate_sub, NULL, gfc_resolve_fdate_sub,
-             dt, BT_CHARACTER, dc, REQUIRED);
+             dt, BT_CHARACTER, dc, REQUIRED, INTENT_OUT);
 
 
-  add_sym_1s ("gerror", GFC_ISYM_GERROR, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_gerror, NULL, gfc_resolve_gerror, res, BT_CHARACTER,
-             dc, REQUIRED);
+  add_sym_1s ("gerror", GFC_ISYM_GERROR, CLASS_IMPURE, BT_UNKNOWN,
+             0, GFC_STD_GNU, gfc_check_gerror, NULL, gfc_resolve_gerror,
+             res, BT_CHARACTER, dc, REQUIRED, INTENT_OUT);
 
 
-  add_sym_2s ("getcwd", GFC_ISYM_GETCWD, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_getcwd_sub, NULL, gfc_resolve_getcwd_sub,
-             c, BT_CHARACTER, dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
+  add_sym_2s ("getcwd", GFC_ISYM_GETCWD, CLASS_IMPURE, BT_UNKNOWN, 0,
+             GFC_STD_GNU, gfc_check_getcwd_sub, NULL, gfc_resolve_getcwd_sub,
+             c, BT_CHARACTER, dc, REQUIRED, INTENT_OUT,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_2s ("getenv", GFC_ISYM_GETENV, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             NULL, NULL, NULL,
-             name, BT_CHARACTER, dc, REQUIRED, val, BT_CHARACTER, dc,
-             REQUIRED);
+  add_sym_2s ("getenv", GFC_ISYM_GETENV, CLASS_IMPURE, BT_UNKNOWN,
+             0, GFC_STD_GNU, NULL, NULL, NULL,
+             name, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             val, BT_CHARACTER, dc, REQUIRED, INTENT_OUT);
 
 
-  add_sym_2s ("getarg", GFC_ISYM_GETARG, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_getarg, NULL, gfc_resolve_getarg,
-             pos, BT_INTEGER, di, REQUIRED, val, BT_CHARACTER, dc, REQUIRED);
+  add_sym_2s ("getarg", GFC_ISYM_GETARG, CLASS_IMPURE, BT_UNKNOWN,
+             0, GFC_STD_GNU, gfc_check_getarg, NULL, gfc_resolve_getarg,
+             pos, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             val, BT_CHARACTER, dc, REQUIRED, INTENT_OUT);
 
 
-  add_sym_1s ("getlog", GFC_ISYM_GETLOG, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_getlog, NULL, gfc_resolve_getlog, c, BT_CHARACTER,
-             dc, REQUIRED);
+  add_sym_1s ("getlog", GFC_ISYM_GETLOG, CLASS_IMPURE, BT_UNKNOWN,
+             0, GFC_STD_GNU, gfc_check_getlog, NULL, gfc_resolve_getlog,
+             c, BT_CHARACTER, dc, REQUIRED, INTENT_OUT);
 
   /* F2003 commandline routines.  */
 
 
   /* F2003 commandline routines.  */
 
-  add_sym_3s_intent ("get_command", GFC_ISYM_GET_COMMAND, NO_CLASS, BT_UNKNOWN,
-                    0, GFC_STD_F2003, NULL, NULL, gfc_resolve_get_command,
-                    com, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
-                    length, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
-                    st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+  add_sym_3s ("get_command", GFC_ISYM_GET_COMMAND, CLASS_IMPURE,
+             BT_UNKNOWN, 0, GFC_STD_F2003,
+             NULL, NULL, gfc_resolve_get_command,
+             com, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
+             length, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_4s ("get_command_argument", GFC_ISYM_GET_COMMAND_ARGUMENT, NO_CLASS,
-             BT_UNKNOWN, 0, GFC_STD_F2003, NULL, NULL,
+  add_sym_4s ("get_command_argument", GFC_ISYM_GET_COMMAND_ARGUMENT,
+             CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_F2003, NULL, NULL,
              gfc_resolve_get_command_argument,
              num, BT_INTEGER, di, REQUIRED, INTENT_IN,
              val, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
              gfc_resolve_get_command_argument,
              num, BT_INTEGER, di, REQUIRED, INTENT_IN,
              val, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
@@ -2773,7 +3241,7 @@ add_subroutines (void)
   /* F2003 subroutine to get environment variables.  */
 
   add_sym_5s ("get_environment_variable", GFC_ISYM_GET_ENVIRONMENT_VARIABLE,
   /* F2003 subroutine to get environment variables.  */
 
   add_sym_5s ("get_environment_variable", GFC_ISYM_GET_ENVIRONMENT_VARIABLE,
-             NO_CLASS, BT_UNKNOWN, 0, GFC_STD_F2003,
+             CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_F2003,
              NULL, NULL, gfc_resolve_get_environment_variable,
              name, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
              val, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
              NULL, NULL, gfc_resolve_get_environment_variable,
              name, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
              val, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT,
@@ -2781,10 +3249,11 @@ add_subroutines (void)
              st, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
              trim_name, BT_LOGICAL, dl, OPTIONAL, INTENT_IN);
 
              st, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
              trim_name, BT_LOGICAL, dl, OPTIONAL, INTENT_IN);
 
-  add_sym_2s_intent ("move_alloc", GFC_ISYM_MOVE_ALLOC, NO_CLASS, BT_UNKNOWN, 0,
-                    GFC_STD_F2003, gfc_check_move_alloc, NULL, NULL,
-                    f, BT_UNKNOWN, 0, REQUIRED, INTENT_INOUT,
-                    t, BT_UNKNOWN, 0, REQUIRED, INTENT_OUT);
+  add_sym_2s ("move_alloc", GFC_ISYM_MOVE_ALLOC, CLASS_PURE, BT_UNKNOWN, 0,
+             GFC_STD_F2003,
+             gfc_check_move_alloc, NULL, NULL,
+             f, BT_UNKNOWN, 0, REQUIRED, INTENT_INOUT,
+             t, BT_UNKNOWN, 0, REQUIRED, INTENT_OUT);
 
   add_sym_5s ("mvbits", GFC_ISYM_MVBITS, CLASS_ELEMENTAL, BT_UNKNOWN, 0,
              GFC_STD_F95, gfc_check_mvbits, gfc_simplify_mvbits,
 
   add_sym_5s ("mvbits", GFC_ISYM_MVBITS, CLASS_ELEMENTAL, BT_UNKNOWN, 0,
              GFC_STD_F95, gfc_check_mvbits, gfc_simplify_mvbits,
@@ -2795,144 +3264,232 @@ add_subroutines (void)
              t, BT_INTEGER, di, REQUIRED, INTENT_INOUT,
              tp, BT_INTEGER, di, REQUIRED, INTENT_IN);
 
              t, BT_INTEGER, di, REQUIRED, INTENT_INOUT,
              tp, BT_INTEGER, di, REQUIRED, INTENT_IN);
 
-  add_sym_1s_intent ("random_number", GFC_ISYM_RANDOM_NUMBER, NO_CLASS,
-                    BT_UNKNOWN, 0, GFC_STD_F95, gfc_check_random_number, NULL,
-                    gfc_resolve_random_number,
-                    h, BT_REAL, dr, REQUIRED, INTENT_OUT);
+  add_sym_1s ("random_number", GFC_ISYM_RANDOM_NUMBER, CLASS_IMPURE,
+             BT_UNKNOWN, 0, GFC_STD_F95,
+             gfc_check_random_number, NULL, gfc_resolve_random_number,
+             h, BT_REAL, dr, REQUIRED, INTENT_OUT);
+
+  add_sym_3s ("random_seed", GFC_ISYM_RANDOM_SEED, CLASS_IMPURE,
+             BT_UNKNOWN, 0, GFC_STD_F95,
+             gfc_check_random_seed, NULL, gfc_resolve_random_seed,
+             sz, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+             pt, BT_INTEGER, di, OPTIONAL, INTENT_IN,
+             gt, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  /* The following subroutines are part of ISO_C_BINDING.  */
+
+  add_sym_3s ("c_f_pointer", GFC_ISYM_C_F_POINTER, CLASS_IMPURE, BT_UNKNOWN, 0,
+             GFC_STD_F2003, gfc_check_c_f_pointer, NULL, NULL,
+             "cptr", BT_VOID, 0, REQUIRED, INTENT_IN,
+             "fptr", BT_UNKNOWN, 0, REQUIRED, INTENT_OUT,
+             "shape", BT_INTEGER, di, OPTIONAL, INTENT_IN);
+  make_from_module();
+
+  add_sym_2s ("c_f_procpointer", GFC_ISYM_C_F_PROCPOINTER, CLASS_IMPURE,
+             BT_UNKNOWN, 0, GFC_STD_F2003, gfc_check_c_f_procpointer,
+             NULL, NULL,
+             "cptr", BT_VOID, 0, REQUIRED, INTENT_IN,
+             "fptr", BT_UNKNOWN, 0, REQUIRED, INTENT_OUT);
+  make_from_module();
+
+  /* Coarray collectives.  */
+  add_sym_4s ("co_broadcast", GFC_ISYM_CO_BROADCAST, CLASS_IMPURE,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_co_broadcast, NULL, NULL,
+             a, BT_REAL, dr, REQUIRED, INTENT_INOUT,
+             "source_image", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+             errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT);
+
+  add_sym_4s ("co_max", GFC_ISYM_CO_MAX, CLASS_IMPURE,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_co_minmax, NULL, NULL,
+             a, BT_REAL, dr, REQUIRED, INTENT_INOUT,
+             result_image, BT_INTEGER, di, OPTIONAL, INTENT_IN,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+             errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT);
+
+  add_sym_4s ("co_min", GFC_ISYM_CO_MIN, CLASS_IMPURE,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_co_minmax, NULL, NULL,
+             a, BT_REAL, dr, REQUIRED, INTENT_INOUT,
+             result_image, BT_INTEGER, di, OPTIONAL, INTENT_IN,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+             errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT);
+
+  add_sym_4s ("co_sum", GFC_ISYM_CO_SUM, CLASS_IMPURE,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_co_sum, NULL, NULL,
+             a, BT_REAL, dr, REQUIRED, INTENT_INOUT,
+             result_image, BT_INTEGER, di, OPTIONAL, INTENT_IN,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+             errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT);
+
+  add_sym_5s ("co_reduce", GFC_ISYM_CO_REDUCE, CLASS_IMPURE,
+             BT_UNKNOWN, 0, GFC_STD_F2008_TS,
+             gfc_check_co_reduce, NULL, NULL,
+             a, BT_REAL, dr, REQUIRED, INTENT_INOUT,
+             "operator", BT_INTEGER, di, REQUIRED, INTENT_IN,
+             result_image, BT_INTEGER, di, OPTIONAL, INTENT_IN,
+             stat, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+             errmsg, BT_CHARACTER, dc, OPTIONAL, INTENT_OUT);
+
+
+  /* The following subroutine is internally used for coarray libray functions.
+     "make_from_module" makes it inaccessible for external users.  */
+  add_sym_2s (GFC_PREFIX ("caf_send"), GFC_ISYM_CAF_SEND, CLASS_IMPURE,
+             BT_UNKNOWN, 0, GFC_STD_GNU, NULL, NULL, NULL,
+             "x", BT_REAL, dr, REQUIRED, INTENT_OUT,
+             "y", BT_REAL, dr, REQUIRED, INTENT_IN);
+  make_from_module();
 
 
-  add_sym_3s_intent ("random_seed", GFC_ISYM_RANDOM_SEED, NO_CLASS,
-                    BT_UNKNOWN, 0, GFC_STD_F95,
-                    gfc_check_random_seed, NULL, gfc_resolve_random_seed,
-                    sz, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
-                    pt, BT_INTEGER, di, OPTIONAL, INTENT_IN,
-                    gt, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
   /* More G77 compatibility garbage.  */
 
   /* More G77 compatibility garbage.  */
-  add_sym_3s ("alarm", GFC_ISYM_ALARM, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_3s ("alarm", GFC_ISYM_ALARM, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_alarm_sub, NULL, gfc_resolve_alarm_sub,
              gfc_check_alarm_sub, NULL, gfc_resolve_alarm_sub,
-             sec, BT_INTEGER, di, REQUIRED, han, BT_UNKNOWN, 0, REQUIRED,
-             st, BT_INTEGER, di, OPTIONAL);
+             sec, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             han, BT_UNKNOWN, 0, REQUIRED, INTENT_IN,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_1s ("srand", GFC_ISYM_SRAND, NO_CLASS, BT_UNKNOWN, di, GFC_STD_GNU,
-             gfc_check_srand, NULL, gfc_resolve_srand,
-             "seed", BT_INTEGER, 4, REQUIRED);
+  add_sym_1s ("srand", GFC_ISYM_SRAND, CLASS_IMPURE, BT_UNKNOWN,
+             di, GFC_STD_GNU, gfc_check_srand, NULL, gfc_resolve_srand,
+             "seed", BT_INTEGER, 4, REQUIRED, INTENT_IN);
 
 
-  add_sym_1s ("exit", GFC_ISYM_EXIT, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_1s ("exit", GFC_ISYM_EXIT, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_exit, NULL, gfc_resolve_exit,
              gfc_check_exit, NULL, gfc_resolve_exit,
-             st, BT_INTEGER, di, OPTIONAL);
+             st, BT_INTEGER, di, OPTIONAL, INTENT_IN);
 
   make_noreturn();
 
 
   make_noreturn();
 
-  add_sym_3s ("fgetc", GFC_ISYM_FGETC, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_3s ("fgetc", GFC_ISYM_FGETC, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_fgetputc_sub, NULL, gfc_resolve_fgetc_sub,
              gfc_check_fgetputc_sub, NULL, gfc_resolve_fgetc_sub,
-             ut, BT_INTEGER, di, REQUIRED, c, BT_CHARACTER, dc, REQUIRED,
-             st, BT_INTEGER, di, OPTIONAL);
+             ut, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             c, BT_CHARACTER, dc, REQUIRED, INTENT_OUT,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_2s ("fget", GFC_ISYM_FGET, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_2s ("fget", GFC_ISYM_FGET, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_fgetput_sub, NULL, gfc_resolve_fget_sub,
              gfc_check_fgetput_sub, NULL, gfc_resolve_fget_sub,
-             c, BT_CHARACTER, dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
+             c, BT_CHARACTER, dc, REQUIRED, INTENT_OUT,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_1s ("flush", GFC_ISYM_FLUSH, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_1s ("flush", GFC_ISYM_FLUSH, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_flush, NULL, gfc_resolve_flush,
              gfc_check_flush, NULL, gfc_resolve_flush,
-             ut, BT_INTEGER, di, OPTIONAL);
+             ut, BT_INTEGER, di, OPTIONAL, INTENT_IN);
 
 
-  add_sym_3s ("fputc", GFC_ISYM_FPUTC, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_3s ("fputc", GFC_ISYM_FPUTC, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_fgetputc_sub, NULL, gfc_resolve_fputc_sub,
              gfc_check_fgetputc_sub, NULL, gfc_resolve_fputc_sub,
-             ut, BT_INTEGER, di, REQUIRED, c, BT_CHARACTER, dc, REQUIRED,
-             st, BT_INTEGER, di, OPTIONAL);
+             ut, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             c, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_2s ("fput", GFC_ISYM_FPUT, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_2s ("fput", GFC_ISYM_FPUT, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_fgetput_sub, NULL, gfc_resolve_fput_sub,
              gfc_check_fgetput_sub, NULL, gfc_resolve_fput_sub,
-             c, BT_CHARACTER, dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
+             c, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_1s ("free", GFC_ISYM_FREE, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_1s ("free", GFC_ISYM_FREE, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_free, NULL, gfc_resolve_free,
              gfc_check_free, NULL, gfc_resolve_free,
-             ptr, BT_INTEGER, ii, REQUIRED);
+             ptr, BT_INTEGER, ii, REQUIRED, INTENT_INOUT);
 
 
-  add_sym_4s ("fseek", GFC_ISYM_FSEEK, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-              gfc_check_fseek_sub, NULL, gfc_resolve_fseek_sub,
-              ut, BT_INTEGER, di, REQUIRED, INTENT_IN,
+  add_sym_4s ("fseek", GFC_ISYM_FSEEK, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
+             gfc_check_fseek_sub, NULL, gfc_resolve_fseek_sub,
+             ut, BT_INTEGER, di, REQUIRED, INTENT_IN,
              of, BT_INTEGER, di, REQUIRED, INTENT_IN,
              of, BT_INTEGER, di, REQUIRED, INTENT_IN,
-              whence, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             whence, BT_INTEGER, di, REQUIRED, INTENT_IN,
              st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
              st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
-  add_sym_2s ("ftell", GFC_ISYM_FTELL, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_2s ("ftell", GFC_ISYM_FTELL, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_ftell_sub, NULL, gfc_resolve_ftell_sub,
              gfc_check_ftell_sub, NULL, gfc_resolve_ftell_sub,
-             ut, BT_INTEGER, di, REQUIRED, of, BT_INTEGER, ii, REQUIRED);
+             ut, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             of, BT_INTEGER, ii, REQUIRED, INTENT_OUT);
 
 
-  add_sym_2s ("hostnm", GFC_ISYM_HOSTNM, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_hostnm_sub, NULL, gfc_resolve_hostnm_sub,
-             c, BT_CHARACTER, dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
+  add_sym_2s ("hostnm", GFC_ISYM_HOSTNM, CLASS_IMPURE, BT_UNKNOWN, 0,
+             GFC_STD_GNU, gfc_check_hostnm_sub, NULL, gfc_resolve_hostnm_sub,
+             c, BT_CHARACTER, dc, REQUIRED, INTENT_OUT,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_3s ("kill", GFC_ISYM_KILL, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU, gfc_check_kill_sub,
-             NULL, gfc_resolve_kill_sub, c, BT_INTEGER, di, REQUIRED,
-             val, BT_INTEGER, di, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
+  add_sym_3s ("kill", GFC_ISYM_KILL, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
+             gfc_check_kill_sub, NULL, gfc_resolve_kill_sub,
+             c, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             val, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_3s ("link", GFC_ISYM_LINK, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_3s ("link", GFC_ISYM_LINK, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_link_sub, NULL, gfc_resolve_link_sub,
              gfc_check_link_sub, NULL, gfc_resolve_link_sub,
-             p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER,
-             dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
+             p1, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             p2, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_1s ("perror", GFC_ISYM_PERROR, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_perror, NULL, gfc_resolve_perror,
-             "string", BT_CHARACTER, dc, REQUIRED);
+  add_sym_1s ("perror", GFC_ISYM_PERROR, CLASS_IMPURE, BT_UNKNOWN,
+             0, GFC_STD_GNU, gfc_check_perror, NULL, gfc_resolve_perror,
+             "string", BT_CHARACTER, dc, REQUIRED, INTENT_IN);
 
 
-  add_sym_3s ("rename", GFC_ISYM_RENAME, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_rename_sub, NULL, gfc_resolve_rename_sub,
-             p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER,
-             dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
+  add_sym_3s ("rename", GFC_ISYM_RENAME, CLASS_IMPURE, BT_UNKNOWN, 0,
+             GFC_STD_GNU, gfc_check_rename_sub, NULL, gfc_resolve_rename_sub,
+             p1, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             p2, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_1s ("sleep", GFC_ISYM_SLEEP, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_1s ("sleep", GFC_ISYM_SLEEP, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_sleep_sub, NULL, gfc_resolve_sleep_sub,
              gfc_check_sleep_sub, NULL, gfc_resolve_sleep_sub,
-             sec, BT_INTEGER, di, REQUIRED);
+             sec, BT_INTEGER, di, REQUIRED, INTENT_IN);
 
 
-  add_sym_3s ("fstat", GFC_ISYM_FSTAT, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_3s ("fstat", GFC_ISYM_FSTAT, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_fstat_sub, NULL, gfc_resolve_fstat_sub,
              gfc_check_fstat_sub, NULL, gfc_resolve_fstat_sub,
-             ut, BT_INTEGER, di, REQUIRED, vl, BT_INTEGER, di, REQUIRED,
-             st, BT_INTEGER, di, OPTIONAL);
+             ut, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             vl, BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_3s ("lstat", GFC_ISYM_LSTAT, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_3s ("lstat", GFC_ISYM_LSTAT, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_stat_sub, NULL, gfc_resolve_lstat_sub,
              gfc_check_stat_sub, NULL, gfc_resolve_lstat_sub,
-             name, BT_CHARACTER, dc, REQUIRED, vl, BT_INTEGER, di, REQUIRED,
-             st, BT_INTEGER, di, OPTIONAL);
+             name, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             vl, BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_3s ("stat", GFC_ISYM_STAT, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+  add_sym_3s ("stat", GFC_ISYM_STAT, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_stat_sub, NULL, gfc_resolve_stat_sub,
              gfc_check_stat_sub, NULL, gfc_resolve_stat_sub,
-             name, BT_CHARACTER, dc, REQUIRED, vl, BT_INTEGER, di, REQUIRED,
-             st, BT_INTEGER, di, OPTIONAL);
-
-  add_sym_3s ("signal", GFC_ISYM_SIGNAL, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_signal_sub, NULL, gfc_resolve_signal_sub,
-             num, BT_INTEGER, di, REQUIRED, han, BT_UNKNOWN, 0, REQUIRED,
-             st, BT_INTEGER, di, OPTIONAL);
-
-  add_sym_3s ("symlnk", GFC_ISYM_SYMLINK, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_symlnk_sub, NULL, gfc_resolve_symlnk_sub,
-             p1, BT_CHARACTER, dc, REQUIRED, p2, BT_CHARACTER,
-             dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
-
-  add_sym_2s ("system", GFC_ISYM_SYSTEM, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             NULL, NULL, gfc_resolve_system_sub,
-             com, BT_CHARACTER, dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
-
-  add_sym_3s_intent ("system_clock", GFC_ISYM_SYSTEM_CLOCK, NO_CLASS,
-                    BT_UNKNOWN, 0, GFC_STD_F95,
-                    gfc_check_system_clock, NULL, gfc_resolve_system_clock,
-                    c, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
-                    cr, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
-                    cm, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
-
-  add_sym_2s ("ttynam", GFC_ISYM_TTYNAM, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_ttynam_sub, NULL, gfc_resolve_ttynam_sub,
-             ut, BT_INTEGER, di, REQUIRED, name, BT_CHARACTER, dc, REQUIRED);
-
-  add_sym_2s ("umask", GFC_ISYM_UMASK, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
+             name, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             vl, BT_INTEGER, di, REQUIRED, INTENT_OUT,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_3s ("signal", GFC_ISYM_SIGNAL, CLASS_IMPURE, BT_UNKNOWN, 0,
+             GFC_STD_GNU, gfc_check_signal_sub, NULL, gfc_resolve_signal_sub,
+             num, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             han, BT_UNKNOWN, 0, REQUIRED, INTENT_IN,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_3s ("symlnk", GFC_ISYM_SYMLINK, CLASS_IMPURE, BT_UNKNOWN, 0,
+             GFC_STD_GNU, gfc_check_symlnk_sub, NULL, gfc_resolve_symlnk_sub,
+             p1, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             p2, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_2s ("system", GFC_ISYM_SYSTEM, CLASS_IMPURE, BT_UNKNOWN,
+             0, GFC_STD_GNU, NULL, NULL, gfc_resolve_system_sub,
+             com, BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_3s ("system_clock", GFC_ISYM_SYSTEM_CLOCK, CLASS_IMPURE,
+             BT_UNKNOWN, 0, GFC_STD_F95,
+             gfc_check_system_clock, NULL, gfc_resolve_system_clock,
+             c, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+             cr, BT_INTEGER, di, OPTIONAL, INTENT_OUT,
+             cm, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
+
+  add_sym_2s ("ttynam", GFC_ISYM_TTYNAM, CLASS_IMPURE, BT_UNKNOWN, 0,
+             GFC_STD_GNU, gfc_check_ttynam_sub, NULL, gfc_resolve_ttynam_sub,
+             ut, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             name, BT_CHARACTER, dc, REQUIRED, INTENT_OUT);
+
+  add_sym_2s ("umask", GFC_ISYM_UMASK, CLASS_IMPURE, BT_UNKNOWN, 0, GFC_STD_GNU,
              gfc_check_umask_sub, NULL, gfc_resolve_umask_sub,
              gfc_check_umask_sub, NULL, gfc_resolve_umask_sub,
-             msk, BT_INTEGER, di, REQUIRED, old, BT_INTEGER, di, OPTIONAL);
+             msk, BT_INTEGER, di, REQUIRED, INTENT_IN,
+             old, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 
 
-  add_sym_2s ("unlink", GFC_ISYM_UNLINK, NO_CLASS, BT_UNKNOWN, 0, GFC_STD_GNU,
-             gfc_check_unlink_sub, NULL, gfc_resolve_unlink_sub,
-             "path", BT_CHARACTER, dc, REQUIRED, st, BT_INTEGER, di, OPTIONAL);
+  add_sym_2s ("unlink", GFC_ISYM_UNLINK, CLASS_IMPURE, BT_UNKNOWN, 0,
+             GFC_STD_GNU, gfc_check_unlink_sub, NULL, gfc_resolve_unlink_sub,
+             "path", BT_CHARACTER, dc, REQUIRED, INTENT_IN,
+             st, BT_INTEGER, di, OPTIONAL, INTENT_OUT);
 }
 
 
 }
 
 
@@ -2965,6 +3522,7 @@ add_conv (bt from_type, int from_kind, bt to_type, int to_kind, int standard)
   sym->simplify.cc = gfc_convert_constant;
   sym->standard = standard;
   sym->elemental = 1;
   sym->simplify.cc = gfc_convert_constant;
   sym->standard = standard;
   sym->elemental = 1;
+  sym->pure = 1;
   sym->conversion = 1;
   sym->ts = to;
   sym->id = GFC_ISYM_CONVERSION;
   sym->conversion = 1;
   sym->ts = to;
   sym->id = GFC_ISYM_CONVERSION;
@@ -3115,6 +3673,7 @@ add_char_conversions (void)
        char_conversions[n].simplify.cc = gfc_convert_char_constant;
        char_conversions[n].standard = GFC_STD_F2003;
        char_conversions[n].elemental = 1;
        char_conversions[n].simplify.cc = gfc_convert_char_constant;
        char_conversions[n].standard = GFC_STD_F2003;
        char_conversions[n].elemental = 1;
+       char_conversions[n].pure = 1;
        char_conversions[n].conversion = 0;
        char_conversions[n].ts = to;
        char_conversions[n].id = GFC_ISYM_CONVERSION;
        char_conversions[n].conversion = 0;
        char_conversions[n].ts = to;
        char_conversions[n].id = GFC_ISYM_CONVERSION;
@@ -3128,8 +3687,6 @@ add_char_conversions (void)
 void
 gfc_intrinsic_init_1 (void)
 {
 void
 gfc_intrinsic_init_1 (void)
 {
-  int i;
-
   nargs = nfunc = nsub = nconv = 0;
 
   /* Create a namespace to hold the resolved intrinsic symbols.  */
   nargs = nfunc = nsub = nconv = 0;
 
   /* Create a namespace to hold the resolved intrinsic symbols.  */
@@ -3162,24 +3719,15 @@ gfc_intrinsic_init_1 (void)
 
   /* Character conversion intrinsics need to be treated separately.  */
   add_char_conversions ();
 
   /* Character conversion intrinsics need to be treated separately.  */
   add_char_conversions ();
-
-  /* Set the pure flag.  All intrinsic functions are pure, and
-     intrinsic subroutines are pure if they are elemental.  */
-
-  for (i = 0; i < nfunc; i++)
-    functions[i].pure = 1;
-
-  for (i = 0; i < nsub; i++)
-    subroutines[i].pure = subroutines[i].elemental;
 }
 
 
 void
 gfc_intrinsic_done_1 (void)
 {
 }
 
 
 void
 gfc_intrinsic_done_1 (void)
 {
-  gfc_free (functions);
-  gfc_free (conversion);
-  gfc_free (char_conversions);
+  free (functions);
+  free (conversion);
+  free (char_conversions);
   gfc_free_namespace (gfc_intrinsic_namespace);
 }
 
   gfc_free_namespace (gfc_intrinsic_namespace);
 }
 
@@ -3227,9 +3775,9 @@ remove_nullargs (gfc_actual_arglist **ap)
    with the format arglist.  Arguments that are not present are given
    a blank gfc_actual_arglist structure.  If something is obviously
    wrong (say, a missing required argument) we abort sorting and
    with the format arglist.  Arguments that are not present are given
    a blank gfc_actual_arglist structure.  If something is obviously
    wrong (say, a missing required argument) we abort sorting and
-   return FAILURE.  */
+   return false.  */
 
 
-static gfc_try
+static bool
 sort_actual (const char *name, gfc_actual_arglist **ap,
             gfc_intrinsic_arg *formal, locus *where)
 {
 sort_actual (const char *name, gfc_actual_arglist **ap,
             gfc_intrinsic_arg *formal, locus *where)
 {
@@ -3246,7 +3794,7 @@ sort_actual (const char *name, gfc_actual_arglist **ap,
   a = actual;
 
   if (f == NULL && a == NULL)  /* No arguments */
   a = actual;
 
   if (f == NULL && a == NULL)  /* No arguments */
-    return SUCCESS;
+    return true;
 
   for (;;)
     {          /* Put the nonkeyword arguments in a 1:1 correspondence */
 
   for (;;)
     {          /* Put the nonkeyword arguments in a 1:1 correspondence */
@@ -3268,7 +3816,7 @@ sort_actual (const char *name, gfc_actual_arglist **ap,
     goto do_sort;
 
   gfc_error ("Too many arguments in call to '%s' at %L", name, where);
     goto do_sort;
 
   gfc_error ("Too many arguments in call to '%s' at %L", name, where);
-  return FAILURE;
+  return false;
 
 keywords:
   /* Associate the remaining actual arguments, all of which have
 
 keywords:
   /* Associate the remaining actual arguments, all of which have
@@ -3287,14 +3835,14 @@ keywords:
          else
            gfc_error ("Can't find keyword named '%s' in call to '%s' at %L",
                       a->name, name, where);
          else
            gfc_error ("Can't find keyword named '%s' in call to '%s' at %L",
                       a->name, name, where);
-         return FAILURE;
+         return false;
        }
 
       if (f->actual != NULL)
        {
          gfc_error ("Argument '%s' appears twice in call to '%s' at %L",
                     f->name, name, where);
        }
 
       if (f->actual != NULL)
        {
          gfc_error ("Argument '%s' appears twice in call to '%s' at %L",
                     f->name, name, where);
-         return FAILURE;
+         return false;
        }
 
       f->actual = a;
        }
 
       f->actual = a;
@@ -3308,7 +3856,7 @@ optional:
        {
          gfc_error ("Missing actual argument '%s' in call to '%s' at %L",
                     f->name, name, where);
        {
          gfc_error ("Missing actual argument '%s' in call to '%s' at %L",
                     f->name, name, where);
-         return FAILURE;
+         return false;
        }
     }
 
        }
     }
 
@@ -3322,7 +3870,7 @@ do_sort:
       if (f->actual && f->actual->label != NULL && f->ts.type)
        {
          gfc_error ("ALTERNATE RETURN not permitted at %L", where);
       if (f->actual && f->actual->label != NULL && f->ts.type)
        {
          gfc_error ("ALTERNATE RETURN not permitted at %L", where);
-         return FAILURE;
+         return false;
        }
 
       if (f->actual == NULL)
        }
 
       if (f->actual == NULL)
@@ -3342,7 +3890,7 @@ do_sort:
     }
   actual->next = NULL;         /* End the sorted argument list.  */
 
     }
   actual->next = NULL;         /* End the sorted argument list.  */
 
-  return SUCCESS;
+  return true;
 }
 
 
 }
 
 
@@ -3350,7 +3898,7 @@ do_sort:
    list.  The lists are checked for agreement of type.  We don't check
    for arrayness here.  */
 
    list.  The lists are checked for agreement of type.  We don't check
    for arrayness here.  */
 
-static gfc_try
+static bool
 check_arglist (gfc_actual_arglist **ap, gfc_intrinsic_sym *sym,
               int error_flag)
 {
 check_arglist (gfc_actual_arglist **ap, gfc_intrinsic_sym *sym,
               int error_flag)
 {
@@ -3379,15 +3927,27 @@ check_arglist (gfc_actual_arglist **ap, gfc_intrinsic_sym *sym,
        {
          if (error_flag)
            gfc_error ("Type of argument '%s' in call to '%s' at %L should "
        {
          if (error_flag)
            gfc_error ("Type of argument '%s' in call to '%s' at %L should "
-                      "be %s, not %s", gfc_current_intrinsic_arg[i],
+                      "be %s, not %s", gfc_current_intrinsic_arg[i]->name,
                       gfc_current_intrinsic, &actual->expr->where,
                       gfc_typename (&formal->ts),
                       gfc_typename (&actual->expr->ts));
                       gfc_current_intrinsic, &actual->expr->where,
                       gfc_typename (&formal->ts),
                       gfc_typename (&actual->expr->ts));
-         return FAILURE;
+         return false;
+       }
+
+      /* If the formal argument is INTENT([IN]OUT), check for definability.  */
+      if (formal->intent == INTENT_INOUT || formal->intent == INTENT_OUT)
+       {
+         const char* context = (error_flag
+                                ? _("actual argument to INTENT = OUT/INOUT")
+                                : NULL);
+
+         /* No pointer arguments for intrinsics.  */
+         if (!gfc_check_vardef_context (actual->expr, false, false, false, context))
+           return false;
        }
     }
 
        }
     }
 
-  return SUCCESS;
+  return true;
 }
 
 
 }
 
 
@@ -3478,11 +4038,11 @@ resolve_intrinsic (gfc_intrinsic_sym *specific, gfc_expr *e)
 
 /* Given an intrinsic symbol node and an expression node, call the
    simplification function (if there is one), perhaps replacing the
 
 /* Given an intrinsic symbol node and an expression node, call the
    simplification function (if there is one), perhaps replacing the
-   expression with something simpler.  We return FAILURE on an error
-   of the simplification, SUCCESS if the simplification worked, even
+   expression with something simpler.  We return false on an error
+   of the simplification, true if the simplification worked, even
    if nothing has changed in the expression itself.  */
 
    if nothing has changed in the expression itself.  */
 
-static gfc_try
+static bool
 do_simplify (gfc_intrinsic_sym *specific, gfc_expr *e)
 {
   gfc_expr *result, *a1, *a2, *a3, *a4, *a5;
 do_simplify (gfc_intrinsic_sym *specific, gfc_expr *e)
 {
   gfc_expr *result, *a1, *a2, *a3, *a4, *a5;
@@ -3566,7 +4126,7 @@ do_simplify (gfc_intrinsic_sym *specific, gfc_expr *e)
 
 finish:
   if (result == &gfc_bad_expr)
 
 finish:
   if (result == &gfc_bad_expr)
-    return FAILURE;
+    return false;
 
   if (result == NULL)
     resolve_intrinsic (specific, e);   /* Must call at run-time */
 
   if (result == NULL)
     resolve_intrinsic (specific, e);   /* Must call at run-time */
@@ -3576,12 +4136,12 @@ finish:
       gfc_replace_expr (e, result);
     }
 
       gfc_replace_expr (e, result);
     }
 
-  return SUCCESS;
+  return true;
 }
 
 
 /* Initialize the gfc_current_intrinsic_arg[] array for the benefit of
 }
 
 
 /* Initialize the gfc_current_intrinsic_arg[] array for the benefit of
-   error messages.  This subroutine returns FAILURE if a subroutine
+   error messages.  This subroutine returns false if a subroutine
    has more than MAX_INTRINSIC_ARGS, in which case the actual argument
    list cannot match any intrinsic.  */
 
    has more than MAX_INTRINSIC_ARGS, in which case the actual argument
    list cannot match any intrinsic.  */
 
@@ -3598,21 +4158,21 @@ init_arglist (gfc_intrinsic_sym *isym)
     {
       if (i >= MAX_INTRINSIC_ARGS)
        gfc_internal_error ("init_arglist(): too many arguments");
     {
       if (i >= MAX_INTRINSIC_ARGS)
        gfc_internal_error ("init_arglist(): too many arguments");
-      gfc_current_intrinsic_arg[i++] = formal->name;
+      gfc_current_intrinsic_arg[i++] = formal;
     }
 }
 
 
 /* Given a pointer to an intrinsic symbol and an expression consisting
    of a function call, see if the function call is consistent with the
     }
 }
 
 
 /* Given a pointer to an intrinsic symbol and an expression consisting
    of a function call, see if the function call is consistent with the
-   intrinsic's formal argument list.  Return SUCCESS if the expression
-   and intrinsic match, FAILURE otherwise.  */
+   intrinsic's formal argument list.  Return true if the expression
+   and intrinsic match, false otherwise.  */
 
 
-static gfc_try
+static bool
 check_specific (gfc_intrinsic_sym *specific, gfc_expr *expr, int error_flag)
 {
   gfc_actual_arglist *arg, **ap;
 check_specific (gfc_intrinsic_sym *specific, gfc_expr *expr, int error_flag)
 {
   gfc_actual_arglist *arg, **ap;
-  gfc_try t;
+  bool t;
 
   ap = &expr->value.function.actual;
 
 
   ap = &expr->value.function.actual;
 
@@ -3623,11 +4183,17 @@ check_specific (gfc_intrinsic_sym *specific, gfc_expr *expr, int error_flag)
       || specific->check.f1m == gfc_check_min_max_integer
       || specific->check.f1m == gfc_check_min_max_real
       || specific->check.f1m == gfc_check_min_max_double)
       || specific->check.f1m == gfc_check_min_max_integer
       || specific->check.f1m == gfc_check_min_max_real
       || specific->check.f1m == gfc_check_min_max_double)
-    return (*specific->check.f1m) (*ap);
+    {
+      if (!do_ts29113_check (specific, *ap))
+       return false;
+      return (*specific->check.f1m) (*ap);
+    }
+
+  if (!sort_actual (specific->name, ap, specific->formal, &expr->where))
+    return false;
 
 
-  if (sort_actual (specific->name, ap, specific->formal,
-                  &expr->where) == FAILURE)
-    return FAILURE;
+  if (!do_ts29113_check (specific, *ap))
+    return false;
 
   if (specific->check.f3ml == gfc_check_minloc_maxloc)
     /* This is special because we might have to reorder the argument list.  */
 
   if (specific->check.f3ml == gfc_check_minloc_maxloc)
     /* This is special because we might have to reorder the argument list.  */
@@ -3640,12 +4206,15 @@ check_specific (gfc_intrinsic_sym *specific, gfc_expr *expr, int error_flag)
     /* Same here. The difference to the previous case is that we allow a
        general numeric type.  */
     t = gfc_check_product_sum (*ap);
     /* Same here. The difference to the previous case is that we allow a
        general numeric type.  */
     t = gfc_check_product_sum (*ap);
+  else if (specific->check.f3red == gfc_check_transf_bit_intrins)
+    /* Same as for PRODUCT and SUM, but different checks.  */
+    t = gfc_check_transf_bit_intrins (*ap);
   else
      {
        if (specific->check.f1 == NULL)
         {
           t = check_arglist (ap, specific, error_flag);
   else
      {
        if (specific->check.f1 == NULL)
         {
           t = check_arglist (ap, specific, error_flag);
-          if (t == SUCCESS)
+          if (t)
             expr->ts = specific->ts;
         }
        else
             expr->ts = specific->ts;
         }
        else
@@ -3653,7 +4222,7 @@ check_specific (gfc_intrinsic_sym *specific, gfc_expr *expr, int error_flag)
      }
 
   /* Check conformance of elemental intrinsics.  */
      }
 
   /* Check conformance of elemental intrinsics.  */
-  if (t == SUCCESS && specific->elemental)
+  if (t && specific->elemental)
     {
       int n = 0;
       gfc_expr *first_expr;
     {
       int n = 0;
       gfc_expr *first_expr;
@@ -3664,16 +4233,16 @@ check_specific (gfc_intrinsic_sym *specific, gfc_expr *expr, int error_flag)
       first_expr = arg->expr;
 
       for ( ; arg && arg->expr; arg = arg->next, n++)
       first_expr = arg->expr;
 
       for ( ; arg && arg->expr; arg = arg->next, n++)
-       if (gfc_check_conformance (first_expr, arg->expr,
-                                  "arguments '%s' and '%s' for "
-                                  "intrinsic '%s'",
-                                  gfc_current_intrinsic_arg[0],
-                                  gfc_current_intrinsic_arg[n],
-                                  gfc_current_intrinsic) == FAILURE)
-         return FAILURE;
+       if (!gfc_check_conformance (first_expr, arg->expr, 
+                                   "arguments '%s' and '%s' for "
+                                   "intrinsic '%s'", 
+                                   gfc_current_intrinsic_arg[0]->name, 
+                                   gfc_current_intrinsic_arg[n]->name, 
+                                   gfc_current_intrinsic))
+         return false;
     }
 
     }
 
-  if (t == FAILURE)
+  if (!t)
     remove_nullargs (ap);
 
   return t;
     remove_nullargs (ap);
 
   return t;
@@ -3686,9 +4255,9 @@ check_specific (gfc_intrinsic_sym *specific, gfc_expr *expr, int error_flag)
    textual representation of the symbols standard status (like
    "new in Fortran 2008", "a GNU extension" or "obsolescent in Fortran 95") that
    can be used to construct a detailed warning/error message in case of
    textual representation of the symbols standard status (like
    "new in Fortran 2008", "a GNU extension" or "obsolescent in Fortran 95") that
    can be used to construct a detailed warning/error message in case of
-   a FAILURE.  */
+   a false.  */
 
 
-gfc_try
+bool
 gfc_check_intrinsic_standard (const gfc_intrinsic_sym* isym,
                              const char** symstd, bool silent, locus where)
 {
 gfc_check_intrinsic_standard (const gfc_intrinsic_sym* isym,
                              const char** symstd, bool silent, locus where)
 {
@@ -3696,7 +4265,7 @@ gfc_check_intrinsic_standard (const gfc_intrinsic_sym* isym,
 
   /* For -fall-intrinsics, just succeed.  */
   if (gfc_option.flag_all_intrinsics)
 
   /* For -fall-intrinsics, just succeed.  */
   if (gfc_option.flag_all_intrinsics)
-    return SUCCESS;
+    return true;
 
   /* Find the symbol's standard message for later usage.  */
   switch (isym->standard)
 
   /* Find the symbol's standard message for later usage.  */
   switch (isym->standard)
@@ -3725,6 +4294,10 @@ gfc_check_intrinsic_standard (const gfc_intrinsic_sym* isym,
       symstd_msg = "new in Fortran 2008";
       break;
 
       symstd_msg = "new in Fortran 2008";
       break;
 
+    case GFC_STD_F2008_TS:
+      symstd_msg = "new in TS 29113/TS 18508";
+      break;
+
     case GFC_STD_GNU:
       symstd_msg = "a GNU Fortran extension";
       break;
     case GFC_STD_GNU:
       symstd_msg = "a GNU Fortran extension";
       break;
@@ -3734,7 +4307,7 @@ gfc_check_intrinsic_standard (const gfc_intrinsic_sym* isym,
       break;
 
     default:
       break;
 
     default:
-      gfc_internal_error ("Invalid standard code on intrinsic '%s' (%d)",
+      gfc_internal_error ("Invalid standard code on intrinsic %qs (%d)",
                          isym->name, isym->standard);
     }
 
                          isym->name, isym->standard);
     }
 
@@ -3746,17 +4319,17 @@ gfc_check_intrinsic_standard (const gfc_intrinsic_sym* isym,
        gfc_warning ("Intrinsic '%s' (is %s) is used at %L",
                     isym->name, _(symstd_msg), &where);
 
        gfc_warning ("Intrinsic '%s' (is %s) is used at %L",
                     isym->name, _(symstd_msg), &where);
 
-      return SUCCESS;
+      return true;
     }
 
   /* If allowing the symbol's standard, succeed, too.  */
   if (gfc_option.allow_std & isym->standard)
     }
 
   /* If allowing the symbol's standard, succeed, too.  */
   if (gfc_option.allow_std & isym->standard)
-    return SUCCESS;
+    return true;
 
   /* Otherwise, fail.  */
   if (symstd)
     *symstd = _(symstd_msg);
 
   /* Otherwise, fail.  */
   if (symstd)
     *symstd = _(symstd_msg);
-  return FAILURE;
+  return false;
 }
 
 
 }
 
 
@@ -3782,7 +4355,7 @@ gfc_intrinsic_func_interface (gfc_expr *expr, int error_flag)
   int flag;
 
   if (expr->value.function.isym != NULL)
   int flag;
 
   if (expr->value.function.isym != NULL)
-    return (do_simplify (expr->value.function.isym, expr) == FAILURE)
+    return (!do_simplify(expr->value.function.isym, expr))
           ? MATCH_ERROR : MATCH_YES;
 
   if (!error_flag)
           ? MATCH_ERROR : MATCH_YES;
 
   if (!error_flag)
@@ -3796,7 +4369,14 @@ gfc_intrinsic_func_interface (gfc_expr *expr, int error_flag)
 
   name = expr->symtree->n.sym->name;
 
 
   name = expr->symtree->n.sym->name;
 
-  isym = specific = gfc_find_function (name);
+  if (expr->symtree->n.sym->intmod_sym_id)
+    {
+      gfc_isym_id id = gfc_isym_id_by_intmod_sym (expr->symtree->n.sym);
+      isym = specific = gfc_intrinsic_function_by_id (id);
+    }
+  else
+    isym = specific = gfc_find_function (name);
+
   if (isym == NULL)
     {
       if (!error_flag)
   if (isym == NULL)
     {
       if (!error_flag)
@@ -3806,10 +4386,9 @@ 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)
 
   if ((isym->id == GFC_ISYM_REAL || isym->id == GFC_ISYM_DBLE
        || isym->id == GFC_ISYM_CMPLX)
-      && gfc_init_expr
-      && gfc_notify_std (GFC_STD_F2003, "Fortran 2003: Function '%s' "
-                        "as initialization expression at %L", name,
-                        &expr->where) == FAILURE)
+      && gfc_init_expr_flag
+      && !gfc_notify_std (GFC_STD_F2003, "Function '%s' as initialization "
+                         "expression at %L", name, &expr->where))
     {
       if (!error_flag)
        gfc_pop_suppress_errors ();
     {
       if (!error_flag)
        gfc_pop_suppress_errors ();
@@ -3818,12 +4397,12 @@ gfc_intrinsic_func_interface (gfc_expr *expr, int error_flag)
 
   gfc_current_intrinsic_where = &expr->where;
 
 
   gfc_current_intrinsic_where = &expr->where;
 
-  /* Bypass the generic list for min and max.  */
+  /* Bypass the generic list for min, max and ISO_C_Binding's c_loc.  */
   if (isym->check.f1m == gfc_check_min_max)
     {
       init_arglist (isym);
 
   if (isym->check.f1m == gfc_check_min_max)
     {
       init_arglist (isym);
 
-      if (gfc_check_min_max (expr->value.function.actual) == SUCCESS)
+      if (isym->check.f1m(expr->value.function.actual))
        goto got_specific;
 
       if (!error_flag)
        goto got_specific;
 
       if (!error_flag)
@@ -3844,7 +4423,7 @@ gfc_intrinsic_func_interface (gfc_expr *expr, int error_flag)
        {
          if (specific == isym)
            continue;
        {
          if (specific == isym)
            continue;
-         if (check_specific (specific, expr, 0) == SUCCESS)
+         if (check_specific (specific, expr, 0))
            {
              gfc_pop_suppress_errors ();
              goto got_specific;
            {
              gfc_pop_suppress_errors ();
              goto got_specific;
@@ -3854,7 +4433,7 @@ gfc_intrinsic_func_interface (gfc_expr *expr, int error_flag)
 
   gfc_pop_suppress_errors ();
 
 
   gfc_pop_suppress_errors ();
 
-  if (check_specific (isym, expr, error_flag) == FAILURE)
+  if (!check_specific (isym, expr, error_flag))
     {
       if (!error_flag)
        gfc_pop_suppress_errors ();
     {
       if (!error_flag)
        gfc_pop_suppress_errors ();
@@ -3865,12 +4444,13 @@ gfc_intrinsic_func_interface (gfc_expr *expr, int error_flag)
 
 got_specific:
   expr->value.function.isym = specific;
 
 got_specific:
   expr->value.function.isym = specific;
-  gfc_intrinsic_symbol (expr->symtree->n.sym);
+  if (!expr->symtree->n.sym->module)
+    gfc_intrinsic_symbol (expr->symtree->n.sym);
 
   if (!error_flag)
     gfc_pop_suppress_errors ();
 
 
   if (!error_flag)
     gfc_pop_suppress_errors ();
 
-  if (do_simplify (specific, expr) == FAILURE)
+  if (!do_simplify (specific, expr))
     return MATCH_ERROR;
 
   /* F95, 7.1.6.1, Initialization expressions
     return MATCH_ERROR;
 
   /* F95, 7.1.6.1, Initialization expressions
@@ -3882,10 +4462,10 @@ got_specific:
      (4)   A reference to an elemental standard intrinsic function,
            where each argument is an initialization expression  */
 
      (4)   A reference to an elemental standard intrinsic function,
            where each argument is an initialization expression  */
 
-  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)
+  if (gfc_init_expr_flag && isym->elemental && flag
+      && !gfc_notify_std (GFC_STD_F2003, "Elemental function as "
+                         "initialization expression with non-integer/non-"
+                         "character arguments at %L", &expr->where))
     return MATCH_ERROR;
 
   return MATCH_YES;
     return MATCH_ERROR;
 
   return MATCH_YES;
@@ -3905,7 +4485,14 @@ gfc_intrinsic_sub_interface (gfc_code *c, int error_flag)
 
   name = c->symtree->n.sym->name;
 
 
   name = c->symtree->n.sym->name;
 
-  isym = gfc_find_subroutine (name);
+  if (c->symtree->n.sym->intmod_sym_id)
+    {
+      gfc_isym_id id;
+      id = gfc_isym_id_by_intmod_sym (c->symtree->n.sym);
+      isym = gfc_intrinsic_subroutine_by_id (id);
+    }
+  else
+    isym = gfc_find_subroutine (name);
   if (isym == NULL)
     return MATCH_NO;
 
   if (isym == NULL)
     return MATCH_NO;
 
@@ -3914,17 +4501,20 @@ gfc_intrinsic_sub_interface (gfc_code *c, int error_flag)
 
   init_arglist (isym);
 
 
   init_arglist (isym);
 
-  if (sort_actual (name, &c->ext.actual, isym->formal, &c->loc) == FAILURE)
+  if (!sort_actual (name, &c->ext.actual, isym->formal, &c->loc))
+    goto fail;
+
+  if (!do_ts29113_check (isym, c->ext.actual))
     goto fail;
 
   if (isym->check.f1 != NULL)
     {
     goto fail;
 
   if (isym->check.f1 != NULL)
     {
-      if (do_check (isym, c->ext.actual) == FAILURE)
+      if (!do_check (isym, c->ext.actual))
        goto fail;
     }
   else
     {
        goto fail;
     }
   else
     {
-      if (check_arglist (&c->ext.actual, isym, 1) == FAILURE)
+      if (!check_arglist (&c->ext.actual, isym, 1))
        goto fail;
     }
 
        goto fail;
     }
 
@@ -3942,13 +4532,23 @@ gfc_intrinsic_sub_interface (gfc_code *c, int error_flag)
       c->resolved_sym->attr.elemental = isym->elemental;
     }
 
       c->resolved_sym->attr.elemental = isym->elemental;
     }
 
-  if (gfc_pure (NULL) && !isym->elemental)
+  if (gfc_do_concurrent_flag && !isym->pure)
+    {
+      gfc_error ("Subroutine call to intrinsic '%s' in DO CONCURRENT "
+                "block at %L is not PURE", name, &c->loc);
+      return MATCH_ERROR;
+    }
+
+  if (!isym->pure && gfc_pure (NULL))
     {
       gfc_error ("Subroutine call to intrinsic '%s' at %L is not PURE", name,
                 &c->loc);
       return MATCH_ERROR;
     }
 
     {
       gfc_error ("Subroutine call to intrinsic '%s' at %L is not PURE", name,
                 &c->loc);
       return MATCH_ERROR;
     }
 
+  if (!isym->pure)
+    gfc_unset_implicit_pure (NULL);
+
   c->resolved_sym->attr.noreturn = isym->noreturn;
 
   return MATCH_YES;
   c->resolved_sym->attr.noreturn = isym->noreturn;
 
   return MATCH_YES;
@@ -3962,7 +4562,7 @@ fail:
 
 /* Call gfc_convert_type() with warning enabled.  */
 
 
 /* Call gfc_convert_type() with warning enabled.  */
 
-gfc_try
+bool
 gfc_convert_type (gfc_expr *expr, gfc_typespec *ts, int eflag)
 {
   return gfc_convert_type_warn (expr, ts, eflag, 1);
 gfc_convert_type (gfc_expr *expr, gfc_typespec *ts, int eflag)
 {
   return gfc_convert_type_warn (expr, ts, eflag, 1);
@@ -3979,7 +4579,7 @@ gfc_convert_type (gfc_expr *expr, gfc_typespec *ts, int eflag)
 
    'wflag' controls the warning related to conversion.  */
 
 
    'wflag' controls the warning related to conversion.  */
 
-gfc_try
+bool
 gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
 {
   gfc_intrinsic_sym *sym;
 gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
 {
   gfc_intrinsic_sym *sym;
@@ -4000,7 +4600,7 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
     {
       /* Sometimes the RHS acquire the type.  */
       expr->ts = *ts;
     {
       /* Sometimes the RHS acquire the type.  */
       expr->ts = *ts;
-      return SUCCESS;
+      return true;
     }
 
   if (expr->ts.type == BT_UNKNOWN)
     }
 
   if (expr->ts.type == BT_UNKNOWN)
@@ -4008,7 +4608,7 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
 
   if (expr->ts.type == BT_DERIVED && ts->type == BT_DERIVED
       && gfc_compare_types (&expr->ts, ts))
 
   if (expr->ts.type == BT_DERIVED && ts->type == BT_DERIVED
       && gfc_compare_types (&expr->ts, ts))
-    return SUCCESS;
+    return true;
 
   sym = find_conv (&expr->ts, ts);
   if (sym == NULL)
 
   sym = find_conv (&expr->ts, ts);
   if (sym == NULL)
@@ -4016,11 +4616,74 @@ 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)
 
   /* 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 && gfc_option.warn_conversion)
-    gfc_warning_now ("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)
+    {
+      if (gfc_option.flag_range_check
+         && expr->expr_type == EXPR_CONSTANT
+         && from_ts.type == ts->type)
+       {
+         /* Do nothing. Constants of the same type are range-checked
+            elsewhere. If a value too large for the target type is
+            assigned, an error is generated. Not checking here avoids
+            duplications of warnings/errors.
+            If range checking was disabled, but -Wconversion enabled,
+            a non range checked warning is generated below.  */
+       }
+      else if (from_ts.type == BT_LOGICAL || ts->type == BT_LOGICAL)
+       {
+         /* Do nothing. This block exists only to simplify the other
+            else-if expressions.
+              LOGICAL <> LOGICAL    no warning, independent of kind values
+              LOGICAL <> INTEGER    extension, warned elsewhere
+              LOGICAL <> REAL       invalid, error generated elsewhere
+              LOGICAL <> COMPLEX    invalid, error generated elsewhere  */
+       }
+      else if (from_ts.type == ts->type
+              || (from_ts.type == BT_INTEGER && ts->type == BT_REAL)
+              || (from_ts.type == BT_INTEGER && ts->type == BT_COMPLEX)
+              || (from_ts.type == BT_REAL && ts->type == BT_COMPLEX))
+       {
+         /* Larger kinds can hold values of smaller kinds without problems.
+            Hence, only warn if target kind is smaller than the source
+            kind - or if -Wconversion-extra is specified.  */
+         if (warn_conversion && from_ts.kind > ts->kind)
+           gfc_warning_now (OPT_Wconversion, "Possible change of value in "
+                            "conversion from %s to %s at %L",
+                            gfc_typename (&from_ts), gfc_typename (ts),
+                            &expr->where);
+         else if (warn_conversion_extra)
+           gfc_warning_now (OPT_Wconversion_extra, "Conversion from %s to %s "
+                            "at %L", gfc_typename (&from_ts),
+                            gfc_typename (ts), &expr->where);
+       }
+      else if ((from_ts.type == BT_REAL && ts->type == BT_INTEGER)
+              || (from_ts.type == BT_COMPLEX && ts->type == BT_INTEGER)
+              || (from_ts.type == BT_COMPLEX && ts->type == BT_REAL))
+       {
+         /* Conversion from REAL/COMPLEX to INTEGER or COMPLEX to REAL
+            usually comes with a loss of information, regardless of kinds.  */
+         if (warn_conversion)
+           gfc_warning_now (OPT_Wconversion, "Possible change of value in "
+                            "conversion from %s to %s at %L",
+                            gfc_typename (&from_ts), gfc_typename (ts),
+                            &expr->where);
+       }
+      else if (from_ts.type == BT_HOLLERITH || ts->type == BT_HOLLERITH)
+       {
+         /* If HOLLERITH is involved, all bets are off.  */
+         if (warn_conversion)
+           gfc_warning_now (OPT_Wconversion, "Conversion from %s to %s at %L",
+                            gfc_typename (&from_ts), gfc_typename (ts),
+                            &expr->where);
+       }
+      else
+        gcc_unreachable ();
+    }
 
   /* Insert a pre-resolved function call to the right function.  */
   old_where = expr->where;
 
   /* Insert a pre-resolved function call to the right function.  */
   old_where = expr->where;
@@ -4050,36 +4713,36 @@ gfc_convert_type_warn (gfc_expr *expr, gfc_typespec *ts, int eflag, int wflag)
 
   *expr = *new_expr;
 
 
   *expr = *new_expr;
 
-  gfc_free (new_expr);
+  free (new_expr);
   expr->ts = *ts;
 
   if (gfc_is_constant_expr (expr->value.function.actual->expr)
   expr->ts = *ts;
 
   if (gfc_is_constant_expr (expr->value.function.actual->expr)
-      && do_simplify (sym, expr) == FAILURE)
+      && !do_simplify (sym, expr))
     {
 
       if (eflag == 2)
        goto bad;
     {
 
       if (eflag == 2)
        goto bad;
-      return FAILURE;          /* Error already generated in do_simplify() */
+      return false;            /* Error already generated in do_simplify() */
     }
 
     }
 
-  return SUCCESS;
+  return true;
 
 bad:
   if (eflag == 1)
     {
       gfc_error ("Can't convert %s to %s at %L",
                 gfc_typename (&from_ts), gfc_typename (ts), &expr->where);
 
 bad:
   if (eflag == 1)
     {
       gfc_error ("Can't convert %s to %s at %L",
                 gfc_typename (&from_ts), gfc_typename (ts), &expr->where);
-      return FAILURE;
+      return false;
     }
 
     }
 
-  gfc_internal_error ("Can't convert %s to %s at %L",
+  gfc_internal_error ("Can't convert %qs to %qs at %L",
                      gfc_typename (&from_ts), gfc_typename (ts),
                      &expr->where);
   /* Not reached */
 }
 
 
                      gfc_typename (&from_ts), gfc_typename (ts),
                      &expr->where);
   /* Not reached */
 }
 
 
-gfc_try
+bool
 gfc_convert_chartype (gfc_expr *expr, gfc_typespec *ts)
 {
   gfc_intrinsic_sym *sym;
 gfc_convert_chartype (gfc_expr *expr, gfc_typespec *ts)
 {
   gfc_intrinsic_sym *sym;
@@ -4119,17 +4782,17 @@ gfc_convert_chartype (gfc_expr *expr, gfc_typespec *ts)
 
   *expr = *new_expr;
 
 
   *expr = *new_expr;
 
-  gfc_free (new_expr);
+  free (new_expr);
   expr->ts = *ts;
 
   if (gfc_is_constant_expr (expr->value.function.actual->expr)
   expr->ts = *ts;
 
   if (gfc_is_constant_expr (expr->value.function.actual->expr)
-      && do_simplify (sym, expr) == FAILURE)
+      && !do_simplify (sym, expr))
     {
       /* Error already generated in do_simplify() */
     {
       /* Error already generated in do_simplify() */
-      return FAILURE;
+      return false;
     }
 
     }
 
-  return SUCCESS;
+  return true;
 }
 
 
 }
 
 
@@ -4144,7 +4807,7 @@ gfc_warn_intrinsic_shadow (const gfc_symbol* sym, bool in_module, bool func)
   gfc_intrinsic_sym* isym;
 
   /* If the warning is disabled, do nothing at all.  */
   gfc_intrinsic_sym* isym;
 
   /* If the warning is disabled, do nothing at all.  */
-  if (!gfc_option.warn_intrinsic_shadow)
+  if (!warn_intrinsic_shadow)
     return;
 
   /* Try to find an intrinsic of the same name.  */
     return;
 
   /* Try to find an intrinsic of the same name.  */
@@ -4155,12 +4818,12 @@ gfc_warn_intrinsic_shadow (const gfc_symbol* sym, bool in_module, bool func)
 
   /* If no intrinsic was found with this name or it's not included in the
      selected standard, everything's fine.  */
 
   /* If no intrinsic was found with this name or it's not included in the
      selected standard, everything's fine.  */
-  if (!isym || gfc_check_intrinsic_standard (isym, NULL, true,
-                                            sym->declared_at) == FAILURE)
+  if (!isym || !gfc_check_intrinsic_standard (isym, NULL, true, 
+                                             sym->declared_at))
     return;
 
   /* Emit the warning.  */
     return;
 
   /* Emit the warning.  */
-  if (in_module)
+  if (in_module || sym->ns->proc_name)
     gfc_warning ("'%s' declared at %L may shadow the intrinsic of the same"
                 " name.  In order to call the intrinsic, explicit INTRINSIC"
                 " declarations may be required.",
     gfc_warning ("'%s' declared at %L may shadow the intrinsic of the same"
                 " name.  In order to call the intrinsic, explicit INTRINSIC"
                 " declarations may be required.",