Completely overhauled the internals of Memcheck's error handling.  All the
different error kinds were reusing the same struct for storing their
details.  Each one used some but not all the fields, and the AddrInfo was
similar, and it was very confusing.

So I changed MC_Error and AddrInfo to be tagged unions, like Vex's IRExpr and
IRStmt types.  The resulting code is a little more verbose but much easier
to understand.  I also split up several error kinds, which also made things
simpler.  The user-visible behaviour is identical except for a couple of
very minor things that I've documented in the NEWS file for the 3.3.0
release.

Ideally I'd get rid of the Addr and Char* fields in the core Error type,
which are not always used, and do them similarly within tools.  But that
would require changing the core/tool interface, so I'm leaving it for the
moment.




git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6402 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/memcheck/mc_include.h b/memcheck/mc_include.h
index 23a6b2c..0c79c44 100644
--- a/memcheck/mc_include.h
+++ b/memcheck/mc_include.h
@@ -56,7 +56,7 @@
    struct _MC_Chunk {
       struct _MC_Chunk* next;
       Addr         data;            // ptr to actual block
-      SizeT        size : (sizeof(UWord)*8)-2; // size requested; 30 or 62 bits
+      SizeT        szB : (sizeof(UWord)*8)-2; // size requested; 30 or 62 bits
       MC_AllocKind allockind : 2;   // which wrapper did the allocation
       ExeContext*  where;           // where it was allocated
    }
@@ -120,28 +120,6 @@
 
 
 /*------------------------------------------------------------*/
-/*--- Errors and suppressions                              ---*/
-/*------------------------------------------------------------*/
-
-/* Extra info for overlap errors */
-typedef
-   struct {
-      Addr src;
-      Addr dst;
-      Int  len;   // -1 if unused
-   }
-   OverlapExtra;
-
-extern void MC_(record_free_error)            ( ThreadId tid, Addr a ); 
-extern void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a );
-extern void MC_(record_freemismatch_error)    ( ThreadId tid, Addr a,
-                                                MC_Chunk* mc );
-extern Bool MC_(record_leak_error)            ( ThreadId tid, 
-                                                void* leak_extra,
-                                                ExeContext* where,
-                                                Bool print_record );
-
-/*------------------------------------------------------------*/
 /*--- Profiling of memory events                           ---*/
 /*------------------------------------------------------------*/
 
@@ -201,6 +179,21 @@
 /*--- Leak checking                                        ---*/
 /*------------------------------------------------------------*/
 
+/* A block is either 
+   -- Proper-ly reached; a pointer to its start has been found
+   -- Interior-ly reached; only an interior pointer to it has been found
+   -- Unreached; so far, no pointers to any part of it have been found. 
+   -- IndirectLeak; leaked, but referred to by another leaked block
+*/
+typedef 
+   enum { 
+      Unreached    =0, 
+      IndirectLeak =1,
+      Interior     =2, 
+      Proper       =3
+  }
+  Reachedness;
+
 /* For VALGRIND_COUNT_LEAKS client request */
 extern SizeT MC_(bytes_leaked);
 extern SizeT MC_(bytes_indirect);
@@ -208,9 +201,6 @@
 extern SizeT MC_(bytes_reachable);
 extern SizeT MC_(bytes_suppressed);
 
-/* For leak checking */
-extern void MC_(pp_LeakError)(void* extra);
-                           
 typedef
    enum {
       LC_Off,
@@ -219,12 +209,44 @@
    }
    LeakCheckMode;
 
+/* A block record, used for generating err msgs. */
+typedef
+   struct _LossRecord {
+      struct _LossRecord* next;
+      /* Where these lost blocks were allocated. */
+      ExeContext*  allocated_at;
+      /* Their reachability. */
+      Reachedness  loss_mode;
+      /* Number of blocks and total # bytes involved. */
+      SizeT        total_bytes;
+      SizeT        indirect_bytes;
+      UInt         num_blocks;
+   }
+   LossRecord;
+
 extern void MC_(do_detect_memory_leaks) (
           ThreadId tid, LeakCheckMode mode,
           Bool (*is_within_valid_secondary) ( Addr ),
           Bool (*is_valid_aligned_word)     ( Addr )
        );
 
+extern void MC_(pp_LeakError)(UInt n_this_record, UInt n_total_records,
+                              LossRecord* l);
+                          
+
+/*------------------------------------------------------------*/
+/*--- Errors and suppressions                              ---*/
+/*------------------------------------------------------------*/
+
+extern void MC_(record_free_error)            ( ThreadId tid, Addr a ); 
+extern void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a );
+extern void MC_(record_freemismatch_error)    ( ThreadId tid, MC_Chunk* mc );
+extern Bool MC_(record_leak_error)            ( ThreadId tid,
+                                                UInt n_this_record,
+                                                UInt n_total_records,
+                                                LossRecord* lossRecord,
+                                                Bool print_record );
+
 /*------------------------------------------------------------*/
 /*--- Command line options + defaults                      ---*/
 /*------------------------------------------------------------*/