Bug 336619 valgrind --read-var-info=yes doesn't handle DW_TAG_restrict_type.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14165 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/NEWS b/NEWS
index 16415ab..fefa8f5 100644
--- a/NEWS
+++ b/NEWS
@@ -177,6 +177,7 @@
 335263  arm64: dmb instruction is not implemented
 335441  unhandled ioctl 0x8905 (SIOCATMARK) when running wine under valgrind
 335496  arm64: sbc/abc instructions are not implemented
+336619  valgrind --read-var-info=yes doesn't handle DW_TAG_restrict_type
 336772  Make moans about unknown ioctls more informative
 336957  Add a section about the Solaris/illumos port on the webpage
 337094  ifunc wrapper is broken on ppc64
diff --git a/coregrind/m_debuginfo/priv_tytypes.h b/coregrind/m_debuginfo/priv_tytypes.h
index 255090e..301e897 100644
--- a/coregrind/m_debuginfo/priv_tytypes.h
+++ b/coregrind/m_debuginfo/priv_tytypes.h
@@ -133,7 +133,7 @@
          struct {
          } TyFn;
          struct {
-            UChar qual; /* C:const V:volatile */
+            UChar qual; /* C:const V:volatile R:restrict */
             UWord typeR;
          } TyQual;
          struct {
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
index 0dd49df..7f7f3e9 100644
--- a/coregrind/m_debuginfo/readdwarf3.c
+++ b/coregrind/m_debuginfo/readdwarf3.c
@@ -3478,13 +3478,15 @@
       goto acquire_Type;
    }
 
-   if (dtag == DW_TAG_volatile_type || dtag == DW_TAG_const_type) {
+   if (dtag == DW_TAG_volatile_type || dtag == DW_TAG_const_type
+       || dtag == DW_TAG_restrict_type) {
       Int have_ty = 0;
       VG_(memset)(&typeE, 0, sizeof(typeE));
       typeE.cuOff = D3_INVALID_CUOFF;
       typeE.tag   = Te_TyQual;
       typeE.Te.TyQual.qual
-         = dtag == DW_TAG_volatile_type ? 'V' : 'C';
+         = (dtag == DW_TAG_volatile_type ? 'V'
+            : (dtag == DW_TAG_const_type ? 'C' : 'R'));
       /* target type defaults to 'void' */
       typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF;
       nf_i = 0;
diff --git a/coregrind/m_debuginfo/tytypes.c b/coregrind/m_debuginfo/tytypes.c
index 30f431d..abf6c18 100644
--- a/coregrind/m_debuginfo/tytypes.c
+++ b/coregrind/m_debuginfo/tytypes.c
@@ -297,6 +297,7 @@
          switch (ent->Te.TyQual.qual) {
             case 'C': VG_(printf)("const "); break;
             case 'V': VG_(printf)("volatile "); break;
+            case 'R': VG_(printf)("restrict "); break;
             default: goto unhandled;
          }
          ML_(pp_TyEnt_C_ishly)(tyents, ent->Te.TyQual.typeR);
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
index 06e5414..b0ba9c5 100644
--- a/memcheck/tests/Makefile.am
+++ b/memcheck/tests/Makefile.am
@@ -260,6 +260,7 @@
 		varinfo5.stderr.exp-ppc64 \
 	varinfo6.vgtest varinfo6.stdout.exp varinfo6.stderr.exp \
 		varinfo6.stderr.exp-ppc64 \
+	varinforestrict.vgtest varinforestrict.stderr.exp \
 	vcpu_bz2.stdout.exp vcpu_bz2.stderr.exp vcpu_bz2.vgtest \
 	vcpu_fbench.stdout.exp vcpu_fbench.stderr.exp vcpu_fbench.vgtest \
 	vcpu_fnfns.stdout.exp vcpu_fnfns.stdout.exp-glibc28-amd64 \
@@ -350,6 +351,7 @@
 	unit_libcbase unit_oset \
 	varinfo1 varinfo2 varinfo3 varinfo4 \
 	varinfo5 varinfo5so.so varinfo6 \
+	varinforestrict \
 	vcpu_fbench vcpu_fnfns \
 	wcs \
 	xml1 \
@@ -498,6 +500,7 @@
  varinfo5so_so_LDFLAGS  = -fpic $(AM_FLAG_M3264_PRI) -shared \
 				-Wl,-soname -Wl,varinfo5so.so
 endif
+varinforestrict_CFLAGS	= $(AM_CFLAGS) -O0 -g -std=c99
 
 # Build shared object for wrap7
 wrap7_SOURCES           = wrap7.c
diff --git a/memcheck/tests/varinforestrict.c b/memcheck/tests/varinforestrict.c
new file mode 100644
index 0000000..a009102
--- /dev/null
+++ b/memcheck/tests/varinforestrict.c
@@ -0,0 +1,59 @@
+// Simple program that uses C99 restrict qualifier.
+// Once GCC is fixed to output DW_TAG_restrict_type in the debuginfo
+// valgrind --read-var-info=yes would get a serious error reading the
+// debuginfo. This tests makes sure that a fixed GCC and a fixed valgrind
+// work well together.
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59051
+// https://bugs.kde.org/show_bug.cgi?id=336619
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "memcheck/memcheck.h"
+
+/* Cause memcheck to complain about the address "a" and so to print
+   its best guess as to what "a" actually is.  a must be addressible. */
+void croak ( void * restrict aV )
+{
+  char* a = (char*)aV;
+  char* undefp = malloc(1);
+  char saved = *a;
+  assert(undefp);
+  *a = *undefp;
+  (void) VALGRIND_CHECK_MEM_IS_DEFINED(a, 1);
+  *a = saved;
+  free(undefp);
+}
+
+void
+bad_restrict_ptr (char * restrict bad_ptr)
+{
+  croak (&bad_ptr);
+}
+
+char *
+cpy (char * restrict s1, const char * restrict s2, size_t n)
+{
+  char *t1 = s1;
+  const char *t2 = s2;
+  while(n-- > 0)
+    *t1++ = *t2++;
+  return s1;
+}
+
+int
+main (int argc, char **argv)
+{
+  const char *hello = "World";
+  size_t l = strlen (hello) + 1;
+  char *earth = malloc (l);
+  fprintf (stderr, "Hello %s\n", cpy (earth, hello, l));
+  free (earth);
+
+  const char *bad = malloc (16);
+  bad_restrict_ptr (bad);
+  free (bad);
+  return 0;
+}
diff --git a/memcheck/tests/varinforestrict.stderr.exp b/memcheck/tests/varinforestrict.stderr.exp
new file mode 100644
index 0000000..d84164b
--- /dev/null
+++ b/memcheck/tests/varinforestrict.stderr.exp
@@ -0,0 +1,8 @@
+Hello World
+Uninitialised byte(s) found during client check request
+   at 0x........: croak (varinforestrict.c:25)
+   by 0x........: bad_restrict_ptr (varinforestrict.c:33)
+   by 0x........: main (varinforestrict.c:56)
+ Location 0x........ is 0 bytes inside local var "bad_ptr"
+ declared at varinforestrict.c:31, in frame #1 of thread 1
+
diff --git a/memcheck/tests/varinforestrict.vgtest b/memcheck/tests/varinforestrict.vgtest
new file mode 100644
index 0000000..ff4862e
--- /dev/null
+++ b/memcheck/tests/varinforestrict.vgtest
@@ -0,0 +1,2 @@
+prog: varinforestrict
+vgopts: -q --read-var-info=yes