diff --git a/memcheck/docs/mc-manual.xml b/memcheck/docs/mc-manual.xml
index 330355440..4b70e64a1 100644
--- a/memcheck/docs/mc-manual.xml
+++ b/memcheck/docs/mc-manual.xml
@@ -970,6 +970,24 @@ is
+
+
+
+
+
+ Controls whether Memcheck should employ more precise but also more
+ expensive (time consuming) algorithms when checking the definedness of a
+ value. The default setting is not to do that and it is usually
+ sufficient. However, for highly optimised code valgrind may sometimes
+ incorrectly complain.
+ Invoking valgrind with
+ helps but comes at a performance cost. Runtime degradation of
+ 25% have been observed but the extra cost depends a lot on the
+ application at hand.
+
+
+
+
diff --git a/memcheck/mc_include.h b/memcheck/mc_include.h
index 1d62bf604..8ae7a8ac9 100644
--- a/memcheck/mc_include.h
+++ b/memcheck/mc_include.h
@@ -695,6 +695,9 @@ extern Int MC_(clo_mc_level);
/* Should we show mismatched frees? Default: YES */
extern Bool MC_(clo_show_mismatched_frees);
+/* Should we use expensive definedness checking for add/sub and compare
+ operations? Default: NO */
+extern Bool MC_(clo_expensive_definedness_check);
/*------------------------------------------------------------*/
/*--- Instrumentation ---*/
diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c
index 580c051c5..674a50d71 100644
--- a/memcheck/mc_main.c
+++ b/memcheck/mc_main.c
@@ -5711,6 +5711,7 @@ Int MC_(clo_free_fill) = -1;
KeepStacktraces MC_(clo_keep_stacktraces) = KS_alloc_then_free;
Int MC_(clo_mc_level) = 2;
Bool MC_(clo_show_mismatched_frees) = True;
+Bool MC_(clo_expensive_definedness_check) = False;
static const HChar * MC_(parse_leak_heuristics_tokens) =
"-,stdstring,length64,newarray,multipleinheritance";
@@ -5857,6 +5858,8 @@ static Bool mc_process_cmd_line_options(const HChar* arg)
else if VG_BOOL_CLO(arg, "--show-mismatched-frees",
MC_(clo_show_mismatched_frees)) {}
+ else if VG_BOOL_CLO(arg, "--expensive-definedness-check",
+ MC_(clo_expensive_definedness_check)) {}
else
return VG_(replacement_malloc_process_cmd_line_option)(arg);
diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c
index a6697cc82..6e5941bf2 100644
--- a/memcheck/mc_translate.c
+++ b/memcheck/mc_translate.c
@@ -6313,29 +6313,35 @@ IRSB* MC_(instrument) ( VgCallbackClosure* closure,
}
tl_assert( VG_(sizeXA)( mce.tmpMap ) == sb_in->tyenv->types_used );
- /* Make a preliminary inspection of the statements, to see if there
- are any dodgy-looking literals. If there are, we generate
- extra-detailed (hence extra-expensive) instrumentation in
- places. Scan the whole bb even if dodgyness is found earlier,
- so that the flatness assertion is applied to all stmts. */
- Bool bogus = False;
+ if (MC_(clo_expensive_definedness_check)) {
+ /* For expensive definedness checking skip looking for bogus
+ literals. */
+ mce.bogusLiterals = True;
+ } else {
+ /* Make a preliminary inspection of the statements, to see if there
+ are any dodgy-looking literals. If there are, we generate
+ extra-detailed (hence extra-expensive) instrumentation in
+ places. Scan the whole bb even if dodgyness is found earlier,
+ so that the flatness assertion is applied to all stmts. */
+ Bool bogus = False;
- for (i = 0; i < sb_in->stmts_used; i++) {
- st = sb_in->stmts[i];
- tl_assert(st);
- tl_assert(isFlatIRStmt(st));
+ for (i = 0; i < sb_in->stmts_used; i++) {
+ st = sb_in->stmts[i];
+ tl_assert(st);
+ tl_assert(isFlatIRStmt(st));
- if (!bogus) {
- bogus = checkForBogusLiterals(st);
- if (0 && bogus) {
- VG_(printf)("bogus: ");
- ppIRStmt(st);
- VG_(printf)("\n");
+ if (!bogus) {
+ bogus = checkForBogusLiterals(st);
+ if (0 && bogus) {
+ VG_(printf)("bogus: ");
+ ppIRStmt(st);
+ VG_(printf)("\n");
+ }
+ if (bogus) break;
}
- if (bogus) break;
}
+ mce.bogusLiterals = bogus;
}
- mce.bogusLiterals = bogus;
/* Copy verbatim any IR preamble preceding the first IMark */
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
index 0a850a2ed..0a22e5e3a 100644
--- a/memcheck/tests/Makefile.am
+++ b/memcheck/tests/Makefile.am
@@ -84,6 +84,7 @@ EXTRA_DIST = \
buflen_check.stderr.exp-kfail \
bug155125.stderr.exp bug155125.vgtest \
bug287260.stderr.exp bug287260.vgtest \
+ bug340392.stderr.exp bug340392.vgtest \
calloc-overflow.stderr.exp calloc-overflow.vgtest\
client-msg.stderr.exp client-msg.vgtest \
client-msg-as-xml.stderr.exp client-msg-as-xml.vgtest \
@@ -308,6 +309,7 @@ check_PROGRAMS = \
buflen_check \
bug155125 \
bug287260 \
+ bug340392 \
calloc-overflow \
client-msg \
clientperm \
@@ -418,6 +420,7 @@ leak_cpp_interior_SOURCES = leak_cpp_interior.cpp
demangle_SOURCES = demangle.cpp
+bug340392_CFLAGS = $(AM_CFLAGS) -O3
dw4_CFLAGS = $(AM_CFLAGS) -gdwarf-4 -fdebug-types-section
descr_belowsp_LDADD = -lpthread
diff --git a/memcheck/tests/bug340392.c b/memcheck/tests/bug340392.c
new file mode 100644
index 000000000..c95bdf937
--- /dev/null
+++ b/memcheck/tests/bug340392.c
@@ -0,0 +1,26 @@
+#include
+
+typedef struct {
+ unsigned char c;
+ int i;
+ void *foo;
+} S;
+
+S *make_s (void);
+
+int
+main (int argc, char **argv)
+{
+ S *s = make_s ();
+ if (s->c == 0 && s->i == 1 && s->foo == getenv ("BLAH"))
+ abort();
+ return 0;
+}
+
+S *
+make_s (void)
+{
+ S *res = malloc (sizeof (S));
+ res->c = 1;
+ return res;
+}
diff --git a/memcheck/tests/bug340392.stderr.exp b/memcheck/tests/bug340392.stderr.exp
new file mode 100644
index 000000000..e69de29bb
diff --git a/memcheck/tests/bug340392.vgtest b/memcheck/tests/bug340392.vgtest
new file mode 100644
index 000000000..fc585e572
--- /dev/null
+++ b/memcheck/tests/bug340392.vgtest
@@ -0,0 +1,10 @@
+# When run without --expensive-definedness-check valgrind
+# produces:
+#
+# ==10953== Conditional jump or move depends on uninitialised value(s)
+# ==10953== at 0x4004F8: main (bug340392.c:15)
+#
+# Making sure we don't get the message.
+#
+prog: bug340392
+vgopts: -q --expensive-definedness-check=yes