Hi Bernd,
Not familiar with this area but one comment below...
On 06/10/16 15:12, Bernd Edlinger wrote:
Hi!
Currently C++ does not warn at all when built-in functions are
re-defined with a different signature, while C does warn on that
even without -Wall.
Thus I'd like to propose a -Wall enabled warning for that in C++ only.
Initially I tried to warn unconditionally but that made too many tests
in the C++ testsuite emit that warning :-(
So making the warning dependent on -Wall is a compromise due
to the very many compile only tests, that use this "feature".
There is also a wrong-code side on this redefinition, because
even if the new function has the nothrow attribute the code is
generated as if it could throw. Fixed as well.
This is an updated version of the patch that was posted
here: https://gcc.gnu.org/ml/gcc-patches/2016-08/msg01463.html
... but got no response so far.
I have seen a few warnings in system headers, when -Wsystem-headers
is used, and fixed most of them, for instance strftime got a
redefinition warning, because the const struct tm* parameter has to be
handled as the FILE* in other builtin functions.
As a little surprise, it turned out, there were warnings missing
from strftime in C due to the type conflict when merging the builtin
with the actual declaration, see the format warnings in the test case
testsuite/g++.dg/pr71973-2.C, which were not working previously in C++.
Then there are cases, where a builtin function and C++ overloads
have the same name like the abs function from cstdlib. Due to
missing strictness in duplicate_decls the builtin got merged with
one of the C++ overloads. That was visible due to the new warning.
I believe a builtin function always needs an extern "C" declaration.
Additional C++ overloads are possible, but do not redefine the builtin
function, and create additional overloads.
However these warnings remain, and I have no idea if the header
file is correct or the warning:
/usr/include/unistd.h:551:12: warning: declaration of 'int execve(const
char*, char* const*, char* const*)' conflicts with built-in declaration
'int execve(const char*, const char**, const char**)'
[-Wbuiltin-function-redefined]
extern int execve (const char *__path, char *const __argv[],
^~~~~~
/usr/include/unistd.h:563:12: warning: declaration of 'int execv(const
char*, char* const*)' conflicts with built-in declaration 'int
execv(const char*, const char**)' [-Wbuiltin-function-redefined]
extern int execv (const char *__path, char *const __argv[])
^~~~~
/usr/include/unistd.h:578:12: warning: declaration of 'int execvp(const
char*, char* const*)' conflicts with built-in declaration 'int
execvp(const char*, const char**)' [-Wbuiltin-function-redefined]
extern int execvp (const char *__file, char *const __argv[])
^~~~~~
Interesting is that, these do not happen with -std=c++03/11/14 but only
with -std=gnu++03/11/14. I could not figure out how to resolve that.
As said, this is only visible with -Wsystem-headers, and would not
happen, if the declaration in unistd.h would match the builtin function
prototype.
The reg-test also revealed a test case that is IMO invalid, and
depends on the incorrect merging of a builtin definition with a friend
function see testsuite/g++.dg/lookup/extern-c-redecl4.C:
This test case does no longer compile, because the builtin
fails to have an explicit declaration.
Bootstrap and reg-testing on x86_64-pc-linux-gnu.
OK for trunk?
Thanks
Bernd.
@@ -1553,7 +1588,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool
/* Whether or not the builtin can throw exceptions has no
bearing on this declarator. */
- TREE_NOTHROW (olddecl) = 0;
+ TREE_NOTHROW (olddecl) = TREE_NOTHROW (newdecl);
The comment would need to be updated I think.
Kyrill