public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFA] [PATCH] Add a warning for invalid function casts
@ 2017-10-03 19:33 Bernd Edlinger
  2017-10-03 21:34 ` Joseph Myers
                   ` (2 more replies)
  0 siblings, 3 replies; 54+ messages in thread
From: Bernd Edlinger @ 2017-10-03 19:33 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1183 bytes --]

Hi!

I have implemented a warning -Wcast-function-type that analyzes
type casts which change the function signatures.

I would consider function pointers with different result type
invalid, also if both function types have a non-null TYPE_ARG_TYPES
I would say this deserves a warning.  As an exception I have
used for instance in recog.h, the warning allows casting
a function with the type typedef rtx (*stored_funcptr) (...);
to any function with the same result type.

I would think a warning like that should be enabled with -Wextra.

Attached is a first version of the patch and as you can see
the warning found already lots of suspicious type casts.  The worst
is the splay-tree which always calls functions with uintptr_t
instead of the correct parameter type.  I was unable to find
a solution for this, and just silenced the warning with a
second type-cast.

Note that I also changed one line in libgo, but that is only
a quick hack which I only did to make the boot-strap with
all languages succeed.

I'm not sure if this warning may be a bit too strict, but I think
so far it just triggered on rather questionable code.

Thoughts?


Bernd.

[-- Attachment #2: changelog-cast-function-type.txt --]
[-- Type: text/plain, Size: 1720 bytes --]

gcc:
2017-10-03  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	* doc/invoke.texi: Document -Wcast-function-type.
	* gengtype.c (write_root): Remove cast.
	* ggc.h (gt_pch_n_S_nonconst, gt_ggc_m_S_nonconst): Declare.
	* ggc-page.c (gt_ggc_m_S_nonconst): New function.
	* stringpool.c (gt_pch_n_S_nonconst): New function.
	* tree-pass.h (do_per_function_toporder): Adjust header.
	* passes.c (do_per_function_toporder): Change signature.
	(execute_ipa_pass_list): Remove cast.
	* recog.h (f0..f15): Fix return types.
	(stored_funcptr): Use variadic parameter list.
	* tree-dump.c (dump_node): Avoid warning.
	* typed-splay-tree.h (typed_splay_tree): Avoid warning.

libcpp:
2017-10-03  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	* include/symtab.h (ht_forall_internal): Declare.
	* symtab.c (ht_forall_internal): New function.
	* internal.h (maybe_print_line): Change signature.
	
c-family:
2017-10-03  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	* c.opt (Wcast-function-type): New warning option.
	* c-lex.c (get_fileinfo): Avoid warning.
	* c-ppoutput.c (scan_translation_unit_directives_only): Remove cast.

c:
2017-10-03  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	* c-typeck.c (build_c_cast): Implement -Wcast_function_type.

cp:
2017-10-03  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	* cxx-pretty-print.c (pp_c_type_specifier_seq,
	pp_c_parameter_declaration_clause): New wrapper functions.
	(cxx_pretty_printer::cxx_pretty_printer): Remove cast.
	* decl2.c (start_static_storage_duration_function): Aboid warning.
	* typeck.c (build_reinterpret_cast_1): Implement -Wcast_function_type.

testsuite:
2017-10-03  Bernd Edlinger  <bernd.edlinger@hotmail.de>

	* c-c++-common/Wcast-function-type.c: New test.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: patch-cast-function-type.diff --]
[-- Type: text/x-patch; name="patch-cast-function-type.diff", Size: 24484 bytes --]

Index: gcc/c/c-typeck.c
===================================================================
--- gcc/c/c-typeck.c	(revision 253328)
+++ gcc/c/c-typeck.c	(working copy)
@@ -5667,6 +5667,20 @@ build_c_cast (location_t loc, tree type, tree expr
 	pedwarn (loc, OPT_Wpedantic, "ISO C forbids "
 		 "conversion of object pointer to function pointer type");
 
+      if (TREE_CODE (type) == POINTER_TYPE
+	  && TREE_CODE (otype) == POINTER_TYPE
+	  && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
+	  && TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE
+	  && (TYPE_ARG_TYPES (TREE_TYPE (type))
+	      && TYPE_ARG_TYPES (TREE_TYPE (otype))
+	      ? !comptypes (TREE_TYPE (type),
+			    TREE_TYPE (otype))
+	      : !comptypes (TREE_TYPE (TREE_TYPE (type)),
+			    TREE_TYPE (TREE_TYPE (otype)))))
+	warning_at (loc, OPT_Wcast_function_type,
+		    "cast between incompatible function types"
+		    " from %qT to %qT", otype, type);
+
       ovalue = value;
       value = convert (type, value);
 
Index: gcc/c-family/c-lex.c
===================================================================
--- gcc/c-family/c-lex.c	(revision 253328)
+++ gcc/c-family/c-lex.c	(working copy)
@@ -101,9 +101,11 @@ get_fileinfo (const char *name)
   struct c_fileinfo *fi;
 
   if (!file_info_tree)
-    file_info_tree = splay_tree_new ((splay_tree_compare_fn) strcmp,
+    file_info_tree = splay_tree_new ((splay_tree_compare_fn)
+				     (uintptr_t) strcmp,
 				     0,
-				     (splay_tree_delete_value_fn) free);
+				     (splay_tree_delete_value_fn)
+				     (uintptr_t) free);
 
   n = splay_tree_lookup (file_info_tree, (splay_tree_key) name);
   if (n)
Index: gcc/c-family/c-ppoutput.c
===================================================================
--- gcc/c-family/c-ppoutput.c	(revision 253328)
+++ gcc/c-family/c-ppoutput.c	(working copy)
@@ -299,7 +299,7 @@ scan_translation_unit_directives_only (cpp_reader
   struct _cpp_dir_only_callbacks cb;
 
   cb.print_lines = print_lines_directives_only;
-  cb.maybe_print_line = (void (*) (source_location)) maybe_print_line;
+  cb.maybe_print_line = maybe_print_line;
 
   _cpp_preprocess_dir_only (pfile, &cb);
 }
Index: gcc/c-family/c.opt
===================================================================
--- gcc/c-family/c.opt	(revision 253328)
+++ gcc/c-family/c.opt	(working copy)
@@ -384,6 +384,10 @@ Wc++17-compat
 C++ ObjC++ Var(warn_cxx17_compat) Warning LangEnabledBy(C++ ObjC++,Wall)
 Warn about C++ constructs whose meaning differs between ISO C++ 2014 and ISO C++ 2017.
 
+Wcast-function-type
+C ObjC C++ ObjC++ Var(warn_cast_function_type) Warning EnabledBy(Wextra)
+Warn about casts between incompatible function types.
+
 Wcast-qual
 C ObjC C++ ObjC++ Var(warn_cast_qual) Warning
 Warn about casts which discard qualifiers.
Index: gcc/cp/cxx-pretty-print.c
===================================================================
--- gcc/cp/cxx-pretty-print.c	(revision 253328)
+++ gcc/cp/cxx-pretty-print.c	(working copy)
@@ -2935,8 +2935,16 @@ pp_cxx_constraint (cxx_pretty_printer *pp, tree t)
 
 
 \f
-typedef c_pretty_print_fn pp_fun;
+static void pp_c_type_specifier_seq (c_pretty_printer *pp, tree t)
+{
+  pp_cxx_type_specifier_seq ((cxx_pretty_printer *)pp, t);
+}
 
+static void pp_c_parameter_declaration_clause (c_pretty_printer *pp, tree t)
+{
+  pp_cxx_parameter_declaration_clause ((cxx_pretty_printer *)pp, t);
+}
+
 /* Initialization of a C++ pretty-printer object.  */
 
 cxx_pretty_printer::cxx_pretty_printer ()
@@ -2943,6 +2951,6 @@ cxx_pretty_printer::cxx_pretty_printer ()
   : c_pretty_printer (),
     enclosing_scope (global_namespace)
 {
-  type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
-  parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
+  type_specifier_seq = pp_c_type_specifier_seq;
+  parameter_list = pp_c_parameter_declaration_clause;
 }
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c	(revision 253328)
+++ gcc/cp/decl2.c	(working copy)
@@ -3480,7 +3480,8 @@ start_static_storage_duration_function (unsigned c
       priority_info_map = splay_tree_new (splay_tree_compare_ints,
 					  /*delete_key_fn=*/0,
 					  /*delete_value_fn=*/
-					  (splay_tree_delete_value_fn) &free);
+					  (splay_tree_delete_value_fn)
+					  (uintptr_t) free);
 
       /* We always need to generate functions for the
 	 DEFAULT_INIT_PRIORITY so enter it now.  That way when we walk
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 253328)
+++ gcc/cp/typeck.c	(working copy)
@@ -7261,8 +7261,21 @@ build_reinterpret_cast_1 (tree type, tree expr, bo
 	   && same_type_p (type, intype))
     /* DR 799 */
     return rvalue (expr);
-  else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
-	   || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
+  else if (TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
+    {
+      if ((complain & tf_warning)
+	  && (TYPE_ARG_TYPES (TREE_TYPE (type))
+	      && TYPE_ARG_TYPES (TREE_TYPE (intype))
+	      ? !same_type_p (TREE_TYPE (type),
+			      TREE_TYPE (intype))
+	      : !same_type_p (TREE_TYPE (TREE_TYPE (type)),
+			      TREE_TYPE (TREE_TYPE (intype)))))
+	warning (OPT_Wcast_function_type,
+		 "cast between incompatible function types"
+		 " from %qH to %qI", intype, type);
+      return build_nop (type, expr);
+    }
+  else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
     return build_nop (type, expr);
   else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
 	   || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 253328)
+++ gcc/doc/invoke.texi	(working copy)
@@ -267,7 +267,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wno-builtin-declaration-mismatch @gol
 -Wno-builtin-macro-redefined  -Wc90-c99-compat  -Wc99-c11-compat @gol
 -Wc++-compat  -Wc++11-compat  -Wc++14-compat  @gol
--Wcast-align  -Wcast-align=strict  -Wcast-qual  @gol
+-Wcast-align  -Wcast-align=strict  -Wcast-function-type  -Wcast-qual  @gol
 -Wchar-subscripts  -Wchkp  -Wcatch-value  -Wcatch-value=@var{n} @gol
 -Wclobbered  -Wcomment  -Wconditionally-supported @gol
 -Wconversion  -Wcoverage-mismatch  -Wno-cpp  -Wdangling-else  -Wdate-time @gol
@@ -3899,6 +3899,7 @@ This enables some extra warning flags that are not
 name is still supported, but the newer name is more descriptive.)
 
 @gccoptlist{-Wclobbered  @gol
+-Wcast-function-type  @gol
 -Wempty-body  @gol
 -Wignored-qualifiers @gol
 -Wimplicit-fallthrough=3 @gol
@@ -5948,6 +5949,15 @@ Warn whenever a pointer is cast such that the requ
 target is increased.  For example, warn if a @code{char *} is cast to
 an @code{int *} regardless of the target machine.
 
+@item -Wcast-function-type
+@opindex Wcast-function-type
+@opindex Wno-cast-function-type
+Warn when a function pointer is cast to an incompatible function pointer.
+When one of the function types uses variable arguments like this
+@code{int f(...);}, then only the return value is checked, otherwise
+the return value and the parameter types are checked.
+This warning is enabled by @option{-Wextra}.
+
 @item -Wwrite-strings
 @opindex Wwrite-strings
 @opindex Wno-write-strings
Index: gcc/gengtype.c
===================================================================
--- gcc/gengtype.c	(revision 253328)
+++ gcc/gengtype.c	(working copy)
@@ -4406,8 +4406,8 @@ write_root (outf_p f, pair_p v, type_p type, const
 	if (!start_root_entry (f, v, name, line))
 	  return;
 
-	oprintf (f, "    (gt_pointer_walker) &gt_ggc_m_S,\n");
-	oprintf (f, "    (gt_pointer_walker) &gt_pch_n_S\n");
+	oprintf (f, "    &gt_ggc_m_S_nonconst,\n");
+	oprintf (f, "    &gt_pch_n_S_nonconst\n");
 	oprintf (f, "  },\n");
       }
       break;
Index: gcc/ggc-page.c
===================================================================
--- gcc/ggc-page.c	(revision 253328)
+++ gcc/ggc-page.c	(working copy)
@@ -1500,6 +1500,11 @@ gt_ggc_m_S (const void *p)
   return;
 }
 
+void
+gt_ggc_m_S_nonconst (void *p)
+{
+  gt_ggc_m_S (CONST_CAST(const void *, p));
+}
 
 /* User-callable entry points for marking string X.  */
 
Index: gcc/ggc.h
===================================================================
--- gcc/ggc.h	(revision 253328)
+++ gcc/ggc.h	(working copy)
@@ -98,6 +98,8 @@ extern int ggc_marked_p	(const void *);
 /* PCH and GGC handling for strings, mostly trivial.  */
 extern void gt_pch_n_S (const void *);
 extern void gt_ggc_m_S (const void *);
+extern void gt_pch_n_S_nonconst (void *);
+extern void gt_ggc_m_S_nonconst (void *);
 
 /* End of GTY machinery API.  */
 
Index: gcc/passes.c
===================================================================
--- gcc/passes.c	(revision 253328)
+++ gcc/passes.c	(working copy)
@@ -1694,7 +1694,8 @@ remove_cgraph_node_from_order (cgraph_node *node,
    call CALLBACK on the current function.
    This function is global so that plugins can use it.  */
 void
-do_per_function_toporder (void (*callback) (function *, void *data), void *data)
+do_per_function_toporder (void (*callback) (function *, opt_pass *data),
+			  opt_pass *data)
 {
   int i;
 
@@ -2932,9 +2933,7 @@ execute_ipa_pass_list (opt_pass *pass)
 	  if (pass->sub->type == GIMPLE_PASS)
 	    {
 	      invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_START, NULL);
-	      do_per_function_toporder ((void (*)(function *, void *))
-					  execute_pass_list,
-					pass->sub);
+	      do_per_function_toporder (execute_pass_list, pass->sub);
 	      invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_END, NULL);
 	    }
 	  else if (pass->sub->type == SIMPLE_IPA_PASS
Index: gcc/recog.h
===================================================================
--- gcc/recog.h	(revision 253328)
+++ gcc/recog.h	(working copy)
@@ -276,43 +276,60 @@ typedef const char * (*insn_output_fn) (rtx *, rtx
 
 struct insn_gen_fn
 {
-  typedef rtx_insn * (*f0) (void);
-  typedef rtx_insn * (*f1) (rtx);
-  typedef rtx_insn * (*f2) (rtx, rtx);
-  typedef rtx_insn * (*f3) (rtx, rtx, rtx);
-  typedef rtx_insn * (*f4) (rtx, rtx, rtx, rtx);
-  typedef rtx_insn * (*f5) (rtx, rtx, rtx, rtx, rtx);
-  typedef rtx_insn * (*f6) (rtx, rtx, rtx, rtx, rtx, rtx);
-  typedef rtx_insn * (*f7) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
-  typedef rtx_insn * (*f8) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
-  typedef rtx_insn * (*f9) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
-  typedef rtx_insn * (*f10) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
-  typedef rtx_insn * (*f11) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
-  typedef rtx_insn * (*f12) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
-  typedef rtx_insn * (*f13) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
-  typedef rtx_insn * (*f14) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
-  typedef rtx_insn * (*f15) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
-  typedef rtx_insn * (*f16) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f0) (void);
+  typedef rtx (*f1) (rtx);
+  typedef rtx (*f2) (rtx, rtx);
+  typedef rtx (*f3) (rtx, rtx, rtx);
+  typedef rtx (*f4) (rtx, rtx, rtx, rtx);
+  typedef rtx (*f5) (rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f6) (rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f7) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f8) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f9) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f10) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f11) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f12) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f13) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f14) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f15) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+  typedef rtx (*f16) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
 
-  typedef f0 stored_funcptr;
+  typedef rtx (*stored_funcptr) (...);
 
-  rtx_insn * operator () (void) const { return ((f0)func) (); }
-  rtx_insn * operator () (rtx a0) const { return ((f1)func) (a0); }
-  rtx_insn * operator () (rtx a0, rtx a1) const { return ((f2)func) (a0, a1); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2) const { return ((f3)func) (a0, a1, a2); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3) const { return ((f4)func) (a0, a1, a2, a3); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4) const { return ((f5)func) (a0, a1, a2, a3, a4); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5) const { return ((f6)func) (a0, a1, a2, a3, a4, a5); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6) const { return ((f7)func) (a0, a1, a2, a3, a4, a5, a6); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7) const { return ((f8)func) (a0, a1, a2, a3, a4, a5, a6, a7); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8) const { return ((f9)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9) const { return ((f10)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10) const { return ((f11)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11) const { return ((f12)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12) const { return ((f13)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13) const { return ((f14)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13, rtx a14) const { return ((f15)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13, rtx a14, rtx a15) const { return ((f16)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+  rtx_insn * operator () (void) const
+  { return (rtx_insn *) ((f0)func) (); }
+  rtx_insn * operator () (rtx a0) const
+  { return (rtx_insn *) ((f1)func) (a0); }
+  rtx_insn * operator () (rtx a0, rtx a1) const
+  { return (rtx_insn *) ((f2)func) (a0, a1); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2) const
+  { return (rtx_insn *) ((f3)func) (a0, a1, a2); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3) const
+  { return (rtx_insn *) ((f4)func) (a0, a1, a2, a3); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4) const
+  { return (rtx_insn *) ((f5)func) (a0, a1, a2, a3, a4); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5) const
+  { return (rtx_insn *) ((f6)func) (a0, a1, a2, a3, a4, a5); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6) const
+  { return (rtx_insn *) ((f7)func) (a0, a1, a2, a3, a4, a5, a6); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7) const
+  { return (rtx_insn *) ((f8)func) (a0, a1, a2, a3, a4, a5, a6, a7); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8) const
+  { return (rtx_insn *) ((f9)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9) const
+  { return (rtx_insn *) ((f10)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10) const
+  { return (rtx_insn *) ((f11)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11) const
+  { return (rtx_insn *)((f12)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12) const
+  { return (rtx_insn *) ((f13)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13) const
+  { return (rtx_insn *) ((f14)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13, rtx a14) const
+  { return (rtx_insn *) ((f15)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+  rtx_insn * operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13, rtx a14, rtx a15) const
+  { return (rtx_insn *) ((f16)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
 
   // This is for compatibility of code that invokes functions like
   //   (*funcptr) (arg)
Index: gcc/stringpool.c
===================================================================
--- gcc/stringpool.c	(revision 253328)
+++ gcc/stringpool.c	(working copy)
@@ -196,6 +196,11 @@ gt_pch_n_S (const void *x)
 		      &gt_pch_p_S);
 }
 
+void
+gt_pch_n_S_nonconst (void *x)
+{
+  gt_pch_n_S (CONST_CAST (const void *, x));
+}
 
 /* User-callable entry point for marking string X.  */
 
Index: gcc/testsuite/c-c++-common/Wcast-function-type.c
===================================================================
--- gcc/testsuite/c-c++-common/Wcast-function-type.c	(revision 0)
+++ gcc/testsuite/c-c++-common/Wcast-function-type.c	(working copy)
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-Wcast-function-type" } */
+
+int f(long);
+
+typedef int (f1)(long);
+typedef int (f2)(void*);
+#ifdef __cplusplus
+typedef int (f3)(...);
+typedef void (f4)(...);
+#else
+typedef int (f3)();
+typedef void (f4)();
+#endif
+
+f1 *a;
+f2 *b;
+f3 *c;
+f4 *d;
+
+void
+foo (void)
+{
+  a = (f1 *) f; /* { dg-bogus   "incompatible function types" } */
+  b = (f2 *) f; /* { dg-warning "incompatible function types" } */
+  c = (f3 *) f; /* { dg-bogus   "incompatible function types" } */
+  d = (f4 *) f; /* { dg-warning "incompatible function types" } */
+}
Index: gcc/tree-dump.c
===================================================================
--- gcc/tree-dump.c	(revision 253328)
+++ gcc/tree-dump.c	(working copy)
@@ -735,7 +735,8 @@ dump_node (const_tree t, dump_flags_t flags, FILE
   di.flags = flags;
   di.node = t;
   di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
-			     (splay_tree_delete_value_fn) &free);
+			     (splay_tree_delete_value_fn)
+			     (uintptr_t) free);
 
   /* Queue up the first node.  */
   queue (&di, t, DUMP_NONE);
Index: gcc/tree-pass.h
===================================================================
--- gcc/tree-pass.h	(revision 253328)
+++ gcc/tree-pass.h	(working copy)
@@ -646,7 +646,8 @@ extern void register_one_dump_file (opt_pass *);
 extern bool function_called_by_processed_nodes_p (void);
 
 /* Declare for plugins.  */
-extern void do_per_function_toporder (void (*) (function *, void *), void *);
+extern void do_per_function_toporder (void (*) (function *, opt_pass *),
+				      opt_pass *);
 
 extern void disable_pass (const char *);
 extern void enable_pass (const char *);
Index: gcc/typed-splay-tree.h
===================================================================
--- gcc/typed-splay-tree.h	(revision 253328)
+++ gcc/typed-splay-tree.h	(working copy)
@@ -75,9 +75,12 @@ inline typed_splay_tree<KEY_TYPE, VALUE_TYPE>::
 		    delete_key_fn delete_key_fn,
 		    delete_value_fn delete_value_fn)
 {
-  m_inner = splay_tree_new ((splay_tree_compare_fn)compare_fn,
-			    (splay_tree_delete_key_fn)delete_key_fn,
-			    (splay_tree_delete_value_fn)delete_value_fn);
+  m_inner = splay_tree_new ((splay_tree_compare_fn)
+			    (uintptr_t) compare_fn,
+			    (splay_tree_delete_key_fn)
+			    (uintptr_t) delete_key_fn,
+			    (splay_tree_delete_value_fn)
+			    (uintptr_t) delete_value_fn);
 }
 
 /* Destructor for typed_splay_tree <K, V>.  */
Index: libcpp/identifiers.c
===================================================================
--- libcpp/identifiers.c	(revision 253328)
+++ libcpp/identifiers.c	(working copy)
@@ -116,5 +116,5 @@ extern char proxy_assertion_broken[offsetof (struc
 void
 cpp_forall_identifiers (cpp_reader *pfile, cpp_cb cb, void *v)
 {
-  ht_forall (pfile->hash_table, (ht_cb) cb, v);
+  ht_forall_internal (pfile->hash_table, cb, v);
 }
Index: libcpp/include/symtab.h
===================================================================
--- libcpp/include/symtab.h	(revision 253328)
+++ libcpp/include/symtab.h	(working copy)
@@ -88,6 +88,11 @@ extern hashnode ht_lookup_with_hash (cpp_hash_tabl
    if the callback returns zero.  */
 typedef int (*ht_cb) (struct cpp_reader *, hashnode, const void *);
 extern void ht_forall (cpp_hash_table *, ht_cb, const void *);
+struct cpp_hashnode;
+extern void ht_forall_internal (cpp_hash_table *,
+				int (*)(struct cpp_reader *,
+					cpp_hashnode *, void *),
+				void *);
 
 /* For all nodes in TABLE, call the callback.  If the callback returns
    a nonzero value, the node is removed from the table.  */
Index: libcpp/internal.h
===================================================================
--- libcpp/internal.h	(revision 253328)
+++ libcpp/internal.h	(working copy)
@@ -708,7 +708,7 @@ struct _cpp_dir_only_callbacks
 {
   /* Called to print a block of lines. */
   void (*print_lines) (int, const void *, size_t);
-  void (*maybe_print_line) (source_location);
+  bool (*maybe_print_line) (source_location);
 };
 
 extern void _cpp_preprocess_dir_only (cpp_reader *,
Index: libcpp/symtab.c
===================================================================
--- libcpp/symtab.c	(revision 253328)
+++ libcpp/symtab.c	(working copy)
@@ -236,6 +236,26 @@ ht_forall (cpp_hash_table *table, ht_cb cb, const
   while (++p < limit);
 }
 
+/* Like ht_forall, but with different parameter types in the callback.  */
+void
+ht_forall_internal (cpp_hash_table *table,
+		    int (*cb)(struct cpp_reader *,
+			      cpp_hashnode *, void *),
+		    void *v)
+{
+  hashnode *p, *limit;
+
+  p = table->entries;
+  limit = p + table->nslots;
+  do
+    if (*p && *p != DELETED)
+      {
+	if ((*cb) (table->pfile, (cpp_hashnode *)*p, v) == 0)
+	  break;
+      }
+  while (++p < limit);
+}
+
 /* Like ht_forall, but a nonzero return from the callback means that
    the entry should be removed from the table.  */
 void
Index: libgo/runtime/runtime.h
===================================================================
--- libgo/runtime/runtime.h	(revision 253328)
+++ libgo/runtime/runtime.h	(working copy)
@@ -94,7 +94,7 @@ struct String
 
 struct FuncVal
 {
-	void	(*fn)(void);
+	void	(*fn)();
 	// variable-size, fn-specific data here
 };
 

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2017-12-14 18:50 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-03 19:33 [RFA] [PATCH] Add a warning for invalid function casts Bernd Edlinger
2017-10-03 21:34 ` Joseph Myers
2017-10-05 14:03   ` Bernd Edlinger
2017-10-05 14:10     ` Joseph Myers
2017-10-05  0:25 ` Eric Gallager
2017-10-05 13:39   ` Bernd Edlinger
2017-10-05 14:06     ` Andreas Schwab
2017-10-05 18:22     ` Eric Gallager
2017-10-05 16:16 ` Martin Sebor
2017-10-05 21:04   ` Bernd Edlinger
2017-10-05 21:47     ` Joseph Myers
2017-10-06 20:50       ` Jeff Law
2017-10-05 22:17     ` Martin Sebor
2017-10-06 13:26   ` Bernd Edlinger
2017-10-06 15:43     ` Martin Sebor
2017-10-06 18:25       ` Bernd Edlinger
2017-10-06 20:43         ` Martin Sebor
2017-10-06 21:01       ` Jeff Law
2017-10-06 22:23         ` Bernd Edlinger
2017-10-07 18:23           ` Bernd Edlinger
2017-10-09 16:48             ` Martin Sebor
2017-10-09 18:19               ` Bernd Edlinger
2017-10-09 18:46                 ` Martin Sebor
2017-10-09 22:33                   ` Bernd Edlinger
2017-10-10 15:35                     ` Martin Sebor
2017-10-10 16:55                       ` Joseph Myers
2017-10-10 17:39                         ` Martin Sebor
2017-10-10 23:57                           ` Joseph Myers
2017-10-11  3:52                             ` Martin Sebor
2017-10-11 17:28                               ` Joseph Myers
2017-10-11 18:04                                 ` Martin Sebor
2017-10-12 11:45                                   ` Pedro Alves
2017-10-12 11:52                               ` Pedro Alves
2017-10-12 11:59                               ` Pedro Alves
2017-10-12 15:26                                 ` Martin Sebor
2017-10-12 15:37                                   ` Joseph Myers
2017-10-21  9:54                     ` Bernd Edlinger
2017-11-03 21:47                     ` Joseph Myers
     [not found]                     ` <fa771535-8fcf-9b22-b5b9-eb928af5e817@hotmail.de>
2017-11-08 17:03                       ` [PING] " Bernd Edlinger
     [not found]                       ` <e64a07da-bada-893e-d1e4-bf4705cc1731@hotmail.de>
2017-11-15 20:52                         ` [PING**2] " Bernd Edlinger
2017-11-29 22:17                     ` Jason Merrill
2017-11-30 15:45                       ` [PATCHv2] " Bernd Edlinger
2017-11-30 15:56                         ` Jason Merrill
2017-11-30 16:22                           ` Bernd Edlinger
2017-11-30 17:32                             ` Jason Merrill
2017-11-30 18:06                               ` Bernd Edlinger
2017-11-30 18:19                                 ` Jason Merrill
2017-11-30 18:39                                   ` Bernd Edlinger
2017-11-30 18:39                                     ` Jason Merrill
2017-12-01 12:42                                       ` [PATCHv3] " Bernd Edlinger
2017-12-06 22:36                                         ` Jason Merrill
2017-12-07 20:48                                           ` Bernd Edlinger
2017-12-14 18:50                                             ` Jason Merrill
     [not found]                                           ` <1c3d1b9b-7a25-fae3-5c44-1a0efae77cc8@hotmail.de>
2017-12-14 18:35                                             ` Bernd Edlinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).