OSDN Git Service

PR c/11234
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Jan 2004 20:03:58 +0000 (20:03 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Jan 2004 20:03:58 +0000 (20:03 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@75595 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-typeck.c
gcc/except.c
gcc/final.c
gcc/genoutput.c
gcc/recog.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/func-ptr-conv-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/weak/weak-6.c
gcc/testsuite/gcc.dg/weak/weak-7.c

index 95c1eaa..89e7a22 100644 (file)
@@ -1,3 +1,18 @@
+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.
index 6d18f7e..ec00801 100644 (file)
@@ -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)
index 5958eae..1468d3b 100644 (file)
@@ -1,6 +1,6 @@
 /* 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;
index ea9aa4b..fbbff31 100644 (file)
@@ -1,6 +1,6 @@
 /* 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 ();
index 6a2e024..9e27b27 100644 (file)
@@ -1,6 +1,6 @@
 /* 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 ();
index 749c64b..a36c896 100644 (file)
@@ -1,5 +1,5 @@
 /* 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;
 
index 6b905bc..fa4e007 100644 (file)
@@ -1,3 +1,9 @@
+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.
diff --git a/gcc/testsuite/gcc.dg/func-ptr-conv-1.c b/gcc/testsuite/gcc.dg/func-ptr-conv-1.c
new file mode 100644 (file)
index 0000000..4e42e5f
--- /dev/null
@@ -0,0 +1,56 @@
+/* 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;
index 531c581..711003c 100644 (file)
@@ -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
index bf2bbb9..7c4a4dc 100644 (file)
@@ -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));