Bug 71973 - c++ handles built-in functions inconsistently
Summary: c++ handles built-in functions inconsistently
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: 7.0
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
Depends on:
Blocks:
 
Reported: 2016-07-22 15:53 UTC by Bernd Edlinger
Modified: 2017-10-07 18:28 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.5.3, 4.8.3, 4.9.3, 5.3.0, 6.1.0, 7.0
Last reconfirmed: 2016-07-22 00:00:00


Attachments
possible patch (693 bytes, patch)
2016-08-18 20:38 UTC, Bernd Edlinger
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Bernd Edlinger 2016-07-22 15:53:09 UTC
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();
}
Comment 1 Bernd Edlinger 2016-07-22 17:40:18 UTC
the bug goes away, if the fork signature is correct.


extern "C"
int fork () __attribute__((nothrow));

void bar () throw()
{
  fork ();
}

does the right thing.
Comment 2 Martin Sebor 2016-07-22 18:52:03 UTC
Confirmed.  It doesn't look like G++ ever rejected such invalid code.
Comment 3 Bernd Edlinger 2016-08-18 20:38:53 UTC
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....
Comment 4 Bernd Edlinger 2016-11-04 15:31:24 UTC
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
Comment 5 Bernd Edlinger 2016-11-21 14:17:37 UTC
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
Comment 6 Jakub Jelinek 2016-11-21 18:55:43 UTC
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
Comment 7 Paolo Carlini 2017-10-07 16:41:06 UTC
Then fixed in 7.1.0, right?
Comment 8 Bernd Edlinger 2017-10-07 16:47:03 UTC
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.
Comment 9 Paolo Carlini 2017-10-07 16:57:14 UTC
I see, maybe for clarity you could open a separate enhancement-type PR.
Comment 10 Bernd Edlinger 2017-10-07 18:28:07 UTC
(In reply to Paolo Carlini from comment #9)
> I see, maybe for clarity you could open a separate enhancement-type PR.

Done: pr82466