Re: [Patch, Fortran] PR40881 - Add two F95 obsolescence warnings

2012-08-14 Thread Tobias Burnus

On 08/09/2012 02:13 PM, Mikael Morin wrote:

On 08/08/2012 19:12, Tobias Burnus wrote:

With this patch, I think the only unimplemented obsolescence warning is for
(8) Fixed form source -- see B.2.7.

For the latter, I would like to see a possibility to silence that
warning, given that there is substantial code around, which is in fixed
form but otherwise a completely valid and obsolescent-free code.

We could silence it with explicit -ffixed-form.


That won't work. The driver (gfortran) automatically adds the flag 
when compiling .f files. Thus, from within the compile (f951) those 
are indistinguishable. Besides, many Makefiles have the same compiler 
flags for fixed and free form as (most) compilers automatically choose 
the right source form based on the file extension.



Regarding the general design, I'm not sure it makes sense to distinguish 
between ST_LABEL_DO_TARGET and ST_LABEL_ENDDO_TARGET.


I concur. I changed it and also added a comment to gfortran.h.


@@ -3825,8 +3828,11 @@ parse_executable (gfc_statement st)
case ST_NONE:
  unexpected_eof ();
  
-	case ST_FORMAT:

case ST_DATA:
+ gfc_notify_std (GFC_STD_F95_OBS, DATA statement at %C after the 
+  first executable statement);
+ /* Fall through.  */
+   case ST_FORMAT:
case ST_ENTRY:
case_executable:
  accept_statement (st);

This diagnostic is more appropriate in verify_st_order (which needs to
be called then).


I disagree. Initially, I thought that verify_st_order is the right place 
- and discovered then that it doesn't get called after the first 
executable statement. Thus, I added it to parse_executable.


Given that DATA is the only statement, which can also occur in the 
execution section and that its validity depends on the compile flags, it 
also would need a special handling in verify_st_order.


Calling verify_st_order from parse_executable only for ST_DATA is kind 
of pointless while calling it always, leads to quite some overhead, 
requires that one keeps track of the previous state (which is required 
by verify_st_order but otherwise not needed in the execution section).


Thus, I really prefer the current solution.


case ST_LABEL_TARGET:
+   case ST_LABEL_ENDDO_TARGET:
  if (lp-referenced == ST_LABEL_FORMAT)
gfc_error (Label %d at %C already referenced as a format label,
   labelno);
  else
lp-defined = ST_LABEL_TARGET;

I think it should be `lp-defined = type;' here.


I think the current code is okay due to the required ordering, e.g. the 
termination label for a DO block has to come after the DO block. But I 
concur that using = type is cleaner.


Thus, I removed ST_LABEL_ENDDO_TARGET, use =type and added a comment, 
but I didn't do the verify_st_order change.


Build and regested on x86-64-linux.
OK for the trunk?

Tobias
2012-08-14  Tobias Burnus  bur...@net-b.de

	PR fortran/40881
	* error.c (gfc_notify_std): Reset cur_error_buffer-flag flag
	when the error/warning has been printed.
	* gfortran.h (gfc_sl_type): Add ST_LABEL_DO_TARGET.
	* match.c (gfc_match_do): Use ST_LABEL_DO_TARGET.
	* parse.c (check_statement_label): Use ST_LABEL_DO_TARGET.
	(parse_executable): Add obsolescence check for DATA.
	* resolve.c (resolve_branch): Handle ST_LABEL_DO_TARGET.
	* symbol.c (gfc_define_st_label, gfc_reference_st_label):
	Add obsolescence diagnostics.
	* trans-stmt.c (gfc_trans_label_assign): Handle ST_LABEL_DO_TARGET.

2012-08-14  Tobias Burnus  bur...@net-b.de

	PR fortran/40881
	* gfortran.dg/data_constraints_3.f90: New.
	* gfortran.dg/data_constraints_1.f90: Update dg-warning.
	* gfortran.dg/pr37243.f: Ditto.
	* gfortran.dg/g77/19990826-3.f: Ditto.
	* gfortran.dg/g77/20020307-1.f : Ditto.
	* gfortran.dg/g77/980310-3.f: Ditto.

diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
index 7e968db..dde6a0f 100644
--- a/gcc/fortran/error.c
+++ b/gcc/fortran/error.c
@@ -875,6 +875,7 @@ gfc_notify_std (int std, const char *gmsgid, ...)
 	warnings++;
   else
 	gfc_increment_error_count();
+  cur_error_buffer-flag = 0;
 }
 
   return (warning  !warnings_are_errors) ? SUCCESS : FAILURE;
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index b6e2975..0e2130f 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -144,9 +144,11 @@ typedef enum
 { AR_FULL = 1, AR_ELEMENT, AR_SECTION, AR_UNKNOWN }
 ar_type;
 
-/* Statement label types.  */
+/* Statement label types. ST_LABEL_DO_TARGET is used for obsolescent warnings
+   related to shared DO terminations and DO targets which are neither END DO
+   nor CONTINUE; otherwise it is identical to ST_LABEL_TARGET.  */
 typedef enum
-{ ST_LABEL_UNKNOWN = 1, ST_LABEL_TARGET,
+{ ST_LABEL_UNKNOWN = 1, ST_LABEL_TARGET, ST_LABEL_DO_TARGET,
   ST_LABEL_BAD_TARGET, ST_LABEL_FORMAT
 }
 gfc_sl_type;
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 737d6a3..5ab07e5 100644
--- 

Re: [Patch, Fortran] PR40881 - Add two F95 obsolescence warnings

2012-08-14 Thread Mikael Morin
On 14/08/2012 11:33, Tobias Burnus wrote:
 Thus, I removed ST_LABEL_ENDDO_TARGET, use =type and added a comment,
 but I didn't do the verify_st_order change.
 
 Build and regested on x86-64-linux.
 OK for the trunk?
 
OK, apart for:

* gfortran.dg/data_constraints_1.f90: Update dg-warning.

I don't see the need for the change, the ChangeLog doesn't match the
patch, and it is different from the initial version. A forgotten local edit?

Thanks,

Mikael


Re: [Patch, Fortran] PR40881 - Add two F95 obsolescence warnings

2012-08-14 Thread Tobias Burnus

On 08/14/2012 11:57 AM, Mikael Morin wrote:

On 14/08/2012 11:33, Tobias Burnus wrote:

Thus, I removed ST_LABEL_ENDDO_TARGET, use =type and added a comment,
but I didn't do the verify_st_order change.

Build and regested on x86-64-linux.
OK for the trunk?


OK, apart for:
* gfortran.dg/data_constraints_1.f90: Update dg-warning.
I don't see the need for the change, the ChangeLog doesn't match the
patch, and it is different from the initial version. A forgotten local edit?


No, just the wrong (?) solution to a real issue. The -pedantic flag 
causes the obsolescent warning. To avoid it, one can either remove the 
allocate or one uses

  ! { dg-options  }
I think the latter is cleaner.

I will commit the patch with the latter and a fixed ChangeLog.

Tobias


Re: [Patch, Fortran] PR40881 - Add two F95 obsolescence warnings

2012-08-09 Thread Mikael Morin
On 08/08/2012 19:12, Tobias Burnus wrote:
 With this patch, I think the only unimplemented obsolescence warning is for
 (8) Fixed form source -- see B.2.7.
 
 For the latter, I would like to see a possibility to silence that
 warning, given that there is substantial code around, which is in fixed
 form but otherwise a completely valid and obsolescent-free code.

We could silence it with explicit -ffixed-form.

 
 The motivation for implementing this patch was that I did a small
 obsolescent cleanup of our fixed-form code (which uses some Fortran 2003
 features) and I realized that ifort had the shared DO termination
 warning and gfortran didn't.
 
 Build and regtested on x86-64-gnu-linux.
 OK for the trunk?

More comments below. Regarding the general design, I'm not sure it makes
sense to distinguish between ST_LABEL_DO_TARGET and
ST_LABEL_ENDDO_TARGET. There are no ST_LABEL_GOTO_TARGET or
ST_LABEL_WRITE_TARGET after all.



 diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
 index b6e2975..9670022 100644
 --- a/gcc/fortran/gfortran.h
 +++ b/gcc/fortran/gfortran.h
 @@ -146,8 +146,8 @@ ar_type;
  
  /* Statement label types.  */
  typedef enum
 -{ ST_LABEL_UNKNOWN = 1, ST_LABEL_TARGET,
 -  ST_LABEL_BAD_TARGET, ST_LABEL_FORMAT
 +{ ST_LABEL_UNKNOWN = 1, ST_LABEL_TARGET, ST_LABEL_DO_TARGET,
 +  ST_LABEL_ENDDO_TARGET, ST_LABEL_BAD_TARGET, ST_LABEL_FORMAT
  }
  gfc_sl_type;

Please add a comment explaining the different types; something like:
The labels referenced in DO statements and defined in END DO statements
 get types respectively ST_LABEL_DO_TARGET and ST_LABEL_ENDDO_TARGET
instead of the generic ST_LABEL_TARGET so that they can be distinguished
to issue DO-specific diagnostics.
The DO label is a label reference, so ST_LABEL_DO_TARGET is to be used
in gfc_st_label::referenced only.  The ST_LABEL_ENDDO_TARGET is the
corresponding label definition, and is to be used in
gfc_st_label::defined only.



 @@ -3825,8 +3828,11 @@ parse_executable (gfc_statement st)
   case ST_NONE:
 unexpected_eof ();
  
 - case ST_FORMAT:
   case ST_DATA:
 +   gfc_notify_std (GFC_STD_F95_OBS, DATA statement at %C after the 
 +first executable statement);
 +   /* Fall through.  */
 + case ST_FORMAT:
   case ST_ENTRY:
   case_executable:
 accept_statement (st);

This diagnostic is more appropriate in verify_st_order (which needs to
be called then).


 diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
 index 455e6c9..135c1e5 100644
 --- a/gcc/fortran/symbol.c
 +++ b/gcc/fortran/symbol.c
 @@ -2213,12 +2214,19 @@ gfc_define_st_label (gfc_st_label *lp, gfc_sl_type 
 type, locus *label_locus)
 break;
  
   case ST_LABEL_TARGET:
 + case ST_LABEL_ENDDO_TARGET:
 if (lp-referenced == ST_LABEL_FORMAT)
   gfc_error (Label %d at %C already referenced as a format label,
  labelno);
 else
   lp-defined = ST_LABEL_TARGET;

I think it should be `lp-defined = type;' here.


 @@ -2254,14 +2262,16 @@ gfc_reference_st_label (gfc_st_label *lp, gfc_sl_type 
 type)
lp-where = gfc_current_locus;
  }
  
 -  if (label_type == ST_LABEL_FORMAT  type == ST_LABEL_TARGET)
 +  if (label_type == ST_LABEL_FORMAT
 +   (type == ST_LABEL_TARGET || type == ST_LABEL_DO_TARGET))
  {
gfc_error (Label %d at %C previously used as a FORMAT label, 
 labelno);
rc = FAILURE;
goto done;
  }
  
 -  if ((label_type == ST_LABEL_TARGET || label_type == ST_LABEL_BAD_TARGET)
 +  if ((label_type == ST_LABEL_TARGET || label_type == ST_LABEL_DO_TARGET
 +   || label_type == ST_LABEL_BAD_TARGET)
 type == ST_LABEL_FORMAT)
  {
gfc_error (Label %d at %C previously used as branch target, labelno);

label_type is initialized using either lp-referenced or lp-defined.
Thus both ST_LABEL_DO_TARGET and ST_LABEL_ENDDO_TARGET should be checked
here. Unless they are merged as suggested above.


Mikael


[Patch, Fortran] PR40881 - Add two F95 obsolescence warnings

2012-08-08 Thread Tobias Burnus
This patch implements a warning for the following Fortran 95 (and later) 
obsolescent features (cf. F2008, B.2 Obsolescent features):


(2) Shared DO termination and termination on a statement other than END 
DO or CONTINUE -- use

an END DO or a CONTINUE statement for each DO statement.
(6) DATA statements amongst executable statements -- see B.2.5.

With this patch, I think the only unimplemented obsolescence warning is for
(8) Fixed form source -- see B.2.7.

For the latter, I would like to see a possibility to silence that 
warning, given that there is substantial code around, which is in fixed 
form but otherwise a completely valid and obsolescent-free code.


The motivation for implementing this patch was that I did a small 
obsolescent cleanup of our fixed-form code (which uses some Fortran 2003 
features) and I realized that ifort had the shared DO termination 
warning and gfortran didn't.


Build and regtested on x86-64-gnu-linux.
OK for the trunk?

Tobias
2012-08-08  Tobias Burnus  bur...@net-b.de

	PR fortran/40881
	* error.c (gfc_notify_std): Reset cur_error_buffer-flag flag
	when the error/warning has been printed.
	* gfortran.h (gfc_sl_type): Add ST_LABEL_DO_TARGET and
	ST_LABEL_ENDDO_TARGET.
	* match.c (gfc_match_do): Use ST_LABEL_DO_TARGET.
	* parse.c (check_statement_label): Use ST_LABEL_ENDDO_TARGET.
	(parse_executable): Add obsolescence check for DATA.
	* resolve.c (resolve_branch): Handle ST_LABEL_DO_TARGET.
	* symbol.c (gfc_define_st_label, gfc_reference_st_label):
	Add obsolescence diagnostics.
	* trans-stmt.c (gfc_trans_label_assign): Handle ST_LABEL_DO_TARGET.

2012-08-08  Tobias Burnus  bur...@net-b.de

	PR fortran/40881
	* gfortran.dg/data_constraints_3.f90: New.
	* gfortran.dg/data_constraints_1.f90: Update dg-warning.
	* gfortran.dg/pr37243.f: Ditto.
	* gfortran.dg/g77/19990826-3.f: Ditto.
	* gfortran.dg/g77/20020307-1.f : Ditto.
	* gfortran.dg/g77/980310-3.f: Ditto.

diff --git a/gcc/fortran/error.c b/gcc/fortran/error.c
index 7e968db..dde6a0f 100644
--- a/gcc/fortran/error.c
+++ b/gcc/fortran/error.c
@@ -875,6 +875,7 @@ gfc_notify_std (int std, const char *gmsgid, ...)
 	warnings++;
   else
 	gfc_increment_error_count();
+  cur_error_buffer-flag = 0;
 }
 
   return (warning  !warnings_are_errors) ? SUCCESS : FAILURE;
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index b6e2975..9670022 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -146,8 +146,8 @@ ar_type;
 
 /* Statement label types.  */
 typedef enum
-{ ST_LABEL_UNKNOWN = 1, ST_LABEL_TARGET,
-  ST_LABEL_BAD_TARGET, ST_LABEL_FORMAT
+{ ST_LABEL_UNKNOWN = 1, ST_LABEL_TARGET, ST_LABEL_DO_TARGET,
+  ST_LABEL_ENDDO_TARGET, ST_LABEL_BAD_TARGET, ST_LABEL_FORMAT
 }
 gfc_sl_type;
 
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 737d6a3..5ab07e5 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -2400,7 +2400,7 @@ gfc_match_do (void)
 	goto concurr_cleanup;
 
   if (label != NULL
-	gfc_reference_st_label (label, ST_LABEL_TARGET) == FAILURE)
+	gfc_reference_st_label (label, ST_LABEL_DO_TARGET) == FAILURE)
 	goto concurr_cleanup;
 
   new_st.label1 = label;
@@ -2454,7 +2454,7 @@ concurr_cleanup:
 
 done:
   if (label != NULL
-   gfc_reference_st_label (label, ST_LABEL_TARGET) == FAILURE)
+   gfc_reference_st_label (label, ST_LABEL_DO_TARGET) == FAILURE)
 goto cleanup;
 
   new_st.label1 = label;
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index ecda163..d7e4b78 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -1168,7 +1168,10 @@ check_statement_label (gfc_statement st)
 case ST_END_ASSOCIATE:
 case_executable:
 case_exec_markers:
-  type = ST_LABEL_TARGET;
+  if (st == ST_ENDDO || st == ST_CONTINUE)
+	type = ST_LABEL_ENDDO_TARGET;
+  else
+	type = ST_LABEL_TARGET;
   break;
 
 case ST_FORMAT:
@@ -3825,8 +3828,11 @@ parse_executable (gfc_statement st)
 	case ST_NONE:
 	  unexpected_eof ();
 
-	case ST_FORMAT:
 	case ST_DATA:
+	  gfc_notify_std (GFC_STD_F95_OBS, DATA statement at %C after the 
+	   first executable statement);
+	  /* Fall through.  */
+	case ST_FORMAT:
 	case ST_ENTRY:
 	case_executable:
 	  accept_statement (st);
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index c5810b2..3db34c5 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -8767,7 +8767,8 @@ resolve_branch (gfc_st_label *label, gfc_code *code)
   return;
 }
 
-  if (label-defined != ST_LABEL_TARGET)
+  if (label-defined != ST_LABEL_TARGET
+   label-defined != ST_LABEL_ENDDO_TARGET)
 {
   gfc_error (Statement at %L is not a valid branch target statement 
 		 for the branch statement at %L, label-where, code-loc);
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 455e6c9..135c1e5 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -2204,7 +2204,8 @@ gfc_define_st_label (gfc_st_label *lp, gfc_sl_type type, locus *label_locus)