diff mbox

[PATCHv2,C++] Warn on redefinition of builtin functions (PR c++/71973)

Message ID AM4PR0701MB216268F6FF1F2B12C60C440CE4B30@AM4PR0701MB2162.eurprd07.prod.outlook.com
State New
Headers show

Commit Message

Bernd Edlinger Nov. 19, 2016, 11:11 a.m. UTC
Hi,

On 11/18/16 22:19, Jason Merrill wrote:
> On 11/05/2016 12:44 PM, Bernd Edlinger wrote:

>> +          warning_at (DECL_SOURCE_LOCATION (newdecl), 0,

>> +              "declaration of %q+#D conflicts with built-in "

>> +              "declaration %q#D", newdecl, olddecl);

>

> There needs to be a way to disable this warning, even if it's enabled by

> default.

>

>> -      TREE_NOTHROW (olddecl) = 0;

>> +      TREE_NOTHROW (olddecl) = TREE_NOTHROW (newdecl);

>

> I still 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.

>



I changed the patch as requested.  I think meanwhile that this else
block does only handle a built-in function with different signature.

I have now changed also the C front end to emit the warning with the new
default-enabled -Wbuiltin-declaration-mismatch.

When I looked at the c-decl.c code, I saw there are effectively two
warnings, one for a function that does not match the builtin signature,
and another for a global variable that has the the name of a built-in.

like:
test.c
int printf;

gives warning:
test.c:1:5: warning: built-in function 'printf' declared as non-function
  int printf;


the same in C++ gives nothing.

That is because of this in duplicate_decls:

       if (TREE_CODE (newdecl) != FUNCTION_DECL)
         {
           /* Avoid warnings redeclaring built-ins which have not been
              explicitly declared.  */
           if (DECL_ANTICIPATED (olddecl))
             return NULL_TREE;

That is from gcc3.1 in 2002 a rather radical patch I would say.

I left the warning for declaring a variable with the name of built-in
function for next time, maybe...


Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
Is it OK for trunk?


Thanks
Bernd.
gcc:
2016-11-19  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-19  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-19  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-19  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-05  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-05  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 -w to dg-options.
	* g++.old-deja/g++.other/realloc.C: Add -w to dg-options.
	* g++.old-deja/g++.other/builtins10.C: Adjust test expectation.

Comments

Jason Merrill Nov. 21, 2016, 5:38 a.m. UTC | #1
OK.

On Sat, Nov 19, 2016 at 6:11 AM, Bernd Edlinger
<bernd.edlinger@hotmail.de> wrote:
> Hi,
>
> On 11/18/16 22:19, Jason Merrill wrote:
>> On 11/05/2016 12:44 PM, Bernd Edlinger wrote:
>>> +          warning_at (DECL_SOURCE_LOCATION (newdecl), 0,
>>> +              "declaration of %q+#D conflicts with built-in "
>>> +              "declaration %q#D", newdecl, olddecl);
>>
>> There needs to be a way to disable this warning, even if it's enabled by
>> default.
>>
>>> -      TREE_NOTHROW (olddecl) = 0;
>>> +      TREE_NOTHROW (olddecl) = TREE_NOTHROW (newdecl);
>>
>> I still 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.
>>
>
>
> I changed the patch as requested.  I think meanwhile that this else
> block does only handle a built-in function with different signature.
>
> I have now changed also the C front end to emit the warning with the new
> default-enabled -Wbuiltin-declaration-mismatch.
>
> When I looked at the c-decl.c code, I saw there are effectively two
> warnings, one for a function that does not match the builtin signature,
> and another for a global variable that has the the name of a built-in.
>
> like:
> test.c
> int printf;
>
> gives warning:
> test.c:1:5: warning: built-in function 'printf' declared as non-function
>   int printf;
>
>
> the same in C++ gives nothing.
>
> That is because of this in duplicate_decls:
>
>        if (TREE_CODE (newdecl) != FUNCTION_DECL)
>          {
>            /* Avoid warnings redeclaring built-ins which have not been
>               explicitly declared.  */
>            if (DECL_ANTICIPATED (olddecl))
>              return NULL_TREE;
>
> That is from gcc3.1 in 2002 a rather radical patch I would say.
>
> I left the warning for declaring a variable with the name of built-in
> function for next time, maybe...
>
>
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> Is it OK for trunk?
>
>
> Thanks
> Bernd.
diff mbox

Patch

Index: gcc/builtin-types.def
===================================================================
--- gcc/builtin-types.def	(revision 242620)
+++ 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 242620)
+++ gcc/builtins.def	(working copy)
@@ -212,8 +212,8 @@  along with GCC; see the file COPYING3.  If not see
    functions are mapped to the actual implementation of the STM library. */
 #undef DEF_TM_BUILTIN
 #define DEF_TM_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
-  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,    \
-	       true, true, true, ATTRS, false, flag_tm)
+  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \
+	       false, true, true, ATTRS, false, flag_tm)
 
 /* Builtin used by the implementation of libsanitizer. These
    functions are mapped to the actual implementation of the 
@@ -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/c-decl.c
===================================================================
--- gcc/c/c-decl.c	(revision 242620)
+++ gcc/c/c-decl.c	(working copy)
@@ -1867,7 +1867,8 @@  diagnose_mismatched_decls (tree newdecl, tree oldd
 	      /* If types don't match for a built-in, throw away the
 		 built-in.  No point in calling locate_old_decl here, it
 		 won't print anything.  */
-	      warning (0, "conflicting types for built-in function %q+D",
+	      warning (OPT_Wbuiltin_declaration_mismatch,
+		       "conflicting types for built-in function %q+D",
 		       newdecl);
 	      return false;
 	    }
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 242620)
+++ gcc/c-family/c-common.c	(working copy)
@@ -4293,9 +4293,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 242620)
+++ gcc/c-family/c.opt	(working copy)
@@ -337,6 +337,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-declaration-mismatch
+C ObjC C++ ObjC++ Var(warn_builtin_declaraion_mismatch) Init(1) Warning
+Warn when a built-in function is declared with the wrong signature.
+
 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 242620)
+++ gcc/cp/decl.c	(working copy)
@@ -1490,10 +1490,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;
@@ -1500,6 +1505,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);
@@ -1520,8 +1527,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_declaration_mismatch,
+			  "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))
@@ -1531,7 +1564,8 @@  duplicate_decls (tree newdecl, tree olddecl, bool
 	      /* A near match; override the builtin.  */
 
 	      if (TREE_PUBLIC (newdecl))
-		warning_at (DECL_SOURCE_LOCATION (newdecl), 0,
+		warning_at (DECL_SOURCE_LOCATION (newdecl),
+			    OPT_Wbuiltin_declaration_mismatch,
 			    "new declaration %q#D ambiguates built-in "
 			    "declaration %q#D", newdecl, olddecl);
 	      else
@@ -2243,6 +2277,7 @@  duplicate_decls (tree newdecl, tree olddecl, bool
       TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
       TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
       TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
+      TREE_NOTHROW (olddecl) = TREE_NOTHROW (newdecl);
       TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
     }
 
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 242620)
+++ gcc/doc/invoke.texi	(working copy)
@@ -259,6 +259,7 @@  Objective-C and Objective-C++ Dialects}.
 -Walloca -Walloca-larger-than=@var{n} @gol
 -Wno-aggressive-loop-optimizations -Warray-bounds -Warray-bounds=@var{n} @gol
 -Wno-attributes -Wbool-compare -Wbool-operation @gol
+-Wno-builtin-declaration-mismatch @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
@@ -5925,6 +5926,12 @@  unrecognized attributes, function attributes appli
 etc.  This does not stop errors for incorrect use of supported
 attributes.
 
+@item -Wno-builtin-declaration-mismatch
+@opindex Wno-builtin-declaration-mismatch
+@opindex Wbuiltin-declaration-mismatch
+Warn if a built-in function is declared with the wrong signature.
+This warning is enabled by default.
+
 @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 242620)
+++ 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 242620)
+++ 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/lto/pr68811_0.C
===================================================================
--- gcc/testsuite/g++.dg/lto/pr68811_0.C	(revision 242620)
+++ gcc/testsuite/g++.dg/lto/pr68811_0.C	(working copy)
@@ -1,5 +1,5 @@ 
 // { dg-lto-do link }
-/* { dg-lto-options "-O2  -w" } */
+/* { dg-lto-options { { -O2 -w } { -w } } } */
 // { dg-extra-ld-options "-r -nostdlib" }
 extern "C" char *strcpy(char *, const char *);
 char InitXPCOMGlue_lastSlash;
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/testsuite/g++.old-deja/g++.mike/p700.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p700.C	(revision 242620)
+++ gcc/testsuite/g++.old-deja/g++.mike/p700.C	(working copy)
@@ -1,5 +1,5 @@ 
 // { dg-do assemble  }
-// { dg-options "-Wno-deprecated -Wno-register" }
+// { dg-options "-Wno-deprecated -Wno-register -Wno-builtin-declaration-mismatch" }
 // { dg-error "limited range of data type" "16-bit target" { target xstormy16-*-* } 0 }
 // prms-id: 700
 
Index: gcc/testsuite/g++.old-deja/g++.other/builtins10.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/builtins10.C	(revision 242620)
+++ gcc/testsuite/g++.old-deja/g++.other/builtins10.C	(working copy)
@@ -1,7 +1,8 @@ 
 // { dg-do assemble  }
-// Test that built-in functions don't warn when prototyped without arguments.
+// Test that built-in functions do warn when prototyped without arguments.
 // Origin: PR c++/9367
 // Copyright (C) 2003 Free Software Foundation.
 
-extern "C" int snprintf();
+extern "C" int snprintf(); // { dg-warning "conflicts with built-in declaration" "" { target c++11 } }
+extern "C" int printf(); // { dg-warning "conflicts with built-in declaration" }
 
Index: gcc/testsuite/g++.old-deja/g++.other/realloc.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/realloc.C	(revision 242620)
+++ gcc/testsuite/g++.old-deja/g++.other/realloc.C	(working copy)
@@ -1,4 +1,5 @@ 
 // { dg-do assemble  }
+// { dg-options "-Wno-builtin-declaration-mismatch" }
 
 extern "C" void realloc();
 
Index: gcc/tree-core.h
===================================================================
--- gcc/tree-core.h	(revision 242620)
+++ gcc/tree-core.h	(working copy)
@@ -618,6 +618,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 242620)
+++ 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.  */
@@ -10332,6 +10333,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 242620)
+++ gcc/tree.h	(working copy)
@@ -3672,6 +3672,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]