Commit 3897f229 by Joseph Myers Committed by Joseph Myers

re PR c/11234 (-pedantic accepts function pointer <-> void*)

	PR c/11234
	* c-typeck.c (build_c_cast): If pedantic, warn for conversions
	between function and object pointers.
	(digest_init): When comparing a pointer to function type to the
	target type, only apply TREE_TYPE once to the pointer to function
	type.
	* except.c (for_each_eh_label_1): Treat data as a pointer to a
	function pointer rather than casting it to a function pointer.
	(for_each_eh_label): Update caller.
	* recog.h (struct insn_data): Use a struct or union for output.
	* genoutput.c (output_insn_data): Update.
	* final.c (get_insn_template): Update.

testsuite:
	* gcc.dg/func-ptr-conv-1.c: New test.
	* gcc.dg/weak/weak-6.c, gcc.dg/weak/weak-7.c: Update.

From-SVN: r75595
parent 0fab64a3
2004-01-09 Joseph S. Myers <jsm@polyomino.org.uk>
PR c/11234
* c-typeck.c (build_c_cast): If pedantic, warn for conversions
between function and object pointers.
(digest_init): When comparing a pointer to function type to the
target type, only apply TREE_TYPE once to the pointer to function
type.
* except.c (for_each_eh_label_1): Treat data as a pointer to a
function pointer rather than casting it to a function pointer.
(for_each_eh_label): Update caller.
* recog.h (struct insn_data): Use a struct or union for output.
* genoutput.c (output_insn_data): Update.
* final.c (get_insn_template): Update.
2004-01-09 Mark Mitchell <mark@codesourcery.com>
* expr.h (expand_expr): Make it a macro, not a function.
......
......@@ -3125,6 +3125,25 @@ build_c_cast (tree type, tree expr)
warning ("dereferencing type-punned pointer will break strict-aliasing rules");
}
/* If pedantic, warn for conversions between function and object
pointer types, except for converting a null pointer constant
to function pointer type. */
if (pedantic
&& TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (otype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE
&& TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
pedwarn ("ISO C forbids conversion of function pointer to object pointer type");
if (pedantic
&& TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (otype) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
&& TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
&& !(integer_zerop (value) && TREE_TYPE (otype) == void_type_node
&& TREE_CODE (expr) != NOP_EXPR))
pedwarn ("ISO C forbids conversion of object pointer to function pointer type");
ovalue = value;
/* Replace a nonvolatile const static variable with its value. */
if (optimize && TREE_CODE (value) == VAR_DECL)
......@@ -4088,9 +4107,12 @@ digest_init (tree type, tree init, int require_constant)
|| (code == VECTOR_TYPE
&& comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT))
|| (code == POINTER_TYPE
&& (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)
&& TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
&& comptypes (TREE_TYPE (TREE_TYPE (inside_init)),
TREE_TYPE (type), COMPARE_STRICT))
|| (code == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE
&& comptypes (TREE_TYPE (inside_init),
TREE_TYPE (type), COMPARE_STRICT))))
{
if (code == POINTER_TYPE)
......
/* Implements exception handling.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Mike Stump <mrs@cygnus.com>.
This file is part of GCC.
......@@ -2430,14 +2430,14 @@ void
for_each_eh_label (void (*callback) (rtx))
{
htab_traverse (cfun->eh->exception_handler_label_map, for_each_eh_label_1,
(void *)callback);
(void *) &callback);
}
static int
for_each_eh_label_1 (void **pentry, void *data)
{
struct ehl_map_entry *entry = *(struct ehl_map_entry **)pentry;
void (*callback) (rtx) = (void (*) (rtx)) data;
void (*callback) (rtx) = *(void (**) (rtx)) data;
(*callback) (entry->label);
return 1;
......
/* Convert RTL to assembler code and output it, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -1591,17 +1591,16 @@ final (rtx first, FILE *file, int optimize, int prescan)
const char *
get_insn_template (int code, rtx insn)
{
const void *output = insn_data[code].output;
switch (insn_data[code].output_format)
{
case INSN_OUTPUT_FORMAT_SINGLE:
return (const char *) output;
return insn_data[code].output.single;
case INSN_OUTPUT_FORMAT_MULTI:
return ((const char *const *) output)[which_alternative];
return insn_data[code].output.multi[which_alternative];
case INSN_OUTPUT_FORMAT_FUNCTION:
if (insn == NULL)
abort ();
return (*(insn_output_fn) output) (recog_data.operand, insn);
return (*insn_data[code].output.function) (recog_data.operand, insn);
default:
abort ();
......
/* Generate code from to output assembler insns as recognized from rtl.
Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002,
2003 Free Software Foundation, Inc.
2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
......@@ -286,6 +286,7 @@ output_insn_data (void)
break;
}
printf ("#if GCC_VERSION >= 2007\n__extension__\n#endif\n");
printf ("\nconst struct insn_data insn_data[] = \n{\n");
for (d = idata; d; d = d->next)
......@@ -322,13 +323,22 @@ output_insn_data (void)
switch (d->output_format)
{
case INSN_OUTPUT_FORMAT_NONE:
printf (" 0,\n");
printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
printf (" { 0 },\n");
printf ("#else\n");
printf (" { 0, 0, 0 },\n");
printf ("#endif\n");
break;
case INSN_OUTPUT_FORMAT_SINGLE:
{
const char *p = d->template;
char prev = 0;
printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
printf (" { .single =\n");
printf ("#else\n");
printf (" {\n");
printf ("#endif\n");
printf (" \"");
while (*p)
{
......@@ -345,11 +355,26 @@ output_insn_data (void)
++p;
}
printf ("\",\n");
printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
printf (" },\n");
printf ("#else\n");
printf (" 0, 0 },\n");
printf ("#endif\n");
}
break;
case INSN_OUTPUT_FORMAT_MULTI:
printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
printf (" { .multi = output_%d },\n", d->code_number);
printf ("#else\n");
printf (" { 0, output_%d, 0 },\n", d->code_number);
printf ("#endif\n");
break;
case INSN_OUTPUT_FORMAT_FUNCTION:
printf (" (const void *) output_%d,\n", d->code_number);
printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
printf (" { .function = output_%d },\n", d->code_number);
printf ("#else\n");
printf (" { 0, 0, output_%d },\n", d->code_number);
printf ("#endif\n");
break;
default:
abort ();
......
/* Declarations for interface to insn recognizer and insn-output.c.
Copyright (C) 1987, 1996, 1997, 1998, 1999, 2000, 2001, 2003
Copyright (C) 1987, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
......@@ -238,7 +238,19 @@ struct insn_operand_data
struct insn_data
{
const char *const name;
const void *output;
#if HAVE_DESIGNATED_INITIALIZERS
union {
const char *single;
const char *const *multi;
insn_output_fn function;
} output;
#else
struct {
const char *single;
const char *const *multi;
insn_output_fn function;
} output;
#endif
const insn_gen_fn genfun;
const struct insn_operand_data *const operand;
......
2004-01-09 Joseph S. Myers <jsm@polyomino.org.uk>
PR c/11234
* gcc.dg/func-ptr-conv-1.c: New test.
* gcc.dg/weak/weak-6.c, gcc.dg/weak/weak-7.c: Update.
2004-01-09 Kazu Hirata <kazu@cs.umass.edu>
PR target/13380.
......
/* Conversions between function and object pointers are not permitted
in any version of ISO C, even with casts, except for the special
case of converting a null pointer constant to function pointer
type. Likewise, comparisons between function and object pointers
are not permitted. PR c/11234. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
/* { dg-options "-pedantic" } */
void f(void);
void *v1 = f; /* { dg-warning "pointer" "bad conversion" } */
void *v2 = &f; /* { dg-warning "pointer" "bad conversion" } */
void *v3 = (void *)f; /* { dg-warning "pointer" "bad conversion" } */
void *v4 = (void *)&f; /* { dg-warning "pointer" "bad conversion" } */
void *v5;
char *c1 = f; /* { dg-warning "pointer" "bad conversion" } */
char *c2 = &f; /* { dg-warning "pointer" "bad conversion" } */
char *c3 = (char *)f; /* { dg-warning "pointer" "bad conversion" } */
char *c4 = (char *)&f; /* { dg-warning "pointer" "bad conversion" } */
char *c5;
void (*fp)(void);
int a;
void
g(void)
{
v5 = f; /* { dg-warning "pointer" "bad conversion" } */
v5 = &f; /* { dg-warning "pointer" "bad conversion" } */
v5 = (void *)f; /* { dg-warning "pointer" "bad conversion" } */
v5 = (void *)&f; /* { dg-warning "pointer" "bad conversion" } */
c5 = f; /* { dg-warning "pointer" "bad conversion" } */
c5 = &f; /* { dg-warning "pointer" "bad conversion" } */
c5 = (char *)f; /* { dg-warning "pointer" "bad conversion" } */
c5 = (char *)&f; /* { dg-warning "pointer" "bad conversion" } */
fp = v5; /* { dg-warning "pointer" "bad conversion" } */
fp = c5; /* { dg-warning "pointer" "bad conversion" } */
fp = (void (*)(void))v5; /* { dg-warning "pointer" "bad conversion" } */
fp = (void (*)(void))c5; /* { dg-warning "pointer" "bad conversion" } */
(a ? f : v3); /* { dg-warning "pointer" "bad conversion" } */
(a ? v2 : fp); /* { dg-warning "pointer" "bad conversion" } */
/* The following are OK. */
fp = 0;
fp = (void *)0;
fp = 0L;
fp = (void (*)(void))0;
fp = (void (*)(void))(void *)0;
(a ? f : 0);
(a ? f : (void *)0);
(a ? (void *)0 : fp);
(a ? 0 : fp);
}
/* The following are OK. */
void (*fp2)(void) = 0;
void (*fp3)(void) = (void *)0;
......@@ -3,5 +3,5 @@
extern void * foo (void);
void * foo (void) { return (void *)foo; } /* { dg-error "precede" } */
/* { dg-error "function pointer" "pointer conversion" { target *-*-* } 5 } */
#pragma weak foo
......@@ -3,5 +3,5 @@
extern void * foo (void);
void * foo (void) { return (void *)foo; } /* { dg-error "precede" } */
/* { dg-error "function pointer" "pointer conversion" { target *-*-* } 5 } */
extern void * foo (void) __attribute__((weak));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment