Index: gcc/fortran/interface.c
===================================================================
--- gcc/fortran/interface.c	(revision 197540)
+++ gcc/fortran/interface.c	(working copy)
@@ -3205,6 +3205,14 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arg
 			 "at %L", &a->expr->where);
 	      return FAILURE;
 	    }
+
+	  /* F08:12.4.2.2 (2e).  */
+	  if (a->expr && a->expr->ts.type == BT_CLASS)
+	    {
+	      gfc_error ("Polymorphic argument requires an explicit interface "
+			 "at %L", &a->expr->where);
+	      return FAILURE;
+	    }
 	}
 
       return SUCCESS;
Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 197540)
+++ gcc/fortran/resolve.c	(working copy)
@@ -2231,7 +2231,8 @@ resolve_global_procedure (gfc_symbol *sym, locus *
       if (def_sym->formal && sym->attr.if_source != IFSRC_IFBODY)
 	{
 	  gfc_formal_arglist *arg = def_sym->formal;
-	  for ( ; arg; arg = arg->next)
+	  gfc_actual_arglist *aarg = (*actual);
+	  for ( ; arg; arg = arg->next, aarg ? aarg = aarg->next : NULL)
 	    if (!arg->sym)
 	      continue;
 	    /* F2003, 12.3.1.1 (2a); F2008, 12.4.2.2 (2a)  */
@@ -2284,8 +2285,11 @@ resolve_global_procedure (gfc_symbol *sym, locus *
 			   arg->sym->name);
 		break;
 	      }
-	    /* F2003, 12.3.1.1 (2d); F2008, 12.4.2.2 (2e)   */
-	    else if (arg->sym->ts.type == BT_CLASS)
+	    /* F2003, 12.3.1.1 (2d); F2008, 12.4.2.2 (2e).
+	       Here we exclude polymorphic actual arguments, because they are
+	       caught by gfc_procedure_use.  */
+	    else if (arg->sym->ts.type == BT_CLASS
+		     && !(aarg && aarg->expr->ts.type == BT_CLASS))
 	      {
 		gfc_error ("Procedure '%s' at %L with polymorphic dummy "
 			   "argument '%s' must have an explicit interface",
Index: gcc/testsuite/gfortran.dg/abstract_type_6.f03
===================================================================
--- gcc/testsuite/gfortran.dg/abstract_type_6.f03	(revision 197540)
+++ gcc/testsuite/gfortran.dg/abstract_type_6.f03	(working copy)
@@ -46,7 +46,7 @@ END SUBROUTINE bottom_b
 
 SUBROUTINE bottom_c(obj)
    CLASS(Bottom) :: obj
-   CALL top_c(obj)
+   CALL top_c(obj)   ! { dg-error "requires an explicit interface" }
    ! other stuff
 END SUBROUTINE bottom_c 
 end module
Index: gcc/testsuite/gfortran.dg/whole_file_20.f03
===================================================================
--- gcc/testsuite/gfortran.dg/whole_file_20.f03	(revision 197540)
+++ gcc/testsuite/gfortran.dg/whole_file_20.f03	(working copy)
@@ -13,12 +13,15 @@ END MODULE
 
 PROGRAM main
   USE classtype
-  CLASS(t), POINTER :: tt
+  CLASS(t), POINTER :: cls
+  TYPE(t), POINTER :: tp
 
   INTEGER :: coarr[*]
 
   CALL coarray(coarr)         ! { dg-error " must have an explicit interface" }
-  CALL polymorph(tt)          ! { dg-error " must have an explicit interface" }
+
+  CALL polymorph(tp)          ! { dg-error "must have an explicit interface" }
+  CALL polymorph(cls)         ! { dg-error "requires an explicit interface" }
 END PROGRAM
 
 SUBROUTINE coarray(a)
