[Bug c/122705] Add function attributes to mark functions that return a pointer parameter, verbatim or derived
foss+gcc@alejandro-colomar.es
gcc-bugzilla@gcc.gnu.org
Mon Nov 17 12:15:31 GMT 2025
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122705
--- Comment #6 from Alejandro Colomar <foss+gcc@alejandro-colomar.es> ---
(In reply to Andrew Pinski from comment #5)
> (In reply to Alejandro Colomar from comment #0)
> > I propose [[gnu::returns_input_ptr(1)]] for strcpy(3),
> > and [[gnu::returns_derived_ptr(1)]] for strstr(3),
> > where in both attributes, the '1' is a parameter index, indicating
> > which parameter is the provenance of the returned pointer.
>
> And GCC already has code to special case some builtins:
> ```
> /* Return the argument that the call STMT to a built-in function returns
> (including with an offset) or null if it doesn't. */
>
> tree
> pass_waccess::gimple_call_return_arg (gcall *call)
> {
> /* Check for attribute fn spec to see if the function returns one
> of its arguments. */
> attr_fnspec fnspec = gimple_call_fnspec (call);
> unsigned int argno;
> if (!fnspec.returns_arg (&argno))
> {
> if (gimple_call_num_args (call) < 1)
> return NULL_TREE;
>
> if (!gimple_call_builtin_p (call, BUILT_IN_NORMAL))
> return NULL_TREE;
>
> tree fndecl = gimple_call_fndecl (call);
> switch (DECL_FUNCTION_CODE (fndecl))
> {
> case BUILT_IN_MEMPCPY:
> case BUILT_IN_MEMPCPY_CHK:
> case BUILT_IN_MEMCHR:
> case BUILT_IN_STRCHR:
> case BUILT_IN_STRRCHR:
> case BUILT_IN_STRSTR:
> case BUILT_IN_STPCPY:
> case BUILT_IN_STPCPY_CHK:
> case BUILT_IN_STPNCPY:
> case BUILT_IN_STPNCPY_CHK:
> argno = 0;
> break;
>
> default:
> return NULL_TREE;
> }
> }
>
> if (gimple_call_num_args (call) <= argno)
> return NULL_TREE;
>
> return gimple_call_arg (call, argno);
> }
>
> ```
>
> Exposing this might be useful but it might also get abused incorrectly ...
I have a function which I'd like to be marked with it:
```
[[gnu::returns_derived_pointer(1)]]
char *
stpecpy(char p[], const char end[];
char p[p ? end - p : 0], const char end[0], const char *restrict src)
{
bool trunc;
char *p;
size_t dsize, dlen, slen;
if (dst == NULL)
return NULL;
dsize = end - dst;
slen = strnlen(src, dsize);
trunc = (slen == dsize);
dlen = slen - trunc;
p = stpcpy(mempcpy(dst, src, dlen), "");
if (trunc) {
errno = E2BIG;
return NULL;
}
return p;
}
```
This function is to be used like this:
```
#define endof(a) (&a[countof(a)])
char buf[1024];
char *p, *e;
p = buf;
e = endof(buf);
p = stpecpy(p, e, "foo");
p = stpecpy(p, e, "bar");
p = stpecpy(p, e, "baz");
if (p == NULL)
goto fail;
```
Currently, the compiler is blind to this function. It can't know the
relationship between p and e.
If the compiler knew that p is always derived from the original p, it would
also know that 'e' is always >=p, regardless of the value of p. This would
improve static analysis.
I think this would be necessary for a future where buffer overflows are
impossible in C.
More information about the Gcc-bugs
mailing list