https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122705
--- Comment #6 from Alejandro Colomar <[email protected]> --- (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.
