I noticed that C++ does not emit a warning when the header defines a built-in function with a different/wrong signature. For instance int fork(void) is a built-in EXT-LIB function: but I define it differently: cat test.c void fork(); gcc -Wall -S test.c test3.c:1:6: warning: conflicting types for built-in function 'fork' void fork(); ^~~~ however with C++ the warning does not fire: cat test.cc extern "C" void fork(); g++ -O3 -Wall -S test.cc zero warnings. However the fact that there is a builtin has an effect: cat test.cc extern "C" void fork() __attribute__((nothrow)) void bar() throw() { fork(); } g++ -O3 -Wall -S test.cc emits eh code in bar which does not happen when the builtin fork is not defined, either by g++ -O3 -Wall -ansi -S test.cc no eh code. ... or changing the name of fork to zork for instance. results also in no eh code. It works of fork is declared as extern "C" void fork() throw(); or if bar is declared as __attribute__((nothrow)) void bar () { fork(); }
the bug goes away, if the fork signature is correct. extern "C" int fork () __attribute__((nothrow)); void bar () throw() { fork (); } does the right thing.
Confirmed. It doesn't look like G++ ever rejected such invalid code.
Created attachment 39472 [details] possible patch Oh, yeah! Boot-strap OK. The eh-code is OK. BUT: the warning triggers a few hundred times, within the g++.dg testsuite, and all of the places look like real bugs, that deserve a warning... FAIL: g++.dg/charset/asm2.c -std=c++98 (test for excess errors) FAIL: g++.dg/charset/asm2.c -std=c++11 (test for excess errors) FAIL: g++.dg/charset/asm2.c -std=c++14 (test for excess errors) FAIL: g++.dg/debug/dwarf2/template-func-params-7.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/debug/dwarf2/template-func-params-7.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/addr_builtin-1.C -std=c++98 (test for excess errors) FAIL: g++.dg/addr_builtin-1.C -std=c++11 (test for excess errors) FAIL: g++.dg/addr_builtin-1.C -std=c++14 (test for excess errors) FAIL: g++.dg/cpp0x/constexpr-builtin1.C -std=c++11 (test for excess errors) FAIL: g++.dg/cpp0x/constexpr-builtin1.C -std=c++14 (test for excess errors) FAIL: g++.dg/cpp0x/constexpr-function2.C -std=c++11 (test for excess errors) FAIL: g++.dg/cpp0x/constexpr-function2.C -std=c++14 (test for excess errors) FAIL: g++.dg/cpp0x/constexpr-pos1.C -std=c++11 (test for excess errors) FAIL: g++.dg/cpp0x/constexpr-pos1.C -std=c++14 (test for excess errors) FAIL: g++.dg/cpp0x/gen-attrs-40.C -std=c++11 (test for excess errors) FAIL: g++.dg/cpp0x/gen-attrs-40.C -std=c++14 (test for excess errors) FAIL: g++.dg/cpp1y/lambda-generic-udt.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/cpp1y/lambda-generic-xudt.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/diagnostic/pr70105.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/diagnostic/pr70105.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/diagnostic/pr70105.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/ext/attrib40.C -std=c++98 (test for excess errors) FAIL: g++.dg/ext/attrib40.C -std=c++11 (test for excess errors) FAIL: g++.dg/ext/attrib40.C -std=c++14 (test for excess errors) FAIL: g++.dg/init/new15.C -std=c++98 (test for excess errors) FAIL: g++.dg/init/new15.C -std=c++11 (test for excess errors) FAIL: g++.dg/init/new15.C -std=c++14 (test for excess errors) FAIL: g++.dg/init/ref9.C -std=c++98 (test for excess errors) FAIL: g++.dg/init/ref9.C -std=c++11 (test for excess errors) FAIL: g++.dg/init/ref9.C -std=c++14 (test for excess errors) AIL: g++.dg/ipa/inline-1.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/ipa/inline-1.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/ipa/inline-1.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/ipa/inline-2.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/ipa/inline-2.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/ipa/inline-2.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/lookup/builtin1.C -std=c++98 (test for excess errors) FAIL: g++.dg/lookup/builtin1.C -std=c++11 (test for excess errors) FAIL: g++.dg/lookup/builtin1.C -std=c++14 (test for excess errors) FAIL: g++.dg/lookup/builtin3.C -std=c++98 (test for excess errors) FAIL: g++.dg/lookup/builtin3.C -std=c++11 (test for excess errors) FAIL: g++.dg/lookup/builtin3.C -std=c++14 (test for excess errors) FAIL: g++.dg/lookup/builtin5.C -std=c++11 (test for excess errors) FAIL: g++.dg/lookup/builtin5.C -std=c++14 (test for excess errors) FAIL: g++.dg/lookup/builtin7.C -std=c++98 (test for excess errors) FAIL: g++.dg/lookup/builtin7.C -std=c++11 (test for excess errors) FAIL: g++.dg/lookup/builtin7.C -std=c++14 (test for excess errors) FAIL: g++.dg/lookup/extern-c-redecl4.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/lookup/extern-c-redecl4.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/lookup/extern-c-redecl4.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/opt/cfg1.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/opt/cfg1.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/opt/cfg1.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/opt/conj1.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/opt/conj1.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/opt/conj1.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/opt/conj2.C -std=c++11 (test for excess errors) FAIL: g++.dg/opt/conj2.C -std=c++14 (test for excess errors) FAIL: g++.dg/opt/copysign-1.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/opt/copysign-1.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/opt/copysign-1.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/opt/pr17724-5.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/opt/pr17724-5.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/opt/pr17724-5.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/opt/pr17724-6.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/opt/pr17724-6.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/opt/pr17724-6.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/opt/reload2.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/opt/reload2.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/opt/reload2.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/other/vararg-2.C -std=c++98 (test for excess errors) FAIL: g++.dg/other/vararg-2.C -std=c++11 (test for excess errors) FAIL: g++.dg/other/vararg-2.C -std=c++14 (test for excess errors) FAIL: g++.dg/overload/builtin3.C -std=c++98 (test for excess errors) FAIL: g++.dg/overload/builtin3.C -std=c++11 (test for excess errors) FAIL: g++.dg/overload/builtin3.C -std=c++14 (test for excess errors) FAIL: g++.dg/overload/using2.C -std=c++98 (test for excess errors) FAIL: g++.dg/overload/using2.C -std=c++11 (test for excess errors) FAIL: g++.dg/overload/using2.C -std=c++14 (test for excess errors) FAIL: g++.dg/parse/builtin1.C -std=c++98 (test for excess errors) FAIL: g++.dg/parse/builtin1.C -std=c++11 (test for excess errors) FAIL: g++.dg/parse/builtin1.C -std=c++14 (test for excess errors) FAIL: g++.dg/parse/pr26997.C -std=c++98 (test for excess errors) FAIL: g++.dg/parse/pr26997.C -std=c++11 (test for excess errors) FAIL: g++.dg/parse/pr26997.C -std=c++14 (test for excess errors) FAIL: g++.dg/spellcheck-identifiers-2.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/spellcheck-identifiers-2.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/spellcheck-identifiers-2.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/spellcheck-identifiers.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/spellcheck-identifiers.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/spellcheck-identifiers.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/tc1/dr20.C -std=c++98 (test for excess errors) FAIL: g++.dg/tc1/dr20.C -std=c++11 (test for excess errors) FAIL: g++.dg/tc1/dr20.C -std=c++14 (test for excess errors) FAIL: g++.dg/template/strlen1.C -std=c++98 (test for excess errors) FAIL: g++.dg/template/strlen1.C -std=c++11 (test for excess errors) FAIL: g++.dg/template/strlen1.C -std=c++14 (test for excess errors) FAIL: g++.dg/tree-ssa/copyprop.C (test for excess errors) FAIL: g++.dg/tree-ssa/inline-1.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/tree-ssa/inline-1.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/tree-ssa/inline-1.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/tree-ssa/inline-2.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/tree-ssa/inline-2.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/tree-ssa/inline-2.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/tree-ssa/nothrow-1.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/tree-ssa/nothrow-1.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/tree-ssa/nothrow-1.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/tree-ssa/pr21584-2.C -std=c++98 (test for excess errors) FAIL: g++.dg/tree-ssa/pr21584-2.C -std=c++11 (test for excess errors) FAIL: g++.dg/tree-ssa/pr21584-2.C -std=c++14 (test for excess errors) FAIL: g++.dg/tree-ssa/pr22037.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/tree-ssa/pr22037.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/tree-ssa/pr22037.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/tree-ssa/ssa-dom.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/tree-ssa/ssa-dom.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/tree-ssa/ssa-dom.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/warn/Wreturn-1.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/warn/Wreturn-1.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/warn/Wreturn-1.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/warn/Wsystem-headers1a.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/warn/Wsystem-headers1a.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/warn/Wsystem-headers1a.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/warn/noeffect5.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/warn/noeffect5.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/warn/noeffect5.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/warn/sequence-pt-1.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/warn/sequence-pt-1.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/warn/sequence-pt-1.C -std=gnu++14 (test for excess errors) FAIL: g++.dg/gomp/for-14.C -std=c++98 (test for excess errors) FAIL: g++.dg/gomp/for-14.C -std=c++11 (test for excess errors) FAIL: g++.dg/gomp/for-14.C -std=c++14 (test for excess errors) FAIL: g++.dg/gomp/openmp-simd-2.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/gomp/openmp-simd-2.C -std=gnu++11 (test for excess errors) FAIL: g++.dg/gomp/openmp-simd-2.C -std=gnu++14 (test for excess errors) etc. etc. etc....
Author: edlinger Date: Fri Nov 4 15:30:52 2016 New Revision: 241846 URL: https://gcc.gnu.org/viewcvs?rev=241846&root=gcc&view=rev Log: 2016-11-04 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c++/71973 * g++.dg/cpp1y/lambda-generic-udt.C: Fix builtin function declaration. * g++.dg/init/new15.C: Likewise. * g++.dg/ipa/inline-1.C: Likewise. * g++.dg/ipa/inline-2.C: Likewise. * g++.dg/lto/20080908-1_0.C: Likewise. * g++.dg/tc1/dr20.C: Likewise. * g++.dg/tree-ssa/inline-1.C: Likewise. * g++.dg/tree-ssa/inline-2.C: Likewise. * g++.old-deja/g++.law/except1.C: Likewise. * g++.old-deja/g++.other/vbase5.C: Likewise. * obj-c++.dg/lto/trivial-1_0.mm: Likewise. Modified: trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/g++.dg/cpp1y/lambda-generic-udt.C trunk/gcc/testsuite/g++.dg/init/new15.C trunk/gcc/testsuite/g++.dg/ipa/inline-1.C trunk/gcc/testsuite/g++.dg/ipa/inline-2.C trunk/gcc/testsuite/g++.dg/lto/20080908-1_0.C trunk/gcc/testsuite/g++.dg/tc1/dr20.C trunk/gcc/testsuite/g++.dg/tree-ssa/inline-1.C trunk/gcc/testsuite/g++.dg/tree-ssa/inline-2.C trunk/gcc/testsuite/g++.old-deja/g++.law/except1.C trunk/gcc/testsuite/g++.old-deja/g++.other/vbase5.C trunk/gcc/testsuite/obj-c++.dg/lto/trivial-1_0.mm
Author: edlinger Date: Mon Nov 21 14:17:05 2016 New Revision: 242662 URL: https://gcc.gnu.org/viewcvs?rev=242662&root=gcc&view=rev Log: gcc: 2016-11-21 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c++/71973 * doc/invoke.texi (-Wno-builtin-declaration-mismatch): Document the new default-enabled warning.. * builtin-types.def (BT_CONST_TM_PTR): New primitive type. (BT_PTR_CONST_STRING): Updated. (BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR): Removed. (BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_TM_PTR): New function type. * builtins.def (DEF_TM_BUILTIN): Disable BOTH_P for TM builtins. (strftime): Update builtin function. * tree-core.h (TI_CONST_TM_PTR_TYPE): New enum value. * tree.h (const_tm_ptr_type_node): New type node. * tree.c (free_lang_data, build_common_tree_nodes): Initialize const_tm_ptr_type_node. c-family: 2016-11-21 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c++/71973 * c.opt (-Wbuiltin-declaration-mismatch): New warning. * c-common.c (c_common_nodes_and_builtins): Initialize const_tm_ptr_type_node. c: 2016-11-21 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c++/71973 * c-decl.c (diagnose_mismatched_decls): Use OPT_Wbuiltin_declaration_mismatch here too. cp: 2016-11-21 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c++/71973 * decl.c (duplicate_decls): Warn when a built-in function is redefined. Don't overload builtin functions with C++ functions. Handle const_tm_ptr_type_node like file_ptr_node. Copy the TREE_NOTHROW flag unmodified to the old decl. lto: 2016-11-21 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c++/71973 * lto-lang.c (lto_init): Assert const_tm_ptr_type_node is sane. testsuite: 2016-11-21 Bernd Edlinger <bernd.edlinger@hotmail.de> PR c++/71973 * g++.dg/pr71973-1.C: New test. * g++.dg/pr71973-2.C: New test. * g++.dg/pr71973-3.C: New test. * g++.dg/lto/pr68811_0.C: Add -w to first lto-options. * g++.dg/lookup/extern-c-redecl4.C: Adjust test expectations. * g++.old-deja/g++.mike/p700.C: Add -Wno-builtin-declaration-mismatch to dg-options. * g++.old-deja/g++.other/realloc.C: Likewise. * g++.old-deja/g++.other/builtins10.C: Adjust test expectations. Added: trunk/gcc/testsuite/g++.dg/pr71973-1.C trunk/gcc/testsuite/g++.dg/pr71973-2.C trunk/gcc/testsuite/g++.dg/pr71973-3.C Modified: trunk/gcc/ChangeLog trunk/gcc/builtin-types.def trunk/gcc/builtins.def trunk/gcc/c-family/ChangeLog trunk/gcc/c-family/c-common.c trunk/gcc/c-family/c.opt trunk/gcc/c/ChangeLog trunk/gcc/c/c-decl.c trunk/gcc/cp/ChangeLog trunk/gcc/cp/decl.c trunk/gcc/doc/invoke.texi trunk/gcc/lto/ChangeLog trunk/gcc/lto/lto-lang.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/g++.dg/lookup/extern-c-redecl4.C trunk/gcc/testsuite/g++.dg/lto/pr68811_0.C trunk/gcc/testsuite/g++.old-deja/g++.mike/p700.C trunk/gcc/testsuite/g++.old-deja/g++.other/builtins10.C trunk/gcc/testsuite/g++.old-deja/g++.other/realloc.C trunk/gcc/tree-core.h trunk/gcc/tree.c trunk/gcc/tree.h
Author: jakub Date: Mon Nov 21 18:55:11 2016 New Revision: 242677 URL: https://gcc.gnu.org/viewcvs?rev=242677&root=gcc&view=rev Log: PR c++/71973 * g++.dg/torture/pr53321.C (size_t): Use __SIZE_TYPE__ instead of long unsigned int. * g++.dg/torture/pr63512.C (::strlen): Use __SIZE_TYPE__ instead of unsigned long. Modified: trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/g++.dg/torture/pr53321.C trunk/gcc/testsuite/g++.dg/torture/pr63512.C
Then fixed in 7.1.0, right?
Yes. fixed in 7.1.0 However, I wonder if I should do something when a variable is declared with the same name as a builtin function. Currently that aborts at runtime, but while C does warn, C++ does not warn.
I see, maybe for clarity you could open a separate enhancement-type PR.
(In reply to Paolo Carlini from comment #9) > I see, maybe for clarity you could open a separate enhancement-type PR. Done: pr82466