diff --git a/NEWS b/NEWS index 16415ab94..fefa8f57b 100644 --- a/NEWS +++ b/NEWS @@ -177,6 +177,7 @@ where XXXXXX is the bug number as listed below. 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 255090e41..301e8976d 100644 --- a/coregrind/m_debuginfo/priv_tytypes.h +++ b/coregrind/m_debuginfo/priv_tytypes.h @@ -133,7 +133,7 @@ typedef 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 0dd49df12..7f7f3e9db 100644 --- a/coregrind/m_debuginfo/readdwarf3.c +++ b/coregrind/m_debuginfo/readdwarf3.c @@ -3478,13 +3478,15 @@ static void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, 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 30f431d3b..abf6c1856 100644 --- a/coregrind/m_debuginfo/tytypes.c +++ b/coregrind/m_debuginfo/tytypes.c @@ -297,6 +297,7 @@ void ML_(pp_TyEnt_C_ishly)( XArray* /* of TyEnt */ tyents, 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 06e54147d..b0ba9c545 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -260,6 +260,7 @@ EXTRA_DIST = \ 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 @@ check_PROGRAMS = \ unit_libcbase unit_oset \ varinfo1 varinfo2 varinfo3 varinfo4 \ varinfo5 varinfo5so.so varinfo6 \ + varinforestrict \ vcpu_fbench vcpu_fnfns \ wcs \ xml1 \ @@ -498,6 +500,7 @@ else 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 000000000..a00910266 --- /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 +#include +#include +#include + +#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 000000000..d84164bfb --- /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 000000000..ff4862e70 --- /dev/null +++ b/memcheck/tests/varinforestrict.vgtest @@ -0,0 +1,2 @@ +prog: varinforestrict +vgopts: -q --read-var-info=yes