invoke.texi: Document -Wcast-function-type.
gcc: 2017-12-14 Bernd Edlinger <bernd.edlinger@hotmail.de> * doc/invoke.texi: Document -Wcast-function-type. * recog.h (stored_funcptr): Change signature. * tree-dump.c (dump_node): Avoid warning. * typed-splay-tree.h (typed_splay_tree): Avoid warning. libcpp: 2017-12-14 Bernd Edlinger <bernd.edlinger@hotmail.de> * internal.h (maybe_print_line): Change signature. c-family: 2017-12-14 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-12-14 Bernd Edlinger <bernd.edlinger@hotmail.de> * c-typeck.c (c_safe_arg_type_equiv_p, c_safe_function_type_cast_p): New function. (build_c_cast): Implement -Wcast-function-type. cp: 2017-12-14 Bernd Edlinger <bernd.edlinger@hotmail.de> * decl2.c (start_static_storage_duration_function): Avoid warning. * typeck.c (cxx_safe_arg_type_equiv_p, cxx_safe_function_type_cast_p): New function. (build_reinterpret_cast_1): Implement -Wcast-function-type. testsuite: 2017-12-14 Bernd Edlinger <bernd.edlinger@hotmail.de> * c-c++-common/Wcast-function-type.c: New test. * g++.dg/Wcast-function-type.C: New test. From-SVN: r255661
This commit is contained in:
parent
9d0e85af87
commit
c65e18d333
@ -1,3 +1,10 @@
|
|||||||
|
2017-12-14 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||||
|
|
||||||
|
* doc/invoke.texi: Document -Wcast-function-type.
|
||||||
|
* recog.h (stored_funcptr): Change signature.
|
||||||
|
* tree-dump.c (dump_node): Avoid warning.
|
||||||
|
* typed-splay-tree.h (typed_splay_tree): Avoid warning.
|
||||||
|
|
||||||
2017-12-14 Qing Zhao <qing.zhao@oracle.com>
|
2017-12-14 Qing Zhao <qing.zhao@oracle.com>
|
||||||
|
|
||||||
PR middle_end/79538
|
PR middle_end/79538
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2017-12-14 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.
|
||||||
|
|
||||||
2017-12-14 Qing Zhao <qing.zhao@oracle.com>
|
2017-12-14 Qing Zhao <qing.zhao@oracle.com>
|
||||||
|
|
||||||
PR middle_end/79538
|
PR middle_end/79538
|
||||||
|
@ -101,9 +101,11 @@ get_fileinfo (const char *name)
|
|||||||
struct c_fileinfo *fi;
|
struct c_fileinfo *fi;
|
||||||
|
|
||||||
if (!file_info_tree)
|
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)
|
||||||
|
(void (*) (void)) strcmp,
|
||||||
0,
|
0,
|
||||||
(splay_tree_delete_value_fn) free);
|
(splay_tree_delete_value_fn)
|
||||||
|
(void (*) (void)) free);
|
||||||
|
|
||||||
n = splay_tree_lookup (file_info_tree, (splay_tree_key) name);
|
n = splay_tree_lookup (file_info_tree, (splay_tree_key) name);
|
||||||
if (n)
|
if (n)
|
||||||
|
@ -299,7 +299,7 @@ scan_translation_unit_directives_only (cpp_reader *pfile)
|
|||||||
struct _cpp_dir_only_callbacks cb;
|
struct _cpp_dir_only_callbacks cb;
|
||||||
|
|
||||||
cb.print_lines = print_lines_directives_only;
|
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);
|
_cpp_preprocess_dir_only (pfile, &cb);
|
||||||
}
|
}
|
||||||
|
@ -384,6 +384,10 @@ Wc++17-compat
|
|||||||
C++ ObjC++ Var(warn_cxx17_compat) Warning LangEnabledBy(C++ ObjC++,Wall)
|
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.
|
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
|
Wcast-qual
|
||||||
C ObjC C++ ObjC++ Var(warn_cast_qual) Warning
|
C ObjC C++ ObjC++ Var(warn_cast_qual) Warning
|
||||||
Warn about casts which discard qualifiers.
|
Warn about casts which discard qualifiers.
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2017-12-14 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||||
|
|
||||||
|
* c-typeck.c (c_safe_arg_type_equiv_p,
|
||||||
|
c_safe_function_type_cast_p): New function.
|
||||||
|
(build_c_cast): Implement -Wcast-function-type.
|
||||||
|
|
||||||
2017-12-14 Richard Biener <rguenther@suse.de>
|
2017-12-14 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
PR c/83415
|
PR c/83415
|
||||||
|
@ -5472,6 +5472,59 @@ handle_warn_cast_qual (location_t loc, tree type, tree otype)
|
|||||||
while (TREE_CODE (in_type) == POINTER_TYPE);
|
while (TREE_CODE (in_type) == POINTER_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Heuristic check if two parameter types can be considered ABI-equivalent. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
c_safe_arg_type_equiv_p (tree t1, tree t2)
|
||||||
|
{
|
||||||
|
t1 = TYPE_MAIN_VARIANT (t1);
|
||||||
|
t2 = TYPE_MAIN_VARIANT (t2);
|
||||||
|
|
||||||
|
if (TREE_CODE (t1) == POINTER_TYPE
|
||||||
|
&& TREE_CODE (t2) == POINTER_TYPE)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* The signedness of the parameter matters only when an integral
|
||||||
|
type smaller than int is promoted to int, otherwise only the
|
||||||
|
precision of the parameter matters.
|
||||||
|
This check should make sure that the callee does not see
|
||||||
|
undefined values in argument registers. */
|
||||||
|
if (INTEGRAL_TYPE_P (t1)
|
||||||
|
&& INTEGRAL_TYPE_P (t2)
|
||||||
|
&& TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
|
||||||
|
&& (TYPE_UNSIGNED (t1) == TYPE_UNSIGNED (t2)
|
||||||
|
|| !targetm.calls.promote_prototypes (NULL_TREE)
|
||||||
|
|| TYPE_PRECISION (t1) >= TYPE_PRECISION (integer_type_node)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return comptypes (t1, t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if a type cast between two function types can be considered safe. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
c_safe_function_type_cast_p (tree t1, tree t2)
|
||||||
|
{
|
||||||
|
if (TREE_TYPE (t1) == void_type_node &&
|
||||||
|
TYPE_ARG_TYPES (t1) == void_list_node)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (TREE_TYPE (t2) == void_type_node &&
|
||||||
|
TYPE_ARG_TYPES (t2) == void_list_node)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!c_safe_arg_type_equiv_p (TREE_TYPE (t1), TREE_TYPE (t2)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (t1 = TYPE_ARG_TYPES (t1), t2 = TYPE_ARG_TYPES (t2);
|
||||||
|
t1 && t2;
|
||||||
|
t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
|
||||||
|
if (!c_safe_arg_type_equiv_p (TREE_VALUE (t1), TREE_VALUE (t2)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Build an expression representing a cast to type TYPE of expression EXPR.
|
/* Build an expression representing a cast to type TYPE of expression EXPR.
|
||||||
LOC is the location of the cast-- typically the open paren of the cast. */
|
LOC is the location of the cast-- typically the open paren of the cast. */
|
||||||
|
|
||||||
@ -5665,6 +5718,16 @@ build_c_cast (location_t loc, tree type, tree expr)
|
|||||||
pedwarn (loc, OPT_Wpedantic, "ISO C forbids "
|
pedwarn (loc, OPT_Wpedantic, "ISO C forbids "
|
||||||
"conversion of object pointer to function pointer type");
|
"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
|
||||||
|
&& !c_safe_function_type_cast_p (TREE_TYPE (type),
|
||||||
|
TREE_TYPE (otype)))
|
||||||
|
warning_at (loc, OPT_Wcast_function_type,
|
||||||
|
"cast between incompatible function types"
|
||||||
|
" from %qT to %qT", otype, type);
|
||||||
|
|
||||||
ovalue = value;
|
ovalue = value;
|
||||||
value = convert (type, value);
|
value = convert (type, value);
|
||||||
|
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2017-12-14 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||||
|
|
||||||
|
* decl2.c (start_static_storage_duration_function): Avoid warning.
|
||||||
|
* typeck.c (cxx_safe_arg_type_equiv_p,
|
||||||
|
cxx_safe_function_type_cast_p): New function.
|
||||||
|
(build_reinterpret_cast_1): Implement -Wcast-function-type.
|
||||||
|
|
||||||
2017-12-14 Jakub Jelinek <jakub@redhat.com>
|
2017-12-14 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR c++/79650
|
PR c++/79650
|
||||||
|
@ -3558,7 +3558,8 @@ start_static_storage_duration_function (unsigned count)
|
|||||||
priority_info_map = splay_tree_new (splay_tree_compare_ints,
|
priority_info_map = splay_tree_new (splay_tree_compare_ints,
|
||||||
/*delete_key_fn=*/0,
|
/*delete_key_fn=*/0,
|
||||||
/*delete_value_fn=*/
|
/*delete_value_fn=*/
|
||||||
(splay_tree_delete_value_fn) &free);
|
(splay_tree_delete_value_fn)
|
||||||
|
(void (*) (void)) free);
|
||||||
|
|
||||||
/* We always need to generate functions for the
|
/* We always need to generate functions for the
|
||||||
DEFAULT_INIT_PRIORITY so enter it now. That way when we walk
|
DEFAULT_INIT_PRIORITY so enter it now. That way when we walk
|
||||||
|
@ -1173,6 +1173,59 @@ comp_template_parms_position (tree t1, tree t2)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Heuristic check if two parameter types can be considered ABI-equivalent. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cxx_safe_arg_type_equiv_p (tree t1, tree t2)
|
||||||
|
{
|
||||||
|
t1 = TYPE_MAIN_VARIANT (t1);
|
||||||
|
t2 = TYPE_MAIN_VARIANT (t2);
|
||||||
|
|
||||||
|
if (TREE_CODE (t1) == POINTER_TYPE
|
||||||
|
&& TREE_CODE (t2) == POINTER_TYPE)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/* The signedness of the parameter matters only when an integral
|
||||||
|
type smaller than int is promoted to int, otherwise only the
|
||||||
|
precision of the parameter matters.
|
||||||
|
This check should make sure that the callee does not see
|
||||||
|
undefined values in argument registers. */
|
||||||
|
if (INTEGRAL_TYPE_P (t1)
|
||||||
|
&& INTEGRAL_TYPE_P (t2)
|
||||||
|
&& TYPE_PRECISION (t1) == TYPE_PRECISION (t2)
|
||||||
|
&& (TYPE_UNSIGNED (t1) == TYPE_UNSIGNED (t2)
|
||||||
|
|| !targetm.calls.promote_prototypes (NULL_TREE)
|
||||||
|
|| TYPE_PRECISION (t1) >= TYPE_PRECISION (integer_type_node)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return same_type_p (t1, t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if a type cast between two function types can be considered safe. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cxx_safe_function_type_cast_p (tree t1, tree t2)
|
||||||
|
{
|
||||||
|
if (TREE_TYPE (t1) == void_type_node &&
|
||||||
|
TYPE_ARG_TYPES (t1) == void_list_node)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (TREE_TYPE (t2) == void_type_node &&
|
||||||
|
TYPE_ARG_TYPES (t2) == void_list_node)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!cxx_safe_arg_type_equiv_p (TREE_TYPE (t1), TREE_TYPE (t2)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (t1 = TYPE_ARG_TYPES (t1), t2 = TYPE_ARG_TYPES (t2);
|
||||||
|
t1 && t2;
|
||||||
|
t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
|
||||||
|
if (!cxx_safe_arg_type_equiv_p (TREE_VALUE (t1), TREE_VALUE (t2)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Subroutine in comptypes. */
|
/* Subroutine in comptypes. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -7326,9 +7379,27 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
|
|||||||
&& same_type_p (type, intype))
|
&& same_type_p (type, intype))
|
||||||
/* DR 799 */
|
/* DR 799 */
|
||||||
return rvalue (expr);
|
return rvalue (expr);
|
||||||
else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
|
else if (TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
|
||||||
|| (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
|
{
|
||||||
return build_nop (type, expr);
|
if ((complain & tf_warning)
|
||||||
|
&& !cxx_safe_function_type_cast_p (TREE_TYPE (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))
|
||||||
|
{
|
||||||
|
if ((complain & tf_warning)
|
||||||
|
&& !cxx_safe_function_type_cast_p
|
||||||
|
(TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (type)),
|
||||||
|
TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (intype))))
|
||||||
|
warning (OPT_Wcast_function_type,
|
||||||
|
"cast between incompatible pointer to member types"
|
||||||
|
" from %qH to %qI", intype, type);
|
||||||
|
return build_nop (type, expr);
|
||||||
|
}
|
||||||
else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
|
else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
|
||||||
|| (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
|
|| (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
|
||||||
{
|
{
|
||||||
|
@ -267,7 +267,7 @@ Objective-C and Objective-C++ Dialects}.
|
|||||||
-Wno-builtin-declaration-mismatch @gol
|
-Wno-builtin-declaration-mismatch @gol
|
||||||
-Wno-builtin-macro-redefined -Wc90-c99-compat -Wc99-c11-compat @gol
|
-Wno-builtin-macro-redefined -Wc90-c99-compat -Wc99-c11-compat @gol
|
||||||
-Wc++-compat -Wc++11-compat -Wc++14-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
|
-Wchar-subscripts -Wchkp -Wcatch-value -Wcatch-value=@var{n} @gol
|
||||||
-Wclobbered -Wcomment -Wconditionally-supported @gol
|
-Wclobbered -Wcomment -Wconditionally-supported @gol
|
||||||
-Wconversion -Wcoverage-mismatch -Wno-cpp -Wdangling-else -Wdate-time @gol
|
-Wconversion -Wcoverage-mismatch -Wno-cpp -Wdangling-else -Wdate-time @gol
|
||||||
@ -3904,6 +3904,7 @@ This enables some extra warning flags that are not enabled by
|
|||||||
name is still supported, but the newer name is more descriptive.)
|
name is still supported, but the newer name is more descriptive.)
|
||||||
|
|
||||||
@gccoptlist{-Wclobbered @gol
|
@gccoptlist{-Wclobbered @gol
|
||||||
|
-Wcast-function-type @gol
|
||||||
-Wempty-body @gol
|
-Wempty-body @gol
|
||||||
-Wignored-qualifiers @gol
|
-Wignored-qualifiers @gol
|
||||||
-Wimplicit-fallthrough=3 @gol
|
-Wimplicit-fallthrough=3 @gol
|
||||||
@ -6041,6 +6042,21 @@ Warn whenever a pointer is cast such that the required alignment of the
|
|||||||
target is increased. For example, warn if a @code{char *} is cast to
|
target is increased. For example, warn if a @code{char *} is cast to
|
||||||
an @code{int *} regardless of the target machine.
|
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.
|
||||||
|
In a cast involving function types with a variable argument list only
|
||||||
|
the types of initial arguments that are provided are considered.
|
||||||
|
Any parameter of pointer-type matches any other pointer-type. Any benign
|
||||||
|
differences in integral types are ignored, like @code{int} vs. @code{long}
|
||||||
|
on ILP32 targets. Likewise type qualifiers are ignored. The function
|
||||||
|
type @code{void (*) (void)} is special and matches everything, which can
|
||||||
|
be used to suppress this warning.
|
||||||
|
In a cast involving pointer to member types this warning warns whenever
|
||||||
|
the type cast is changing the pointer to member type.
|
||||||
|
This warning is enabled by @option{-Wextra}.
|
||||||
|
|
||||||
@item -Wwrite-strings
|
@item -Wwrite-strings
|
||||||
@opindex Wwrite-strings
|
@opindex Wwrite-strings
|
||||||
@opindex Wno-write-strings
|
@opindex Wno-write-strings
|
||||||
|
@ -294,7 +294,7 @@ struct insn_gen_fn
|
|||||||
typedef rtx_insn * (*f15) (rtx, 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_insn * (*f16) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
|
||||||
|
|
||||||
typedef f0 stored_funcptr;
|
typedef void (*stored_funcptr) (void);
|
||||||
|
|
||||||
rtx_insn * operator () (void) const { return ((f0)func) (); }
|
rtx_insn * operator () (void) const { return ((f0)func) (); }
|
||||||
rtx_insn * operator () (rtx a0) const { return ((f1)func) (a0); }
|
rtx_insn * operator () (rtx a0) const { return ((f1)func) (a0); }
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2017-12-14 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||||
|
|
||||||
|
* c-c++-common/Wcast-function-type.c: New test.
|
||||||
|
* g++.dg/Wcast-function-type.C: New test.
|
||||||
|
|
||||||
2017-12-14 Qing Zhao <qing.zhao@oracle.com>
|
2017-12-14 Qing Zhao <qing.zhao@oracle.com>
|
||||||
|
|
||||||
PR middle_end/79538
|
PR middle_end/79538
|
||||||
|
31
gcc/testsuite/c-c++-common/Wcast-function-type.c
Normal file
31
gcc/testsuite/c-c++-common/Wcast-function-type.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* { 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
|
||||||
|
typedef void (f5)(void);
|
||||||
|
|
||||||
|
f1 *a;
|
||||||
|
f2 *b;
|
||||||
|
f3 *c;
|
||||||
|
f4 *d;
|
||||||
|
f5 *e;
|
||||||
|
|
||||||
|
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" } */
|
||||||
|
e = (f5 *) f; /* { dg-bogus "incompatible function types" } */
|
||||||
|
}
|
17
gcc/testsuite/g++.dg/Wcast-function-type.C
Normal file
17
gcc/testsuite/g++.dg/Wcast-function-type.C
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-Wcast-function-type" } */
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
void foo (int*);
|
||||||
|
void bar (int);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (S::*MF)(int);
|
||||||
|
|
||||||
|
void
|
||||||
|
foo (void)
|
||||||
|
{
|
||||||
|
MF p1 = (MF)&S::foo; /* { dg-warning "pointer to member" } */
|
||||||
|
MF p2 = (MF)&S::bar; /* { dg-bogus "pointer to member" } */
|
||||||
|
}
|
@ -736,7 +736,8 @@ dump_node (const_tree t, dump_flags_t flags, FILE *stream)
|
|||||||
di.flags = flags;
|
di.flags = flags;
|
||||||
di.node = t;
|
di.node = t;
|
||||||
di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
|
di.nodes = splay_tree_new (splay_tree_compare_pointers, 0,
|
||||||
(splay_tree_delete_value_fn) &free);
|
(splay_tree_delete_value_fn)
|
||||||
|
(void (*) (void)) free);
|
||||||
|
|
||||||
/* Queue up the first node. */
|
/* Queue up the first node. */
|
||||||
queue (&di, t, DUMP_NONE);
|
queue (&di, t, DUMP_NONE);
|
||||||
|
@ -75,9 +75,12 @@ inline typed_splay_tree<KEY_TYPE, VALUE_TYPE>::
|
|||||||
delete_key_fn delete_key_fn,
|
delete_key_fn delete_key_fn,
|
||||||
delete_value_fn delete_value_fn)
|
delete_value_fn delete_value_fn)
|
||||||
{
|
{
|
||||||
m_inner = splay_tree_new ((splay_tree_compare_fn)compare_fn,
|
m_inner = splay_tree_new ((splay_tree_compare_fn)
|
||||||
(splay_tree_delete_key_fn)delete_key_fn,
|
(void (*) (void)) compare_fn,
|
||||||
(splay_tree_delete_value_fn)delete_value_fn);
|
(splay_tree_delete_key_fn)
|
||||||
|
(void (*) (void)) delete_key_fn,
|
||||||
|
(splay_tree_delete_value_fn)
|
||||||
|
(void (*) (void)) delete_value_fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destructor for typed_splay_tree <K, V>. */
|
/* Destructor for typed_splay_tree <K, V>. */
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2017-12-14 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||||
|
|
||||||
|
* internal.h (maybe_print_line): Change signature.
|
||||||
|
|
||||||
2017-12-05 Jakub Jelinek <jakub@redhat.com>
|
2017-12-05 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR c++/79228
|
PR c++/79228
|
||||||
|
@ -709,7 +709,7 @@ struct _cpp_dir_only_callbacks
|
|||||||
{
|
{
|
||||||
/* Called to print a block of lines. */
|
/* Called to print a block of lines. */
|
||||||
void (*print_lines) (int, const void *, size_t);
|
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 *,
|
extern void _cpp_preprocess_dir_only (cpp_reader *,
|
||||||
|
Loading…
Reference in New Issue
Block a user