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 to detect invalid and missing ATTRIBUTE const/pure [take 2]


Ok here is take 2.  Solaris bootstrap is broken this evening so I
haven't tested it thoroughly yet.  Changes from the last version are:

1.  Only mark functions when !TREE_PUBLIC || MODULE_LOCAL_P.

2.  If a function has a loop, gcc will never suggest marking it, but
    that by itself not a reason to claim its invalid if the programmer
    marked it.

Open issues:

1.  Perhaps noreturn calls should be handled like loops?  I.e. they
    don't by themselves automatically invalidate a marking, but gcc
    won't make or suggest one either.  (Not sure how to implement that
    one yet.)

2.  If a function is marked pure, and gcc detects the function is
    really const, should we proceed to apply the stricter attribute?

Comments welcome.  Next task will be to start adding ATTRIBUTES where
suggested by gcc and test test test.

		--Kaveh


diff -rcp orig/egcc-CVS20020322/gcc/alias.c egcc-CVS20020322/gcc/alias.c
*** orig/egcc-CVS20020322/gcc/alias.c	Thu Mar 21 07:00:26 2002
--- egcc-CVS20020322/gcc/alias.c	Sat Mar 23 00:13:30 2002
*************** void
*** 2549,2566 ****
  mark_constant_function ()
  {
    rtx insn;
!   int nonlocal_memory_referenced;
  
!   if (TREE_PUBLIC (current_function_decl)
!       || TREE_READONLY (current_function_decl)
!       || DECL_IS_PURE (current_function_decl)
!       || TREE_THIS_VOLATILE (current_function_decl)
        || TYPE_MODE (TREE_TYPE (current_function_decl)) == VOIDmode
        || current_function_has_nonlocal_goto)
!     return;
  
!   /* A loop might not return which counts as a side effect.  */
!   if (mark_dfs_back_edges ())
      return;
  
    nonlocal_memory_referenced = 0;
--- 2549,2579 ----
  mark_constant_function ()
  {
    rtx insn;
!   int nonlocal_memory_referenced, loop_present;
  
!   if (TREE_THIS_VOLATILE (current_function_decl)
        || TYPE_MODE (TREE_TYPE (current_function_decl)) == VOIDmode
        || current_function_has_nonlocal_goto)
!     {
!       if (TREE_READONLY (current_function_decl))
! 	warning ("function `%s' invalid for attribute `const'",
! 		 current_function_name);
!       else if (DECL_IS_PURE (current_function_decl))
! 	warning ("function `%s' invalid for attribute `pure'",
! 		 current_function_name);
! 
!       return;
!     }
!   
!   loop_present = mark_dfs_back_edges ();
  
!   /* A loop might not return which counts as a side effect.  If the
!      programmer hasn't marked the function, we won't mark or suggest
!      marking it when a loop is present, just silently return in those
!      cases.  However if the programmer did mark the function, then we
!      proceed to double check it below.  */
!   if (loop_present && !TREE_READONLY (current_function_decl)
!       && !DECL_IS_PURE (current_function_decl))
      return;
  
    nonlocal_memory_referenced = 0;
*************** mark_constant_function ()
*** 2587,2597 ****
    /* Mark the function.  */
    
    if (insn)
!     ;
    else if (nonlocal_memory_referenced)
!     DECL_IS_PURE (current_function_decl) = 1;
!   else
!     TREE_READONLY (current_function_decl) = 1;
  }
  
  
--- 2600,2637 ----
    /* Mark the function.  */
    
    if (insn)
!     {
!       if (TREE_READONLY (current_function_decl))
! 	warning ("function `%s' invalid for attribute `const'",
! 		 current_function_name);
!       else if (DECL_IS_PURE (current_function_decl))
! 	warning ("function `%s' invalid for attribute `pure'",
! 		 current_function_name);
!     }
    else if (nonlocal_memory_referenced)
!     {
!       if (TREE_READONLY (current_function_decl))
! 	warning ("function `%s' invalid for attribute `const'",
! 		 current_function_name);
!       if (!loop_present)
!         {
! 	  if (warn_missing_pure && ! DECL_IS_PURE (current_function_decl))
! 	    warning ("function `%s' may be candidate for attribute `pure'",
! 		     current_function_name);
! 	  if (! TREE_PUBLIC (current_function_decl)
! 	      || MODULE_LOCAL_P (current_function_decl))
! 	    DECL_IS_PURE (current_function_decl) = 1;
! 	}
!     }
!   else if (!loop_present)
!     {
!       if (warn_missing_const && ! TREE_READONLY (current_function_decl))
! 	warning ("function `%s' may be candidate for attribute `const'",
! 		 current_function_name);
!       if (! TREE_PUBLIC (current_function_decl)
! 	  || MODULE_LOCAL_P (current_function_decl))
! 	TREE_READONLY (current_function_decl) = 1;
!     }
  }
  
  
diff -rcp orig/egcc-CVS20020322/gcc/flags.h egcc-CVS20020322/gcc/flags.h
*** orig/egcc-CVS20020322/gcc/flags.h	Thu Mar 21 22:17:54 2002
--- egcc-CVS20020322/gcc/flags.h	Fri Mar 22 23:27:20 2002
*************** extern int warn_return_type;
*** 139,144 ****
--- 139,152 ----
  
  extern int warn_missing_noreturn;
  
+ /* Warn about functions which might be candidates for attribute const.  */
+ 
+ extern int warn_missing_const;
+ 
+ /* Warn about functions which might be candidates for attribute pure.  */
+ 
+ extern int warn_missing_pure;
+ 
  /* Nonzero means warn about pointer casts that increase the required
     alignment of the target type (and might therefore lead to a crash
     due to a misaligned access).  */
diff -rcp orig/egcc-CVS20020322/gcc/toplev.c egcc-CVS20020322/gcc/toplev.c
*** orig/egcc-CVS20020322/gcc/toplev.c	Fri Mar 22 16:00:35 2002
--- egcc-CVS20020322/gcc/toplev.c	Fri Mar 22 23:27:20 2002
*************** int warn_disabled_optimization;
*** 1442,1447 ****
--- 1442,1455 ----
  
  int warn_missing_noreturn;
  
+ /* Warn about functions which might be candidates for attribute const.  */
+ 
+ int warn_missing_const;
+ 
+ /* Warn about functions which might be candidates for attribute pure.  */
+ 
+ int warn_missing_pure;
+ 
  /* Nonzero means warn about uses of __attribute__((deprecated)) 
     declarations.  */
  
*************** static const lang_independent_options W_
*** 1488,1494 ****
    {"deprecated-declarations", &warn_deprecated_decl, 1,
     N_("Warn about uses of __attribute__((deprecated)) declarations") },
    {"missing-noreturn", &warn_missing_noreturn, 1,
!    N_("Warn about functions which might be candidates for attribute noreturn") }
  };
  
  void
--- 1496,1506 ----
    {"deprecated-declarations", &warn_deprecated_decl, 1,
     N_("Warn about uses of __attribute__((deprecated)) declarations") },
    {"missing-noreturn", &warn_missing_noreturn, 1,
!    N_("Warn about functions which might be candidates for attribute noreturn") },
!   {"missing-const", &warn_missing_const, 1,
!    N_("Warn about functions which might be candidates for attribute const") },
!   {"missing-pure", &warn_missing_pure, 1,
!    N_("Warn about functions which might be candidates for attribute pure") }
  };
  
  void


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