Message ID | AM4PR0701MB21623781CE7CE49B190E86F0E4D00@AM4PR0701MB2162.eurprd07.prod.outlook.com |
---|---|
State | Superseded |
Headers | show |
Hi! I'd like to ping for my patch here: https://gcc.gnu.org/ml/gcc-patches/2016-10/msg01348.html Thanks Bernd. On 10/17/16 21:18, Bernd Edlinger wrote: > On 10/17/16 20:05, Joseph Myers wrote: >> On Sun, 16 Oct 2016, Bernd Edlinger wrote: >> >>> Second, the declaration in the glibc header files simply look wrong, >>> because the type of argv, and envp is "char *const *" while the >>> builtin function wants "const char**", thus only the array of char* >>> itself is const, not the actual char stings they point to. >> >> char *const * is the POSIX type. (It can't be const char ** or const >> char >> *const * because you can't convert char ** implicitly to those types in >> ISO C.) You'd need to check the list archives for rationale for the >> built-in functions doing something different. >> > > Yes, that was discussed here: > https://gcc.gnu.org/ml/gcc-patches/2004-03/msg01148.html > > No mention why the BT_PTR_CONST_TYPE does not match the posix type. > But the right types were used on __gcov_execv/e/p stubs, so the author > did know the right types at least. > > So I think that was broken from the beginning, but that was hidden by > the loose checking in the C FE and not warning in the C++ FE when > prototypes don't match. > >>> Third, in C the builtins are not diagnosed, because C does only look >>> at the mode of the parameters see match_builtin_function_types in >>> c/c-decl.c, which may itself be wrong, because that makes an ABI >>> decision dependent on the mode of the parameter. >> >> The matching needs to be loose because of functions using types such as >> FILE * where the compiler doesn't know the exact contents of the type >> when >> processing built-in function definitions. (Historically there were also >> issues with pre-ISO headers, but that may be less relevant now.) >> > > The C++ FE has exactly the same problem with FILE* and struct tm* > but it solves it differently and "learns" the type but only for FILE* > and with this patch also for const struct tm*. It is a lot more > restrictive than C, but that is because of the ++ ;) > > Well in that case the posix functions have to use the prototypes > from POSIX.1.2008 although their rationale is a bit silly... > > This updated patch fixes the prototype of execv/p/e, > and adds a new test case that checks that no type conflict > exists in the execve built-in any more. > > Now we have no -Wsystem-headers warnings with glibc-headers any more. > And the gcov builtin also is working with C++. > > Bootstrapped and reg-tested on x86_64-pc-linux-gnu. > Is it OK for trunk? > > > Thanks > Bernd.
Ping... On 10/24/16 15:36, Bernd Edlinger wrote: > Hi! > > I'd like to ping for my patch here: > https://gcc.gnu.org/ml/gcc-patches/2016-10/msg01348.html > > > Thanks > Bernd. > > On 10/17/16 21:18, Bernd Edlinger wrote: >> On 10/17/16 20:05, Joseph Myers wrote: >>> On Sun, 16 Oct 2016, Bernd Edlinger wrote: >>> >>>> Second, the declaration in the glibc header files simply look wrong, >>>> because the type of argv, and envp is "char *const *" while the >>>> builtin function wants "const char**", thus only the array of char* >>>> itself is const, not the actual char stings they point to. >>> >>> char *const * is the POSIX type. (It can't be const char ** or const >>> char >>> *const * because you can't convert char ** implicitly to those types in >>> ISO C.) You'd need to check the list archives for rationale for the >>> built-in functions doing something different. >>> >> >> Yes, that was discussed here: >> https://gcc.gnu.org/ml/gcc-patches/2004-03/msg01148.html >> >> No mention why the BT_PTR_CONST_TYPE does not match the posix type. >> But the right types were used on __gcov_execv/e/p stubs, so the author >> did know the right types at least. >> >> So I think that was broken from the beginning, but that was hidden by >> the loose checking in the C FE and not warning in the C++ FE when >> prototypes don't match. >> >>>> Third, in C the builtins are not diagnosed, because C does only look >>>> at the mode of the parameters see match_builtin_function_types in >>>> c/c-decl.c, which may itself be wrong, because that makes an ABI >>>> decision dependent on the mode of the parameter. >>> >>> The matching needs to be loose because of functions using types such as >>> FILE * where the compiler doesn't know the exact contents of the type >>> when >>> processing built-in function definitions. (Historically there were also >>> issues with pre-ISO headers, but that may be less relevant now.) >>> >> >> The C++ FE has exactly the same problem with FILE* and struct tm* >> but it solves it differently and "learns" the type but only for FILE* >> and with this patch also for const struct tm*. It is a lot more >> restrictive than C, but that is because of the ++ ;) >> >> Well in that case the posix functions have to use the prototypes >> from POSIX.1.2008 although their rationale is a bit silly... >> >> This updated patch fixes the prototype of execv/p/e, >> and adds a new test case that checks that no type conflict >> exists in the execve built-in any more. >> >> Now we have no -Wsystem-headers warnings with glibc-headers any more. >> And the gcov builtin also is working with C++. >> >> Bootstrapped and reg-tested on x86_64-pc-linux-gnu. >> Is it OK for trunk? >> >> >> Thanks >> Bernd.
On 10/17/2016 03:18 PM, Bernd Edlinger wrote: > Regarding this hunk: > > /* Whether or not the builtin can throw exceptions has no > bearing on this declarator. */ > - TREE_NOTHROW (olddecl) = 0; > + TREE_NOTHROW (olddecl) = TREE_NOTHROW (newdecl); > > You may ask, why the old code was working most of the time. > I think, usually, when types_match == true, there happens another > assignment to TREE_NOTHROW, later in that function around line 2183: > > /* Merge the type qualifiers. */ > if (TREE_READONLY (newdecl)) > TREE_READONLY (olddecl) = 1; > if (TREE_THIS_VOLATILE (newdecl)) > TREE_THIS_VOLATILE (olddecl) = 1; > if (TREE_NOTHROW (newdecl)) > TREE_NOTHROW (olddecl) = 1; > > This is in a big "if (types_match)", so I think that explains, > why the old code did work normally, and why it fails if the > parameter don't match, but I still have no idea what to say > in the comment, except that the code should exactly do what > the comment above says. I think a better fix would be to add a copy of TREE_NOTHROW to the else block of the if (types_match), to go with the existing copies of TREE_READONLY and TREE_THIS_VOLATILE. But yes, duplicate_decls is a mess. Jason
On 10/17/2016 03:18 PM, Bernd Edlinger wrote: > +@item -Wbuiltin-function-redefined @r{(C++ and Objective-C++ only)} > +@opindex Wbuiltin-function-redefined > +@opindex Wno-builtin-function-redefined > +Do warn if built-in functions are redefined. This option is only > +supported for C++ and Objective-C++. It is implied by @option{-Wall}, > +which can be disabled with @option{-Wno-builtin-function-redefined}. There's no redefinition here (only a redeclaration), so perhaps -Wbuiltin-redeclaration-mismatch? I'm not even sure we need a new warning. Can we combine this warning with the block that currently follows? > else if ((DECL_EXTERN_C_P (newdecl) > && DECL_EXTERN_C_P (olddecl)) > || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), > TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) > { > /* A near match; override the builtin. */ > > if (TREE_PUBLIC (newdecl)) > warning_at (DECL_SOURCE_LOCATION (newdecl), 0, > "new declaration %q#D ambiguates built-in " > "declaration %q#D", newdecl, olddecl); > else > warning (OPT_Wshadow, > DECL_BUILT_IN (olddecl) > ? G_("shadowing built-in function %q#D") > : G_("shadowing library function %q#D"), olddecl); > } It seems to me that if we have an extern "C" declaration that doesn't match the built-in, we should just warn. I looked at some of the testcases you mentioned in the bug report, and those declarations aren't extern "C", so we shouldn't be warning about them. Does your current patch still warn about those? Jason
On 11/01/16 16:02, Jason Merrill wrote: > On 10/17/2016 03:18 PM, Bernd Edlinger wrote: >> Regarding this hunk: >> >> /* Whether or not the builtin can throw exceptions has no >> bearing on this declarator. */ >> - TREE_NOTHROW (olddecl) = 0; >> + TREE_NOTHROW (olddecl) = TREE_NOTHROW (newdecl); >> >> You may ask, why the old code was working most of the time. >> I think, usually, when types_match == true, there happens another >> assignment to TREE_NOTHROW, later in that function around line 2183: >> >> /* Merge the type qualifiers. */ >> if (TREE_READONLY (newdecl)) >> TREE_READONLY (olddecl) = 1; >> if (TREE_THIS_VOLATILE (newdecl)) >> TREE_THIS_VOLATILE (olddecl) = 1; >> if (TREE_NOTHROW (newdecl)) >> TREE_NOTHROW (olddecl) = 1; >> >> This is in a big "if (types_match)", so I think that explains, >> why the old code did work normally, and why it fails if the >> parameter don't match, but I still have no idea what to say >> in the comment, except that the code should exactly do what >> the comment above says. > > I think a better fix would be to add a copy of TREE_NOTHROW to the else > block of the if (types_match), to go with the existing copies of > TREE_READONLY and TREE_THIS_VOLATILE. But yes, duplicate_decls is a mess. > Possibly, but I am only aware of problems with redeclarations of builtins functions, TREE_CODE (olddecl) == FUNCTION_DECL && DECL_ARTIFICIAL (olddecl), but the "if (types_match)" can be called for many other types of decls. So super scary code here....
On 11/01/16 16:20, Jason Merrill wrote: > On 10/17/2016 03:18 PM, Bernd Edlinger wrote: >> +@item -Wbuiltin-function-redefined @r{(C++ and Objective-C++ only)} >> +@opindex Wbuiltin-function-redefined >> +@opindex Wno-builtin-function-redefined >> +Do warn if built-in functions are redefined. This option is only >> +supported for C++ and Objective-C++. It is implied by @option{-Wall}, >> +which can be disabled with @option{-Wno-builtin-function-redefined}. > > There's no redefinition here (only a redeclaration), so perhaps > -Wbuiltin-redeclaration-mismatch? > Works for me. Thanks. > I'm not even sure we need a new warning. Can we combine this warning > with the block that currently follows? > After 20 years of not having a warning on that, an implicitly enabled warning would at least break lots of bogus test cases. Of course in C we have an implicitly enabled warning, so I would like to at least enable the warning on -Wall, thus -Wshadow is too weak IMO. >> else if ((DECL_EXTERN_C_P (newdecl) >> && DECL_EXTERN_C_P (olddecl)) >> || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), >> TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) >> { >> /* A near match; override the builtin. */ >> >> if (TREE_PUBLIC (newdecl)) >> warning_at (DECL_SOURCE_LOCATION (newdecl), 0, >> "new declaration %q#D ambiguates built-in " >> "declaration %q#D", newdecl, olddecl); >> else >> warning (OPT_Wshadow, >> DECL_BUILT_IN (olddecl) >> ? G_("shadowing built-in function %q#D") >> : G_("shadowing library function %q#D"), >> olddecl); >> } > > It seems to me that if we have an extern "C" declaration that doesn't > match the built-in, we should just warn. > > I looked at some of the testcases you mentioned in the bug report, and > those declarations aren't extern "C", so we shouldn't be warning about > them. Does your current patch still warn about those? > No. After looking at the false positives with the previous patch, I changed my mind about that. This started because I wanted to add builtin functions for some special_function_p names. And I wanted to warn the user if he uses a name that is recognized by special_function_p, but the parameters don't match. Now I think we need to teach special_function_p to distinguish "C" functions from "C++" functions, which it currently cannot do, because that knowledge is only in the C++ FE. Bernd.
On Tue, Nov 1, 2016 at 11:45 AM, Bernd Edlinger <bernd.edlinger@hotmail.de> wrote: > On 11/01/16 16:20, Jason Merrill wrote: >> On 10/17/2016 03:18 PM, Bernd Edlinger wrote: >> I'm not even sure we need a new warning. Can we combine this warning >> with the block that currently follows? > > After 20 years of not having a warning on that, > an implicitly enabled warning would at least break lots of bogus > test cases. Would it, though? Which test cases still break with the current patch? > Of course in C we have an implicitly enabled warning, > so I would like to at least enable the warning on -Wall, thus > -Wshadow is too weak IMO. Right. The -Wshadow warning is for file-local declarations, so that doesn't apply to your testcase; I was thinking that we should hit the first (currently unconditional) warning. >>> else if ((DECL_EXTERN_C_P (newdecl) >>> && DECL_EXTERN_C_P (olddecl)) >>> || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), >>> TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) So I was thinking to drop the "else" and the compparms test. >>> { >>> /* A near match; override the builtin. */ >>> >>> if (TREE_PUBLIC (newdecl)) >>> warning_at (DECL_SOURCE_LOCATION (newdecl), 0, >>> "new declaration %q#D ambiguates built-in " >>> "declaration %q#D", newdecl, olddecl); So we would hit this warning. And change the message to remove "ambiguates", since we're removing the compparms. > This started because I wanted to add builtin functions for some > special_function_p names. And I wanted to warn the user if he uses a > name that is recognized by special_function_p, but the parameters > don't match. Now I think we need to teach special_function_p to > distinguish "C" functions from "C++" functions, which it currently > cannot do, because that knowledge is only in the C++ FE. It could look at DECL_ASSEMBLER_NAME rather than DECL_NAME? Jason
On 11/01/16 18:11, Jason Merrill wrote: > On Tue, Nov 1, 2016 at 11:45 AM, Bernd Edlinger > <bernd.edlinger@hotmail.de> wrote: >> On 11/01/16 16:20, Jason Merrill wrote: >>> On 10/17/2016 03:18 PM, Bernd Edlinger wrote: >>> I'm not even sure we need a new warning. Can we combine this warning >>> with the block that currently follows? >> >> After 20 years of not having a warning on that, >> an implicitly enabled warning would at least break lots of bogus >> test cases. > > Would it, though? Which test cases still break with the current patch? > Less than before, but there are still at least a few of them. I can make a list and send it tomorrow. >> Of course in C we have an implicitly enabled warning, >> so I would like to at least enable the warning on -Wall, thus >> -Wshadow is too weak IMO. > > Right. The -Wshadow warning is for file-local declarations, so that > doesn't apply to your testcase; I was thinking that we should hit the > first (currently unconditional) warning. > >>>> else if ((DECL_EXTERN_C_P (newdecl) >>>> && DECL_EXTERN_C_P (olddecl)) >>>> || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), >>>> TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) > > So I was thinking to drop the "else" and the compparms test. > Yes. But then we must somehow avoid: else /* Discard the old built-in function. */ return NULL_TREE; It maybe easier, just to copy the warning to the DECL_ANTICIPATED case? >>>> { >>>> /* A near match; override the builtin. */ >>>> >>>> if (TREE_PUBLIC (newdecl)) >>>> warning_at (DECL_SOURCE_LOCATION (newdecl), 0, >>>> "new declaration %q#D ambiguates built-in " >>>> "declaration %q#D", newdecl, olddecl); > > So we would hit this warning. And change the message to remove > "ambiguates", since we're removing the compparms. > >> This started because I wanted to add builtin functions for some >> special_function_p names. And I wanted to warn the user if he uses a >> name that is recognized by special_function_p, but the parameters >> don't match. Now I think we need to teach special_function_p to >> distinguish "C" functions from "C++" functions, which it currently >> cannot do, because that knowledge is only in the C++ FE. > > It could look at DECL_ASSEMBLER_NAME rather than DECL_NAME? > Yes. I think previously special_function_p must have used the DECL_ASSEMBLER_NAME, at least the comments still mention that. Also for a "C" function there are target specific naming rules, some prepend an underscore, some don't, and more, especially W..DOS has special conventions IIRC. Maybe a language callback would be good to have for this task. So that special_function_p can easily check if something is a C++ function, then it is immediately clear that it is not a special function. Bernd.
On Tue, Nov 1, 2016 at 2:15 PM, Bernd Edlinger <bernd.edlinger@hotmail.de> wrote: > On 11/01/16 18:11, Jason Merrill wrote: >> On Tue, Nov 1, 2016 at 11:45 AM, Bernd Edlinger >> <bernd.edlinger@hotmail.de> wrote: >>> On 11/01/16 16:20, Jason Merrill wrote: >>>> On 10/17/2016 03:18 PM, Bernd Edlinger wrote: >>>> I'm not even sure we need a new warning. Can we combine this warning >>>> with the block that currently follows? >>> >>> After 20 years of not having a warning on that, >>> an implicitly enabled warning would at least break lots of bogus >>> test cases. >> >> Would it, though? Which test cases still break with the current patch? > > Less than before, but there are still at least a few of them. > > I can make a list and send it tomorrow. > >>> Of course in C we have an implicitly enabled warning, >>> so I would like to at least enable the warning on -Wall, thus >>> -Wshadow is too weak IMO. >> >> Right. The -Wshadow warning is for file-local declarations, so that >> doesn't apply to your testcase; I was thinking that we should hit the >> first (currently unconditional) warning. >> >>>>> else if ((DECL_EXTERN_C_P (newdecl) >>>>> && DECL_EXTERN_C_P (olddecl)) >>>>> || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), >>>>> TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) >> >> So I was thinking to drop the "else" and the compparms test. > > Yes. But then we must somehow avoid: > > else > /* Discard the old built-in function. */ > return NULL_TREE; > > It maybe easier, just to copy the warning to the DECL_ANTICIPATED case? Or even move it there; removing the existing warning doesn't change anything in the testsuite, and I'm having trouble imagining how to trigger it. Jason
On 11/01/16 20:48, Jason Merrill wrote: >>>>>> else if ((DECL_EXTERN_C_P (newdecl) >>>>>> && DECL_EXTERN_C_P (olddecl)) >>>>>> || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), >>>>>> TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) >>> >>> So I was thinking to drop the "else" and the compparms test. >> >> Yes. But then we must somehow avoid: >> >> else >> /* Discard the old built-in function. */ >> return NULL_TREE; >> >> It maybe easier, just to copy the warning to the DECL_ANTICIPATED case? > > Or even move it there; removing the existing warning doesn't change > anything in the testsuite, and I'm having trouble imagining how to > trigger it. > Nice. It must be something, which does not anticipate a declaration. like: cat test.cc int __builtin_abort(void*); g++ -c test.cc test.cc:1:5: warning: new declaration 'int __builtin_abort(void*)' ambiguates built-in declaration 'void __builtin_abort()' int __builtin_abort(void*); ^~~~~~~~~~~~~~~ Intersting, the warning comes even though I forgot to add the extern "C". Bernd.
On Tue, Nov 1, 2016 at 4:00 PM, Bernd Edlinger <bernd.edlinger@hotmail.de> wrote: > On 11/01/16 20:48, Jason Merrill wrote: >>>>>>> else if ((DECL_EXTERN_C_P (newdecl) >>>>>>> && DECL_EXTERN_C_P (olddecl)) >>>>>>> || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), >>>>>>> TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) >>>> >>>> So I was thinking to drop the "else" and the compparms test. >>> >>> Yes. But then we must somehow avoid: >>> >>> else >>> /* Discard the old built-in function. */ >>> return NULL_TREE; >>> It maybe easier, just to copy the warning to the DECL_ANTICIPATED case? >> >> Or even move it there; removing the existing warning doesn't change >> anything in the testsuite, and I'm having trouble imagining how to >> trigger it. >> > > Nice. It must be something, which does not anticipate a declaration. > > like: > > cat test.cc > int __builtin_abort(void*); > > g++ -c test.cc > test.cc:1:5: warning: new declaration 'int __builtin_abort(void*)' > ambiguates built-in declaration 'void __builtin_abort()' > int __builtin_abort(void*); > ^~~~~~~~~~~~~~~ > > Intersting, the warning comes even though I forgot to add the > extern "C". Looks like anything starting with __builtin is implicitly extern "C" (set in grokfndecl). If we remove the DECL_ANTICIPATED check, I see some failures in builtin* tests due to missing extern "C". That seems appropriate at file scope, but I'm not sure it's right for namespace std. Jason
On 11/01/16 19:15, Bernd Edlinger wrote: > On 11/01/16 18:11, Jason Merrill wrote: >> On Tue, Nov 1, 2016 at 11:45 AM, Bernd Edlinger >> <bernd.edlinger@hotmail.de> wrote: >>> On 11/01/16 16:20, Jason Merrill wrote: >>>> On 10/17/2016 03:18 PM, Bernd Edlinger wrote: >>>> I'm not even sure we need a new warning. Can we combine this warning >>>> with the block that currently follows? >>> >>> After 20 years of not having a warning on that, >>> an implicitly enabled warning would at least break lots of bogus >>> test cases. >> >> Would it, though? Which test cases still break with the current patch? >> > > Less than before, but there are still at least a few of them. > > I can make a list and send it tomorrow. > 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/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/new15.C -std=c++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-1.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/ipa/inline-2.C -std=gnu++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/tc1/dr20.C -std=c++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-1.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/inline-2.C -std=gnu++98 (test for excess errors) FAIL: g++.dg/lto/20080908-1 cp_lto_20080908-1_0.o assemble, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin FAIL: g++.dg/lto/20080908-1 cp_lto_20080908-1_0.o assemble, -O0 -flto -flto-partition=none -fuse-linker-plugin FAIL: g++.dg/lto/20080908-1 cp_lto_20080908-1_0.o assemble, -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects FAIL: g++.dg/lto/20080908-1 cp_lto_20080908-1_0.o assemble, -O2 -flto -flto-partition=1to1 -fno-use-linker-plugin FAIL: g++.dg/lto/20080908-1 cp_lto_20080908-1_0.o assemble, -O2 -flto -flto-partition=none -fuse-linker-plugin -fno-fat-lto-objects FAIL: g++.dg/lto/20080908-1 cp_lto_20080908-1_0.o assemble, -O2 -flto -fuse-linker-plugin FAIL: g++.dg/lto/pr68811 cp_lto_pr68811_0.o assemble, -O2 FAIL: g++.old-deja/g++.law/except1.C -std=gnu++11 (test for excess errors) FAIL: g++.old-deja/g++.law/except1.C -std=gnu++14 (test for excess errors) FAIL: g++.old-deja/g++.law/except1.C -std=gnu++98 (test for excess errors) FAIL: g++.old-deja/g++.mike/p700.C -std=gnu++11 (test for excess errors) FAIL: g++.old-deja/g++.mike/p700.C -std=gnu++14 (test for excess errors) FAIL: g++.old-deja/g++.mike/p700.C -std=gnu++98 (test for excess errors) FAIL: g++.old-deja/g++.other/builtins10.C -std=c++11 (test for excess errors) FAIL: g++.old-deja/g++.other/builtins10.C -std=c++14 (test for excess errors) FAIL: g++.old-deja/g++.other/realloc.C -std=c++11 (test for excess errors) FAIL: g++.old-deja/g++.other/realloc.C -std=c++14 (test for excess errors) FAIL: g++.old-deja/g++.other/realloc.C -std=c++98 (test for excess errors) FAIL: g++.old-deja/g++.other/vbase5.C -std=c++11 (test for excess errors) FAIL: g++.old-deja/g++.other/vbase5.C -std=c++14 (test for excess errors) FAIL: g++.old-deja/g++.other/vbase5.C -std=c++98 (test for excess errors) The lto test case does emit the warning when assembling, but it still produces an executable and even executes it. Also g++.dg/cpp1y/lambda-generic-udt.C, g++.dg/tc1/dr20.C and g++.old-deja/g++.other/vbase5.C are execution tests. So I was wrong to assume these were all compile-only tests. I think that list should be fixable, if we decide to enable the warning by default. >>> Of course in C we have an implicitly enabled warning, >>> so I would like to at least enable the warning on -Wall, thus >>> -Wshadow is too weak IMO. >> >> Right. The -Wshadow warning is for file-local declarations, so that >> doesn't apply to your testcase; I was thinking that we should hit the >> first (currently unconditional) warning. >> >>>>> else if ((DECL_EXTERN_C_P (newdecl) >>>>> && DECL_EXTERN_C_P (olddecl)) >>>>> || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), >>>>> TYPE_ARG_TYPES (TREE_TYPE >>>>> (olddecl)))) >> >> So I was thinking to drop the "else" and the compparms test. >> > > Yes. But then we must somehow avoid: > > else > /* Discard the old built-in function. */ > return NULL_TREE; > > It maybe easier, just to copy the warning to the DECL_ANTICIPATED case? > >>>>> { >>>>> /* A near match; override the builtin. */ >>>>> >>>>> if (TREE_PUBLIC (newdecl)) >>>>> warning_at (DECL_SOURCE_LOCATION (newdecl), 0, >>>>> "new declaration %q#D ambiguates >>>>> built-in " >>>>> "declaration %q#D", newdecl, olddecl); >> >> So we would hit this warning. And change the message to remove >> "ambiguates", since we're removing the compparms. >> >>> This started because I wanted to add builtin functions for some >>> special_function_p names. And I wanted to warn the user if he uses a >>> name that is recognized by special_function_p, but the parameters >>> don't match. Now I think we need to teach special_function_p to >>> distinguish "C" functions from "C++" functions, which it currently >>> cannot do, because that knowledge is only in the C++ FE. >> >> It could look at DECL_ASSEMBLER_NAME rather than DECL_NAME? >> > > Yes. I think previously special_function_p must have used the > DECL_ASSEMBLER_NAME, at least the comments still mention that. > > Also for a "C" function there are target specific naming rules, > some prepend an underscore, some don't, and more, especially > W..DOS has special conventions IIRC. > > Maybe a language callback would be good to have for this task. > So that special_function_p can easily check if something is a > C++ function, then it is immediately clear that it is not a > special function. > > > > Bernd.
On 11/02/16 07:11, Bernd Edlinger wrote: > On 11/01/16 19:15, Bernd Edlinger wrote: >> On 11/01/16 18:11, Jason Merrill wrote: >>> On Tue, Nov 1, 2016 at 11:45 AM, Bernd Edlinger >>> <bernd.edlinger@hotmail.de> wrote: >>>> On 11/01/16 16:20, Jason Merrill wrote: >>>>> On 10/17/2016 03:18 PM, Bernd Edlinger wrote: >>>>> I'm not even sure we need a new warning. Can we combine this warning >>>>> with the block that currently follows? >>>> >>>> After 20 years of not having a warning on that, >>>> an implicitly enabled warning would at least break lots of bogus >>>> test cases. >>> >>> Would it, though? Which test cases still break with the current patch? >>> >> >> Less than before, but there are still at least a few of them. >> >> I can make a list and send it tomorrow. >> > > 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/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/new15.C -std=c++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-1.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/ipa/inline-2.C -std=gnu++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/tc1/dr20.C -std=c++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-1.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/inline-2.C -std=gnu++98 (test for excess errors) > FAIL: g++.dg/lto/20080908-1 cp_lto_20080908-1_0.o assemble, -O0 -flto > -flto-partition=1to1 -fno-use-linker-plugin > FAIL: g++.dg/lto/20080908-1 cp_lto_20080908-1_0.o assemble, -O0 -flto > -flto-partition=none -fuse-linker-plugin > FAIL: g++.dg/lto/20080908-1 cp_lto_20080908-1_0.o assemble, -O0 -flto > -fuse-linker-plugin -fno-fat-lto-objects > FAIL: g++.dg/lto/20080908-1 cp_lto_20080908-1_0.o assemble, -O2 -flto > -flto-partition=1to1 -fno-use-linker-plugin > FAIL: g++.dg/lto/20080908-1 cp_lto_20080908-1_0.o assemble, -O2 -flto > -flto-partition=none -fuse-linker-plugin -fno-fat-lto-objects > FAIL: g++.dg/lto/20080908-1 cp_lto_20080908-1_0.o assemble, -O2 -flto > -fuse-linker-plugin > FAIL: g++.dg/lto/pr68811 cp_lto_pr68811_0.o assemble, -O2 > FAIL: g++.old-deja/g++.law/except1.C -std=gnu++11 (test for excess errors) > FAIL: g++.old-deja/g++.law/except1.C -std=gnu++14 (test for excess errors) > FAIL: g++.old-deja/g++.law/except1.C -std=gnu++98 (test for excess errors) > FAIL: g++.old-deja/g++.mike/p700.C -std=gnu++11 (test for excess errors) > FAIL: g++.old-deja/g++.mike/p700.C -std=gnu++14 (test for excess errors) > FAIL: g++.old-deja/g++.mike/p700.C -std=gnu++98 (test for excess errors) > FAIL: g++.old-deja/g++.other/builtins10.C -std=c++11 (test for excess > errors) > FAIL: g++.old-deja/g++.other/builtins10.C -std=c++14 (test for excess > errors) > FAIL: g++.old-deja/g++.other/realloc.C -std=c++11 (test for excess errors) > FAIL: g++.old-deja/g++.other/realloc.C -std=c++14 (test for excess errors) > FAIL: g++.old-deja/g++.other/realloc.C -std=c++98 (test for excess errors) > FAIL: g++.old-deja/g++.other/vbase5.C -std=c++11 (test for excess errors) > FAIL: g++.old-deja/g++.other/vbase5.C -std=c++14 (test for excess errors) > FAIL: g++.old-deja/g++.other/vbase5.C -std=c++98 (test for excess errors) > > > The lto test case does emit the warning when assembling, but > it still produces an executable and even executes it. > > Also g++.dg/cpp1y/lambda-generic-udt.C, g++.dg/tc1/dr20.C > and g++.old-deja/g++.other/vbase5.C are execution tests. > > So I was wrong to assume these were all compile-only tests. > > I think that list should be fixable, if we decide to enable > the warning by default. > Aehm, sorry. I forgot to look at other languages... === obj-c++ tests === Running target unix FAIL: obj-c++.dg/lto/trivial-1 obj_cpp_lto_trivial-1_0.o assemble, -O0 -flto -fg nu-runtime FAIL: obj-c++.dg/lto/trivial-1 obj_cpp_lto_trivial-1_0.o assemble, -O2 -flto -fg nu-runtime FAIL: obj-c++.dg/lto/trivial-1 obj_cpp_lto_trivial-1_0.o assemble, -O0 -flto -fl to-partition=none -fgnu-runtime FAIL: obj-c++.dg/lto/trivial-1 obj_cpp_lto_trivial-1_0.o assemble, -O2 -flto -fl to-partition=none -fgnu-runtime === libitm tests === Running target unix FAIL: libitm.c++/dropref.C (test for excess errors) FAIL: libitm.c++/throwdown.C (test for excess errors) Bernd.
On 11/01/16 22:31, Jason Merrill wrote: > On Tue, Nov 1, 2016 at 4:00 PM, Bernd Edlinger > <bernd.edlinger@hotmail.de> wrote: >> On 11/01/16 20:48, Jason Merrill wrote: >>>>>>>> else if ((DECL_EXTERN_C_P (newdecl) >>>>>>>> && DECL_EXTERN_C_P (olddecl)) >>>>>>>> || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), >>>>>>>> TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) >>>>> >>>>> So I was thinking to drop the "else" and the compparms test. >>>> >>>> Yes. But then we must somehow avoid: >>>> >>>> else >>>> /* Discard the old built-in function. */ >>>> return NULL_TREE; > >>>> It maybe easier, just to copy the warning to the DECL_ANTICIPATED case? >>> >>> Or even move it there; removing the existing warning doesn't change >>> anything in the testsuite, and I'm having trouble imagining how to >>> trigger it. >>> >> >> Nice. It must be something, which does not anticipate a declaration. >> >> like: >> >> cat test.cc >> int __builtin_abort(void*); >> >> g++ -c test.cc >> test.cc:1:5: warning: new declaration 'int __builtin_abort(void*)' >> ambiguates built-in declaration 'void __builtin_abort()' >> int __builtin_abort(void*); >> ^~~~~~~~~~~~~~~ >> >> Intersting, the warning comes even though I forgot to add the >> extern "C". > > Looks like anything starting with __builtin is implicitly extern "C" > (set in grokfndecl). > Oh, Well. we do also have such builtins that begin with __sync_ like extern "C" unsigned char __sync_fetch_and_add_1(volatile void*, unsigned char); > If we remove the DECL_ANTICIPATED check, I see some failures in > builtin* tests due to missing extern "C". That seems appropriate at > file scope, but I'm not sure it's right for namespace std. > Interesting, what have you done? Sounds a bit like the issue I had with the std::abs overloads. To get rid of that I added this in the DECL_ANTICIPATED path: + /* A new declaration doesn't match a built-in one unless it + is also extern "C". */ + gcc_assert (DECL_IS_BUILTIN (olddecl)); + gcc_assert (DECL_EXTERN_C_P (olddecl)); + if (!DECL_EXTERN_C_P (newdecl)) + return NULL_TREE; + Bernd.
Index: gcc/builtin-types.def =================================================================== --- gcc/builtin-types.def (revision 241271) +++ gcc/builtin-types.def (working copy) @@ -103,6 +103,7 @@ DEF_PRIMITIVE_TYPE (BT_COMPLEX_LONGDOUBLE, complex DEF_PRIMITIVE_TYPE (BT_PTR, ptr_type_node) DEF_PRIMITIVE_TYPE (BT_FILEPTR, fileptr_type_node) +DEF_PRIMITIVE_TYPE (BT_CONST_TM_PTR, const_tm_ptr_type_node) DEF_PRIMITIVE_TYPE (BT_CONST_PTR, const_ptr_type_node) DEF_PRIMITIVE_TYPE (BT_VOLATILE_PTR, build_pointer_type @@ -146,7 +147,12 @@ DEF_PRIMITIVE_TYPE (BT_I16, builtin_type_for_size DEF_PRIMITIVE_TYPE (BT_BND, pointer_bounds_type_node) -DEF_POINTER_TYPE (BT_PTR_CONST_STRING, BT_CONST_STRING) +/* The C type `char * const *'. */ +DEF_PRIMITIVE_TYPE (BT_PTR_CONST_STRING, + build_pointer_type + (build_qualified_type (string_type_node, + TYPE_QUAL_CONST))) + DEF_POINTER_TYPE (BT_PTR_UINT, BT_UINT) DEF_POINTER_TYPE (BT_PTR_LONG, BT_LONG) DEF_POINTER_TYPE (BT_PTR_ULONG, BT_ULONG) @@ -511,8 +517,8 @@ DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZ BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR) DEF_FUNCTION_TYPE_4 (BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG, BT_INT, BT_STRING, BT_SIZE, BT_CONST_STRING, BT_VALIST_ARG) -DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, - BT_SIZE, BT_STRING, BT_SIZE, BT_CONST_STRING, BT_CONST_PTR) +DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_TM_PTR, + BT_SIZE, BT_STRING, BT_SIZE, BT_CONST_STRING, BT_CONST_TM_PTR) DEF_FUNCTION_TYPE_4 (BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, BT_PTR, BT_PTR, BT_CONST_PTR, BT_SIZE, BT_SIZE) DEF_FUNCTION_TYPE_4 (BT_FN_PTR_PTR_INT_SIZE_SIZE, Index: gcc/builtins.def =================================================================== --- gcc/builtins.def (revision 241271) +++ gcc/builtins.def (working copy) @@ -866,7 +866,7 @@ DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, " DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL) DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_RT_NOTHROW_LEAF_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4) -DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0) +DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_TM_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0) DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LEAF_LIST) DEF_GCC_BUILTIN (BUILT_IN_UNREACHABLE, "unreachable", BT_FN_VOID, ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST) DEF_GCC_BUILTIN (BUILT_IN_UNWIND_INIT, "unwind_init", BT_FN_VOID, ATTR_NULL) Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c (revision 241271) +++ gcc/c-family/c-common.c (working copy) @@ -4278,9 +4278,13 @@ c_common_nodes_and_builtins (void) } if (c_dialect_cxx ()) - /* For C++, make fileptr_type_node a distinct void * type until - FILE type is defined. */ - fileptr_type_node = build_variant_type_copy (ptr_type_node); + { + /* For C++, make fileptr_type_node a distinct void * type until + FILE type is defined. */ + fileptr_type_node = build_variant_type_copy (ptr_type_node); + /* Likewise for const struct tm*. */ + const_tm_ptr_type_node = build_variant_type_copy (const_ptr_type_node); + } record_builtin_type (RID_VOID, NULL, void_type_node); Index: gcc/c-family/c.opt =================================================================== --- gcc/c-family/c.opt (revision 241271) +++ gcc/c-family/c.opt (working copy) @@ -323,6 +323,10 @@ Wframe-address C ObjC C++ ObjC++ Var(warn_frame_address) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Warn when __builtin_frame_address or __builtin_return_address is used unsafely. +Wbuiltin-function-redefined +C++ ObjC++ Var(warn_builtin_function_redefined) Warning LangEnabledBy(C++ ObjC++,Wall) +Warn when a built-in function is redefined. + Wbuiltin-macro-redefined C ObjC C++ ObjC++ CPP(warn_builtin_macro_redefined) CppReason(CPP_W_BUILTIN_MACRO_REDEFINED) Var(cpp_warn_builtin_macro_redefined) Init(1) Warning Warn when a built-in preprocessor macro is undefined or redefined. Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 241271) +++ gcc/cp/decl.c (working copy) @@ -1489,10 +1489,15 @@ duplicate_decls (tree newdecl, tree olddecl, bool explicitly declared. */ if (DECL_ANTICIPATED (olddecl)) { - /* Deal with fileptr_type_node. FILE type is not known - at the time we create the builtins. */ tree t1, t2; + /* A new declaration doesn't match a built-in one unless it + is also extern "C". */ + gcc_assert (DECL_IS_BUILTIN (olddecl)); + gcc_assert (DECL_EXTERN_C_P (olddecl)); + if (!DECL_EXTERN_C_P (newdecl)) + return NULL_TREE; + for (t1 = TYPE_ARG_TYPES (TREE_TYPE (newdecl)), t2 = TYPE_ARG_TYPES (TREE_TYPE (olddecl)); t1 || t2; @@ -1499,6 +1504,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2)) if (!t1 || !t2) break; + /* Deal with fileptr_type_node. FILE type is not known + at the time we create the builtins. */ else if (TREE_VALUE (t2) == fileptr_type_node) { tree t = TREE_VALUE (t1); @@ -1519,8 +1526,34 @@ duplicate_decls (tree newdecl, tree olddecl, bool TYPE_ARG_TYPES (TREE_TYPE (olddecl)) = oldargs; } } + /* Likewise for const struct tm*. */ + else if (TREE_VALUE (t2) == const_tm_ptr_type_node) + { + tree t = TREE_VALUE (t1); + + if (TYPE_PTR_P (t) + && TYPE_IDENTIFIER (TREE_TYPE (t)) + == get_identifier ("tm") + && compparms (TREE_CHAIN (t1), TREE_CHAIN (t2))) + { + tree oldargs = TYPE_ARG_TYPES (TREE_TYPE (olddecl)); + + TYPE_ARG_TYPES (TREE_TYPE (olddecl)) + = TYPE_ARG_TYPES (TREE_TYPE (newdecl)); + types_match = decls_match (newdecl, olddecl); + if (types_match) + return duplicate_decls (newdecl, olddecl, + newdecl_is_friend); + TYPE_ARG_TYPES (TREE_TYPE (olddecl)) = oldargs; + } + } else if (! same_type_p (TREE_VALUE (t1), TREE_VALUE (t2))) break; + + warning_at (DECL_SOURCE_LOCATION (newdecl), + OPT_Wbuiltin_function_redefined, + "declaration of %q+#D conflicts with built-in " + "declaration %q#D", newdecl, olddecl); } else if ((DECL_EXTERN_C_P (newdecl) && DECL_EXTERN_C_P (olddecl)) @@ -1574,7 +1607,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); if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl)) { Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 241271) +++ gcc/doc/invoke.texi (working copy) @@ -256,7 +256,7 @@ Objective-C and Objective-C++ Dialects}. -pedantic-errors @gol -w -Wextra -Wall -Waddress -Waggregate-return @gol -Wno-aggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol --Wno-attributes -Wbool-compare -Wbool-operation @gol +-Wno-attributes -Wbool-compare -Wbool-operation -Wbuiltin-function-redefined @gol -Wno-builtin-macro-redefined -Wc90-c99-compat -Wc99-c11-compat @gol -Wc++-compat -Wc++11-compat -Wc++14-compat -Wcast-align -Wcast-qual @gol -Wchar-subscripts -Wclobbered -Wcomment -Wconditionally-supported @gol @@ -3673,6 +3673,7 @@ Options} and @ref{Objective-C and Objective-C++ Di -Warray-bounds=1 @r{(only with} @option{-O2}@r{)} @gol -Wbool-compare @gol -Wbool-operation @gol +-Wbuiltin-function-redefined @r{(C++ and Objective-C++ only)} @gol -Wc++11-compat -Wc++14-compat@gol -Wchar-subscripts @gol -Wcomment @gol @@ -5793,6 +5794,13 @@ unrecognized attributes, function attributes appli etc. This does not stop errors for incorrect use of supported attributes. +@item -Wbuiltin-function-redefined @r{(C++ and Objective-C++ only)} +@opindex Wbuiltin-function-redefined +@opindex Wno-builtin-function-redefined +Do warn if built-in functions are redefined. This option is only +supported for C++ and Objective-C++. It is implied by @option{-Wall}, +which can be disabled with @option{-Wno-builtin-function-redefined}. + @item -Wno-builtin-macro-redefined @opindex Wno-builtin-macro-redefined @opindex Wbuiltin-macro-redefined Index: gcc/lto/lto-lang.c =================================================================== --- gcc/lto/lto-lang.c (revision 241271) +++ gcc/lto/lto-lang.c (working copy) @@ -1266,6 +1266,10 @@ lto_init (void) always use the C definition here in lto1. */ gcc_assert (fileptr_type_node == ptr_type_node); gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node); + /* Likewise for const struct tm*. */ + gcc_assert (const_tm_ptr_type_node == const_ptr_type_node); + gcc_assert (TYPE_MAIN_VARIANT (const_tm_ptr_type_node) + == const_ptr_type_node); ptrdiff_type_node = integer_type_node; Index: gcc/testsuite/g++.dg/lookup/extern-c-redecl4.C =================================================================== --- gcc/testsuite/g++.dg/lookup/extern-c-redecl4.C (revision 241271) +++ gcc/testsuite/g++.dg/lookup/extern-c-redecl4.C (working copy) @@ -3,7 +3,6 @@ // { dg-options "" } // { dg-do compile } -// { dg-final { scan-assembler "call\[\t \]+\[^\$\]*?_Z4forkv" { target i?86-*-* x86_64-*-* } } } class frok { @@ -14,5 +13,5 @@ class frok void foo () { - fork (); + fork (); // { dg-error "was not declared in this scope" } } Index: gcc/testsuite/g++.dg/pr71973-1.C =================================================================== --- gcc/testsuite/g++.dg/pr71973-1.C (revision 0) +++ gcc/testsuite/g++.dg/pr71973-1.C (working copy) @@ -0,0 +1,14 @@ +// { dg-do compile } +// { dg-options "-Wall -fdump-tree-eh" } + +extern "C" +void fork () // { dg-warning "conflicts with built-in declaration" } +__attribute__ ((__nothrow__)); + +void foo () throw () +{ + fork (); +} + +// { dg-final { scan-tree-dump-not "eh_dispatch" "eh" } } +// { dg-final { scan-tree-dump-not "resx" "eh" } } Index: gcc/testsuite/g++.dg/pr71973-2.C =================================================================== --- gcc/testsuite/g++.dg/pr71973-2.C (revision 0) +++ gcc/testsuite/g++.dg/pr71973-2.C (working copy) @@ -0,0 +1,18 @@ +// { dg-do compile } +// { dg-options "-Wall -fdump-tree-eh" } + +typedef __SIZE_TYPE__ size_t; +struct tm; + +extern "C" +size_t strftime (char*, size_t, const char*, const struct tm*) +__attribute__ ((__nothrow__)); + +void foo () throw () +{ + strftime (0,0,0,0); // { dg-warning "null argument where non-null required" } + // { dg-warning "too many arguments for format" "" { target *-*-* } .-1 } +} + +// { dg-final { scan-tree-dump-not "eh_dispatch" "eh" } } +// { dg-final { scan-tree-dump-not "resx" "eh" } } Index: gcc/testsuite/g++.dg/pr71973-3.C =================================================================== --- gcc/testsuite/g++.dg/pr71973-3.C (revision 0) +++ gcc/testsuite/g++.dg/pr71973-3.C (working copy) @@ -0,0 +1,14 @@ +// { dg-do compile } +// { dg-options "-Wall -fdump-tree-eh" } + +extern "C" +int execve (const char *__path, char *const __argv[], char *const __envp[]) +__attribute__ ((__nothrow__)); + +void foo () throw () +{ + execve (0,0,0); +} + +// { dg-final { scan-tree-dump-not "eh_dispatch" "eh" } } +// { dg-final { scan-tree-dump-not "resx" "eh" } } Index: gcc/tree-core.h =================================================================== --- gcc/tree-core.h (revision 241271) +++ gcc/tree-core.h (working copy) @@ -615,6 +615,7 @@ enum tree_index { TI_VA_LIST_FPR_COUNTER_FIELD, TI_BOOLEAN_TYPE, TI_FILEPTR_TYPE, + TI_CONST_TM_PTR_TYPE, TI_POINTER_SIZED_TYPE, TI_POINTER_BOUNDS_TYPE, Index: gcc/tree.c =================================================================== --- gcc/tree.c (revision 241271) +++ gcc/tree.c (working copy) @@ -6006,6 +6006,7 @@ free_lang_data (void) /* Create gimple variants for common types. */ ptrdiff_type_node = integer_type_node; fileptr_type_node = ptr_type_node; + const_tm_ptr_type_node = const_ptr_type_node; /* Reset some langhooks. Do not reset types_compatible_p, it may still be used indirectly via the get_alias_set langhook. */ @@ -10310,6 +10311,7 @@ build_common_tree_nodes (bool signed_char) const_ptr_type_node = build_pointer_type (build_type_variant (void_type_node, 1, 0)); fileptr_type_node = ptr_type_node; + const_tm_ptr_type_node = const_ptr_type_node; pointer_sized_int_node = build_nonstandard_integer_type (POINTER_SIZE, 1); Index: gcc/tree.h =================================================================== --- gcc/tree.h (revision 241271) +++ gcc/tree.h (working copy) @@ -3667,6 +3667,8 @@ tree_operand_check_code (const_tree __t, enum tree #define va_list_fpr_counter_field global_trees[TI_VA_LIST_FPR_COUNTER_FIELD] /* The C type `FILE *'. */ #define fileptr_type_node global_trees[TI_FILEPTR_TYPE] +/* The C type `const struct tm *'. */ +#define const_tm_ptr_type_node global_trees[TI_CONST_TM_PTR_TYPE] #define pointer_sized_int_node global_trees[TI_POINTER_SIZED_TYPE] #define boolean_type_node global_trees[TI_BOOLEAN_TYPE]