This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, fortran] PR28660 - Spurious warning: 'ubound.6' is used uninitialized in this function


:ADDPATCH fortran:

This patch fixes a problem in which dependent declarations would get added to a function in the wrong order and would cause nonsense to be produced or runtime errors for negative allocation of memory.

The patch adds a check of declaration dependences to generate_local_decl before the potentially dependent declaration is added to the function. The testcase checks both versions of the problem as described in the PR.

It should be noted that two declarations of z are produced, with or without the patch. It so happens that the patched version has calculated .z before the second declaration, rather than after it. The redundant declaration should be removed sometime.

Regtested on FC5/Athlon and checked by building tonto-2.3 and running its testsuite.

OK for trunk and 4.2?

Paul

2006-08-11 Paul Thomas <pault@gcc.gnu.org>

   PR fortran/28660
   * trans-decl.c (generate_expr_decls): New function.
   (generate_dependency_declarations): New function.
   (generate_local_decl): Call previous if not either a dummy or
   a declaration in an entry master.

2006-08-11 Paul Thomas <pault@gcc.gnu.org>

   PR fortran/28660
   * gfortran.dg/dependent_decls_1.f90: New test.



*** ./gcc/fortran/trans-decl.c.orig	2006-08-09 17:23:40.000000000 +0200
--- ./gcc/fortran/trans-decl.c	2006-08-11 21:27:59.000000000 +0200
*************** gfc_generate_contained_functions (gfc_na
*** 2751,2756 ****
--- 2751,2862 ----
  }
  
  
+ /* Drill down through expressions for the array specification bounds and
+    character length calling generate_local_decl for all those variables
+    that have not already been declared.  */
+ 
+ static void
+ generate_local_decl (gfc_symbol *);
+ 
+ static void
+ generate_expr_decls (gfc_symbol *sym, gfc_expr *e)
+ {
+   gfc_actual_arglist *arg;
+   gfc_ref *ref;
+   int i;
+ 
+   if (e == NULL)
+     return;
+ 
+   switch (e->expr_type)
+     {
+     case EXPR_FUNCTION:
+       for (arg = e->value.function.actual; arg; arg = arg->next)
+ 	generate_expr_decls (sym, arg->expr);
+       break;
+ 
+     /* If the variable is not the same as the dependent, 'sym', and
+        it is not marked as being declared and it is in the same
+        namespace as 'sym', add it to the local declarations.  */
+     case EXPR_VARIABLE:
+       if (sym == e->symtree->n.sym
+ 	    || e->symtree->n.sym->mark
+ 	    || e->symtree->n.sym->ns != sym->ns)
+ 	return;
+ 
+       generate_local_decl (e->symtree->n.sym);
+       break;
+ 
+     case EXPR_OP:
+       generate_expr_decls (sym, e->value.op.op1);
+       generate_expr_decls (sym, e->value.op.op2);
+       break;
+ 
+     default:
+       break;
+     }
+ 
+   if (e->ref)
+     {
+       for (ref = e->ref; ref; ref = ref->next)
+ 	{
+ 	  switch (ref->type)
+ 	    {
+ 	    case REF_ARRAY:
+ 	      for (i = 0; i < ref->u.ar.dimen; i++)
+ 		{
+ 		  generate_expr_decls (sym, ref->u.ar.start[i]);
+ 		  generate_expr_decls (sym, ref->u.ar.end[i]);
+ 		  generate_expr_decls (sym, ref->u.ar.stride[i]);
+ 		}
+ 	      break;
+ 
+ 	    case REF_SUBSTRING:
+ 	      generate_expr_decls (sym, ref->u.ss.start);
+ 	      generate_expr_decls (sym, ref->u.ss.start);
+ 	      break;
+ 
+ 	    case REF_COMPONENT:
+ 	      if (ref->u.c.component->ts.type == BT_CHARACTER
+ 		    && ref->u.c.component->ts.cl->length->expr_type
+ 						!= EXPR_CONSTANT)
+ 		generate_expr_decls (sym, ref->u.c.component->ts.cl->length);
+ 
+ 	      if (ref->u.c.component->as)
+ 	        for (i = 0; i < ref->u.c.component->as->rank; i++)
+ 		  {
+ 		    generate_expr_decls (sym, ref->u.c.component->as->lower[i]);
+ 		    generate_expr_decls (sym, ref->u.c.component->as->upper[i]);
+ 		  }
+ 	      break;
+ 	    }
+ 	}
+     }
+ }
+ 
+ 
+ /* Check for dependencies in the character length and array spec. */
+ 
+ static void
+ generate_dependency_declarations (gfc_symbol *sym)
+ {
+   int i;
+ 
+   if (sym->ts.type == BT_CHARACTER
+ 	&& sym->ts.cl->length->expr_type != EXPR_CONSTANT)
+     generate_expr_decls (sym, sym->ts.cl->length);
+ 
+   if (sym->as && sym->as->rank)
+     {
+       for (i = 0; i < sym->as->rank; i++)
+ 	{
+           generate_expr_decls (sym, sym->as->lower[i]);
+           generate_expr_decls (sym, sym->as->upper[i]);
+ 	}
+     }
+ }
+ 
+ 
  /* Generate decls for all local variables.  We do this to ensure correct
     handling of expressions which only appear in the specification of
     other functions.  */
*************** generate_local_decl (gfc_symbol * sym)
*** 2760,2765 ****
--- 2866,2879 ----
  {
    if (sym->attr.flavor == FL_VARIABLE)
      {
+       /* Check for dependencies in the array specification and needed have
+ 	 already been added to the function.  We mark the symbol now, as
+ 	 well as in traverse_ns, to prevent getting stuck in a circular
+ 	 dependency.  */
+       sym->mark = 1;
+       if (!sym->attr.dummy && !sym->ns->proc_name->attr.entry_master)
+         generate_dependency_declarations (sym);
+ 
        if (sym->attr.referenced)
          gfc_get_symbol_decl (sym);
        else if (sym->attr.dummy && warn_unused_parameter)
2006-08-11  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/28660
	* trans-decl.c (generate_expr_decls): New function.
	(generate_dependency_declarations): New function.
	(generate_local_decl): Call previous if not either a dummy or
	a declaration in an entry master.

2006-08-11  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/28660
	* gfortran.dg/dependent_decls_1.f90: New test.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]