diff options
Diffstat (limited to 'gcc/c-family/c-common.c')
-rw-r--r-- | gcc/c-family/c-common.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 858ed68..e1df1d3 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -5309,10 +5309,11 @@ check_function_sentinel (const_tree fntype, int nargs, tree *argarray) } } -/* Check that the same argument isn't passed to restrict arguments - and other arguments. */ +/* Check that the same argument isn't passed to two or more + restrict-qualified formal and issue a -Wrestrict warning + if it is. Return true if a warning has been issued. */ -static void +static bool check_function_restrict (const_tree fndecl, const_tree fntype, int nargs, tree *argarray) { @@ -5322,11 +5323,14 @@ check_function_restrict (const_tree fndecl, const_tree fntype, if (fndecl && TREE_CODE (fndecl) == FUNCTION_DECL) { - /* Skip checking built-ins here. They are checked in more - detail elsewhere. */ + /* Avoid diagnosing calls built-ins with a zero size/bound + here. They are checked in more detail elsewhere. */ if (DECL_BUILT_IN (fndecl) - && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) - return; + && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL + && nargs == 3 + && TREE_CODE (argarray[2]) == INTEGER_CST + && integer_zerop (argarray[2])) + return false; if (DECL_ARGUMENTS (fndecl)) parms = DECL_ARGUMENTS (fndecl); @@ -5335,6 +5339,8 @@ check_function_restrict (const_tree fndecl, const_tree fntype, for (i = 0; i < nargs; i++) TREE_VISITED (argarray[i]) = 0; + bool warned = false; + for (i = 0; i < nargs && parms && parms != void_list_node; i++) { tree type; @@ -5351,11 +5357,13 @@ check_function_restrict (const_tree fndecl, const_tree fntype, if (POINTER_TYPE_P (type) && TYPE_RESTRICT (type) && !TYPE_READONLY (TREE_TYPE (type))) - warn_for_restrict (i, argarray, nargs); + warned |= warn_for_restrict (i, argarray, nargs); } for (i = 0; i < nargs; i++) TREE_VISITED (argarray[i]) = 0; + + return warned; } /* Helper for check_function_nonnull; given a list of operands which @@ -5596,8 +5604,10 @@ attribute_fallthrough_p (tree attr) /* Check for valid arguments being passed to a function with FNTYPE. - There are NARGS arguments in the array ARGARRAY. LOC should be used for - diagnostics. Return true if -Wnonnull warning has been diagnosed. */ + There are NARGS arguments in the array ARGARRAY. LOC should be used + for diagnostics. Return true if either -Wnonnull or -Wrestrict has + been issued. */ + bool check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype, int nargs, tree *argarray, vec<location_t> *arglocs) @@ -5620,7 +5630,7 @@ check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype, check_function_sentinel (fntype, nargs, argarray); if (warn_restrict) - check_function_restrict (fndecl, fntype, nargs, argarray); + warned_p |= check_function_restrict (fndecl, fntype, nargs, argarray); return warned_p; } |