diff mbox series

[fortran] Fix PR 70260, ICE on invalid

Message ID 9814033f-e255-349b-b4e6-67b8a2f1f82e@netcologne.de
State New
Headers show
Series [fortran] Fix PR 70260, ICE on invalid | expand

Commit Message

Thomas Koenig Nov. 11, 2018, 3:59 p.m. UTC
Hello world,

the attached patch fixes both ICEs in the PR by adding some tests.
It was necessary to shuffle around a bit of code, plus to make sure that
double error reporting did not become too bad.

Regression-tested. OK for trunk?

Regards

	Thomas


2018-11-11  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/70260
	* expr.c (gfc_check_assign): Reject assigning to an external
	symbol.
	(gfc_check_pointer_assign): Add suppress_type_test
	argument. Insert line after if. A non-proc pointer can not point
	to a constant.  Only check types if suppress_type_test is false.
	* gfortran.h (gfc_check_pointer_assign): Add optional
	suppress_type_test argument.
	* resolve.c (gfc_resolve_code):  Move up gfc_check_pointer_assign
	and give it the extra argument.
	(resolve_fl_procedure): Set error on value for a function with
	an inizializer.

2018-11-11  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/70260
	* gfortran.dg/proc_ptr_result_5.f90:  Add dg-error directive.
	* gfortran.dg/protected_4.f90: Split line to allow for extra error.
	* gfortran.dg/protected_6.f90: Likewise.
	* gfortran.dg/assign_11.f90: New test.
	* gfortran.dg/pointer_assign_12.f90: New test.

Comments

Thomas Koenig Nov. 17, 2018, 3:10 p.m. UTC | #1
Hi,

> the attached patch fixes both ICEs in the PR by adding some tests.
> It was necessary to shuffle around a bit of code, plus to make sure that
> double error reporting did not become too bad.
> 
> Regression-tested. OK for trunk?

Ping?

Regards

	Thomas
Jerry DeLisle Nov. 17, 2018, 4:03 p.m. UTC | #2
On 11/11/18 7:59 AM, Thomas Koenig wrote:
> Hello world,
> 
> the attached patch fixes both ICEs in the PR by adding some tests.
> It was necessary to shuffle around a bit of code, plus to make sure that
> double error reporting did not become too bad.
> 
> Regression-tested. OK for trunk?
> 
> Regards
> 
>      Thomas
> 

On vacation in Florida for a few days with Grandkids.

Looks Good To Me. OK

Jerry
Paul Richard Thomas Nov. 17, 2018, 4:22 p.m. UTC | #3
Hi Thomas,

OK for trunk.

Thanks for working on it.

Paul

On Sat, 17 Nov 2018 at 15:10, Thomas Koenig <tkoenig@netcologne.de> wrote:
>
> Hi,
>
> > the attached patch fixes both ICEs in the PR by adding some tests.
> > It was necessary to shuffle around a bit of code, plus to make sure that
> > double error reporting did not become too bad.
> >
> > Regression-tested. OK for trunk?
>
> Ping?
>
> Regards
>
>         Thomas
Thomas Koenig Nov. 18, 2018, 9:17 a.m. UTC | #4
Hi Paul1

> OK for trunk.
> 
> Thanks for working on it.


Committed as r266248.

Thanks for the review!

Regards

	Thomas
diff mbox series

Patch

Index: fortran/expr.c
===================================================================
--- fortran/expr.c	(Revision 265732)
+++ fortran/expr.c	(Arbeitskopie)
@@ -3507,6 +3507,18 @@  gfc_check_assign (gfc_expr *lvalue, gfc_expr *rval
 	  return false;
 	}
     }
+  else
+    {
+      /* Reject assigning to an external symbol.  For initializers, this
+	 was already done before, in resolve_fl_procedure.  */
+      if (sym->attr.flavor == FL_PROCEDURE && sym->attr.external
+	  && sym->attr.proc != PROC_MODULE && !rvalue->error)
+	{
+	  gfc_error ("Illegal assignment to external procedure at %L",
+		     &lvalue->where);
+	  return false;
+	}
+    }
 
   if (rvalue->rank != 0 && lvalue->rank != rvalue->rank)
     {
@@ -3643,7 +3655,8 @@  gfc_check_assign (gfc_expr *lvalue, gfc_expr *rval
    NULLIFY statement.  */
 
 bool
-gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue)
+gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue,
+			  bool suppress_type_test)
 {
   symbol_attribute attr, lhs_attr;
   gfc_ref *ref;
@@ -3771,6 +3784,7 @@  bool
 		     &rvalue->where);
 	  return false;
 	}
+
       if (rvalue->expr_type == EXPR_VARIABLE && !attr.proc_pointer)
 	{
       	  /* Check for intrinsics.  */
@@ -3967,6 +3981,16 @@  bool
 
       return true;
     }
+  else
+    {
+      /* A non-proc pointer cannot point to a constant.  */
+      if (rvalue->expr_type == EXPR_CONSTANT)
+	{
+	  gfc_error_now ("Pointer assignment target cannot be a constant at %L",
+			 &rvalue->where);
+	  return false;
+	}
+    }
 
   if (!gfc_compare_types (&lvalue->ts, &rvalue->ts))
     {
@@ -3980,7 +4004,7 @@  bool
 		   "polymorphic, or of a type with the BIND or SEQUENCE "
 		   "attribute, to be compatible with an unlimited "
 		   "polymorphic target", &lvalue->where);
-      else
+      else if (!suppress_type_test)
 	gfc_error ("Different types in pointer assignment at %L; "
 		   "attempted assignment of %s to %s", &lvalue->where,
 		   gfc_typename (&rvalue->ts),
Index: fortran/gfortran.h
===================================================================
--- fortran/gfortran.h	(Revision 265732)
+++ fortran/gfortran.h	(Arbeitskopie)
@@ -3219,7 +3219,8 @@  int gfc_kind_max (gfc_expr *, gfc_expr *);
 
 bool gfc_check_conformance (gfc_expr *, gfc_expr *, const char *, ...) ATTRIBUTE_PRINTF_3;
 bool gfc_check_assign (gfc_expr *, gfc_expr *, int, bool c = true);
-bool gfc_check_pointer_assign (gfc_expr *, gfc_expr *);
+bool gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue,
+  bool suppres_type_test = false);
 bool gfc_check_assign_symbol (gfc_symbol *, gfc_component *, gfc_expr *);
 
 gfc_expr *gfc_build_default_init_expr (gfc_typespec *, locus *);
Index: fortran/resolve.c
===================================================================
--- fortran/resolve.c	(Revision 265732)
+++ fortran/resolve.c	(Arbeitskopie)
@@ -11420,11 +11420,12 @@  start:
 	      t = gfc_check_vardef_context (e, false, false, false,
 					    _("pointer assignment"));
 	    gfc_free_expr (e);
+
+	    t = gfc_check_pointer_assign (code->expr1, code->expr2, !t) && t;
+
 	    if (!t)
 	      break;
 
-	    gfc_check_pointer_assign (code->expr1, code->expr2);
-
 	    /* Assigning a class object always is a regular assign.  */
 	    if (code->expr2->ts.type == BT_CLASS
 		&& code->expr1->ts.type == BT_CLASS
@@ -12540,6 +12541,9 @@  resolve_fl_procedure (gfc_symbol *sym, int mp_flag
     {
       gfc_error ("Function %qs at %L cannot have an initializer",
 		 sym->name, &sym->declared_at);
+
+      /* Make sure no second error is issued for this.  */
+      sym->value->error = 1;
       return false;
     }
 
Index: testsuite/gfortran.dg/proc_ptr_result_5.f90
===================================================================
--- testsuite/gfortran.dg/proc_ptr_result_5.f90	(Revision 265732)
+++ testsuite/gfortran.dg/proc_ptr_result_5.f90	(Arbeitskopie)
@@ -14,6 +14,6 @@  contains
      logical(1) function f()
      end function
    end interface
-   f = .true._1
+   f = .true._1 ! { dg-error "Illegal assignment" }
  end function f
 end program test
Index: testsuite/gfortran.dg/protected_4.f90
===================================================================
--- testsuite/gfortran.dg/protected_4.f90	(Revision 265732)
+++ testsuite/gfortran.dg/protected_4.f90	(Arbeitskopie)
@@ -26,7 +26,8 @@  program main
   a = 43       ! { dg-error "variable definition context" }
   ap => null() ! { dg-error "pointer association context" }
   nullify(ap)  ! { dg-error "pointer association context" }
-  ap => at     ! { dg-error "pointer association context" }
+  ap => &      ! { dg-error "pointer association context" }
+       & at    ! { dg-error "Pointer assignment target has PROTECTED attribute" }
   ap = 3       ! OK
   allocate(ap) ! { dg-error "pointer association context" }
   ap = 73      ! OK
Index: testsuite/gfortran.dg/protected_6.f90
===================================================================
--- testsuite/gfortran.dg/protected_6.f90	(Revision 265732)
+++ testsuite/gfortran.dg/protected_6.f90	(Arbeitskopie)
@@ -22,7 +22,8 @@  program main
   a = 43       ! { dg-error "variable definition context" }
   ap => null() ! { dg-error "pointer association context" }
   nullify(ap)  ! { dg-error "pointer association context" }
-  ap => at     ! { dg-error "pointer association context" }
+  ap => &      ! { dg-error "pointer association context" }
+       & at    ! { dg-error "Pointer assignment target has PROTECTED attribute" }
   ap = 3       ! OK
   allocate(ap) ! { dg-error "pointer association context" }
   ap = 73      ! OK