This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to detect invalid and missing ATTRIBUTE const/pure [take 2]
- From: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Cc: dann at ics dot uci dot edu, jh at suse dot cz, john at feith dot com, mark at codesourcery dot com, rth at redhat dot com
- Date: Sat, 23 Mar 2002 00:36:17 -0500 (EST)
- Subject: 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