[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 13:01:11 GMT 2025
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122705
--- Comment #9 from Alejandro Colomar <foss+gcc@alejandro-colomar.es> ---
(In reply to Alejandro Colomar from comment #6)
> (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)
D'oh. Paste-and-edit issues. The p in the prototype should be 'dst'.
> {
> 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