add heuristics decreasing false possible "possible leaks" in c++ code.

The option --leak-check-heuristics=heur1,heur2,... can activate
various heuristics to decrease the number of false positive
"possible leaks" for C++ code. The available heuristics are
detecting valid interior pointers to std::stdstring, to new[] allocated
arrays with elements having destructors and to interior pointers pointing
to an inner part of a C++ object using multiple inheritance.

This fixes 280271 Valgrind reports possible memory leaks on still-reachable
std::string 

This has been tested on x86/amd64/ppc32/ppc64.

First performance measurements seems to show a neglectible impact on
the leak search.

More feedback welcome both on performance and functional aspects
(false positive 'possibly leaked' rate decrease and/or 
false negative 'possibly leaked' rate increase).

Note that the heuristic is not checking that the memory has been
allocated with "new" or "new[]", as it is expected that in some cases,
specific alloc fn are used for c++ objects instead of the standard new/new[].
If needed, we might add an option to check the alloc functions
to be new/new[].



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13582 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/memcheck/mc_include.h b/memcheck/mc_include.h
index 24d53fd..728e7b8 100644
--- a/memcheck/mc_include.h
+++ b/memcheck/mc_include.h
@@ -342,8 +342,9 @@
       LeakCheckMode mode;
       UInt show_leak_kinds;
       UInt errors_for_leak_kinds;
+      UInt heuristics;
       LeakCheckDeltaMode deltamode;
-      UInt max_loss_records_output;       // limit on the nr of loss records output.
+      UInt max_loss_records_output; // limit on the nr of loss records output.
       Bool requested_by_monitor_command; // True when requested by gdb/vgdb.
    }
    LeakCheckParams;
@@ -354,8 +355,8 @@
 extern LeakCheckDeltaMode MC_(detect_memory_leaks_last_delta_mode);
 
 // prints the list of blocks corresponding to the given loss_record_nr.
-// Returns True if loss_record_nr identifies a correct loss record from last leak search.
-// Returns False otherwise.
+// Returns True if loss_record_nr identifies a correct loss record from last
+// leak search, returns False otherwise.
 Bool MC_(print_block_list) ( UInt loss_record_nr);
 
 // Prints the addresses/registers/... at which a pointer to
@@ -494,6 +495,39 @@
    Default : R2S(Possible) | R2S(Unreached). */
 extern UInt MC_(clo_errors_for_leak_kinds);
 
+/* Various leak check heuristics which can be activated/deactivated. */
+typedef 
+   enum {
+      LchNone                =0,
+      // no heuristic.
+      LchStdString           =1,
+      // Consider interior pointer pointing at the array of char in a
+      // std::string as reachable.
+      LchNewArray            =2,
+      // Consider interior pointer pointing at second word of a new[] array as
+      // reachable. Such interior pointers are used for arrays whose elements
+      // have a destructor.
+      LchMultipleInheritance =3,
+      // Conside interior pointer pointing just after what looks a vtable
+      // as reachable.
+  }
+  LeakCheckHeuristic;
+
+// Nr of heuristics.
+#define N_LEAK_CHECK_HEURISTICS 4
+
+// Build mask to check or set Heuristic h membership
+#define H2S(h) (1 << (h))
+// CppHeuristic h is member of the Set s ?
+#define HiS(h,s) ((s) & R2S(h))
+// A set with all Heuristics:
+#define HallS \
+   (H2S(LchStdString) | H2S(LchNewArray) | H2S(LchMultipleInheritance))
+
+/* Heuristics set to use for the leak search.
+   Default : no heuristic. */
+extern UInt MC_(clo_leak_check_heuristics);
+
 /* Assume accesses immediately below %esp are due to gcc-2.96 bugs.
  * default: NO */
 extern Bool MC_(clo_workaround_gcc296_bugs);