Avoid invalid pointer to pointer conversions.
authorPedro Alves <palves@redhat.com>
Mon, 11 Mar 2013 12:22:20 +0000 (12:22 +0000)
committerPedro Alves <palves@redhat.com>
Mon, 11 Mar 2013 12:22:20 +0000 (12:22 +0000)
Casts between 'char **' <-> 'unsigned char **' and 'char **' <-> const
char **' are actually invalid:

  http://gcc.gnu.org/ml/gcc-help/2013-03/msg00118.html

In a nutshell, char (and variants) can alias anything, but pointers to
chars get no special treatment (cf. C99/N1256, 6.5/7).

Turns out older gcc's actually warn/complain on these constructs,
though newer one's don't:

  http://sourceware.org/ml/gdb-patches/2013-03/msg00429.html
  http://sourceware.org/ml/gdb-patches/2013-03/msg00430.html

This patch fixes the cases I added last week.  It also fixes one other
preexisting case in charset.c, though it seems even older gccs don't
complain of char * <-> const char * aliasing.

Tested on x86_64 Fedora 17.

gdb/
2013-03-11  Pedro Alves  <palves@redhat.com>

* charset.c (convert_between_encodings): Don't cast between
different pointer to pointer types.  Instead, make the 'inp' local
be of the type iconv expects.
(wchar_iterate): Don't cast between different pointer to pointer
types.  Instead, use new pointer local of the type iconv expects.
* target.c (target_read_stralloc, target_fileio_read_stralloc):
Add new local of type char pointer, and use it to get a
char/string view of the byte buffer, instead of casting between
pointer to pointer types.

gdb/ChangeLog
gdb/charset.c
gdb/target.c

index 0993c7454eda378028f0e5fc2b3e09929c0ee57b..3334f622f66e959e69135bb4f0b80500ab0b6b19 100644 (file)
@@ -1,3 +1,15 @@
+2013-03-11  Pedro Alves  <palves@redhat.com>
+
+       * charset.c (convert_between_encodings): Don't cast between
+       different pointer to pointer types.  Instead, make the 'inp' local
+       be of the type iconv expects.
+       (wchar_iterate): Don't cast between different pointer to pointer
+       types.  Instead, use new pointer local of the type iconv expects.
+       * target.c (target_read_stralloc, target_fileio_read_stralloc):
+       Add new local of type char pointer, and use it to get a
+       char/string view of the byte buffer, instead of casting between
+       pointer to pointer types.
+
 2013-03-11  Hafiz Abid Qadeer  <abidh@codesourcery.com>
 
        * remote.c (remote_set_trace_buffer_size): Move != operator
index 4cd6f205a7d6f9eee61cc8483b3b74cd5e916534..5835fd40872e7df62bc875782d4c8f8890179ca9 100644 (file)
@@ -474,7 +474,7 @@ convert_between_encodings (const char *from, const char *to,
   iconv_t desc;
   struct cleanup *cleanups;
   size_t inleft;
-  char *inp;
+  ICONV_CONST char *inp;
   unsigned int space_request;
 
   /* Often, the host and target charsets will be the same.  */
@@ -490,7 +490,7 @@ convert_between_encodings (const char *from, const char *to,
   cleanups = make_cleanup (cleanup_iconv, &desc);
 
   inleft = num_bytes;
-  inp = (char *) bytes;
+  inp = (ICONV_CONST char *) bytes;
 
   space_request = num_bytes;
 
@@ -506,7 +506,7 @@ convert_between_encodings (const char *from, const char *to,
       outp = obstack_base (output) + old_size;
       outleft = space_request;
 
-      r = iconv (desc, (ICONV_CONST char **) &inp, &inleft, &outp, &outleft);
+      r = iconv (desc, &inp, &inleft, &outp, &outleft);
 
       /* Now make sure that the object on the obstack only includes
         bytes we have converted.  */
@@ -640,14 +640,15 @@ wchar_iterate (struct wchar_iterator *iter,
   out_request = 1;
   while (iter->bytes > 0)
     {
+      ICONV_CONST char *inptr = (ICONV_CONST char *) iter->input;
       char *outptr = (char *) &iter->out[0];
       const gdb_byte *orig_inptr = iter->input;
       size_t orig_in = iter->bytes;
       size_t out_avail = out_request * sizeof (gdb_wchar_t);
       size_t num;
-      size_t r = iconv (iter->desc,
-                       (ICONV_CONST char **) &iter->input, 
-                       &iter->bytes, &outptr, &out_avail);
+      size_t r = iconv (iter->desc, &inptr, &iter->bytes, &outptr, &out_avail);
+
+      iter->input = (gdb_byte *) inptr;
 
       if (r == (size_t) -1)
        {
index 0329da32adf0e4359e991122cd4862036ef3578a..a961d7b831ee2b9fe317c20aa18f6393a80db860 100644 (file)
@@ -2378,11 +2378,12 @@ char *
 target_read_stralloc (struct target_ops *ops, enum target_object object,
                      const char *annex)
 {
-  char *buffer;
+  gdb_byte *buffer;
+  char *bufstr;
   LONGEST i, transferred;
 
-  transferred = target_read_alloc_1 (ops, object, annex,
-                                    (gdb_byte **) &buffer, 1);
+  transferred = target_read_alloc_1 (ops, object, annex, &buffer, 1);
+  bufstr = (char *) buffer;
 
   if (transferred < 0)
     return NULL;
@@ -2390,11 +2391,11 @@ target_read_stralloc (struct target_ops *ops, enum target_object object,
   if (transferred == 0)
     return xstrdup ("");
 
-  buffer[transferred] = 0;
+  bufstr[transferred] = 0;
 
   /* Check for embedded NUL bytes; but allow trailing NULs.  */
-  for (i = strlen (buffer); i < transferred; i++)
-    if (buffer[i] != 0)
+  for (i = strlen (bufstr); i < transferred; i++)
+    if (bufstr[i] != 0)
       {
        warning (_("target object %d, annex %s, "
                   "contained unexpected null characters"),
@@ -2402,7 +2403,7 @@ target_read_stralloc (struct target_ops *ops, enum target_object object,
        break;
       }
 
-  return buffer;
+  return bufstr;
 }
 
 /* Memory transfer methods.  */
@@ -3542,11 +3543,12 @@ target_fileio_read_alloc (const char *filename, gdb_byte **buf_p)
 char *
 target_fileio_read_stralloc (const char *filename)
 {
-  char *buffer;
+  gdb_byte *buffer;
+  char *bufstr;
   LONGEST i, transferred;
 
-  transferred = target_fileio_read_alloc_1 (filename,
-                                           (gdb_byte **) &buffer, 1);
+  transferred = target_fileio_read_alloc_1 (filename, &buffer, 1);
+  bufstr = (char *) buffer;
 
   if (transferred < 0)
     return NULL;
@@ -3554,11 +3556,11 @@ target_fileio_read_stralloc (const char *filename)
   if (transferred == 0)
     return xstrdup ("");
 
-  buffer[transferred] = 0;
+  bufstr[transferred] = 0;
 
   /* Check for embedded NUL bytes; but allow trailing NULs.  */
-  for (i = strlen (buffer); i < transferred; i++)
-    if (buffer[i] != 0)
+  for (i = strlen (bufstr); i < transferred; i++)
+    if (bufstr[i] != 0)
       {
        warning (_("target file %s "
                   "contained unexpected null characters"),
@@ -3566,7 +3568,7 @@ target_fileio_read_stralloc (const char *filename)
        break;
       }
 
-  return buffer;
+  return bufstr;
 }
 
 
This page took 0.032574 seconds and 4 git commands to generate.