X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=tests%2Flibpspp%2Fhmap-test.c;h=bbe341388a3ce530b26957afd8e89a3df586d6c1;hb=425d780e0e2cc08c58722145df4d3dd808f01d48;hp=7ad86292fa4a12ae4e20342a8567ff3b53f02b85;hpb=c1e75ee809efd2f4bfd9ebcc1c2b0689c1da0e4c;p=pspp diff --git a/tests/libpspp/hmap-test.c b/tests/libpspp/hmap-test.c index 7ad86292fa..bbe341388a 100644 --- a/tests/libpspp/hmap-test.c +++ b/tests/libpspp/hmap-test.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +21,67 @@ "valgrind --leak-check=yes --show-reachable=yes" should give a clean report. */ +/* GCC 4.3 miscompiles some of the tests below, so we do not run + these tests on GCC 4.3. This is a bug in GCC 4.3 triggered by + the test program, not a bug in the library under test. GCC + 4.2 or earlier and GCC 4.4 or later do not have this bug. + + Here is a minimal test program that demonstrates the same or a + similar bug in GCC 4.3: + + #include + #include + + struct node + { + struct node *next; + unsigned int data1; + int data2; + }; + struct list + { + struct node *head; + int dummy; + }; + + static void * + xmalloc (int n) + { + return malloc (n); + } + + static void + check_list (struct list *list) + { + int i __attribute__((unused)); + struct node *e; + for (e = list->head; e != NULL; e = e->next) + if (e->data1 != e->data2) + abort (); + } + + int + main (void) + { + #define MAX_ELEMS 2 + struct node *elements = xmalloc (MAX_ELEMS * sizeof *elements); + int *values = xmalloc (MAX_ELEMS * sizeof *values); + struct list list; + int i; + + list.head = NULL; + for (i = 0; i < MAX_ELEMS; i++) + { + values[i] = elements[i].data2 = i; + elements[i].data1 = elements[i].data2; + elements[i].next = list.head; + list.head = &elements[i]; + } + check_list (&list); + return 0; + } +*/ + #ifdef HAVE_CONFIG_H #include #endif @@ -76,6 +137,10 @@ xalloc_die (void) exit (EXIT_FAILURE); } +static void *xmalloc (size_t n) MALLOC_LIKE; +static void *xnmalloc (size_t n, size_t m) MALLOC_LIKE; +static void *xmemdup (const void *p, size_t n) MALLOC_LIKE; + /* Allocates and returns N bytes of memory. */ static void * xmalloc (size_t n) @@ -277,6 +342,7 @@ check_hmap (struct hmap *hmap, const int data[], size_t cnt, size_t i, j; int *order; + check (hmap_is_empty (hmap) == (cnt == 0)); check (hmap_count (hmap) == cnt); check (cnt <= hmap_capacity (hmap)); @@ -313,7 +379,6 @@ check_hmap (struct hmap *hmap, const int data[], size_t cnt, for (p = hmap_first (hmap), i = 0; i < cnt; p = hmap_next (hmap, p), i++) { struct element *e = hmap_node_to_element (p); - size_t j; check (hmap_node_hash (&e->node) == hash (e->data)); for (j = 0; j < left; j++) @@ -601,6 +666,10 @@ test_insert_ordered (int max_elems, hash_function *hash) struct hmap hmap; int i; +#if __GNUC__ == 4 && __GNUC_MINOR__ == 3 + return; +#endif /* GCC 4.3 */ + hmap_init (&hmap); elements = xnmalloc (max_elems, sizeof *elements); values = xnmalloc (max_elems, sizeof *values); @@ -673,6 +742,10 @@ test_moved (int max_elems, hash_function *hash) struct hmap hmap; int i, j; +#if __GNUC__ == 4 && __GNUC_MINOR__ == 3 + return; +#endif /* GCC 4.3 */ + hmap_init (&hmap); e[0] = xnmalloc (max_elems, sizeof *e[0]); e[1] = xnmalloc (max_elems, sizeof *e[1]); @@ -808,6 +881,10 @@ test_swap (int max_elems, hash_function *hash) struct hmap *working, *empty; int i; +#if __GNUC__ == 4 && __GNUC_MINOR__ == 3 + return; +#endif /* GCC 4.3 */ + hmap_init (&a); hmap_init (&b); working = &a; @@ -838,6 +915,45 @@ test_swap_random_hash (void) test_swap (128, random_hash); } +/* Inserts elements into an hmap in ascending order, then clears the hash table + using hmap_clear(). */ +static void +test_clear (void) +{ + const int max_elems = 128; + struct element *elements; + int *values; + struct hmap hmap; + int cnt; + +#if __GNUC__ == 4 && __GNUC_MINOR__ == 3 + return; +#endif /* GCC 4.3 */ + + elements = xnmalloc (max_elems, sizeof *elements); + values = xnmalloc (max_elems, sizeof *values); + + for (cnt = 0; cnt <= max_elems; cnt++) + { + int i; + + hmap_init (&hmap); + for (i = 0; i < cnt; i++) + { + values[i] = elements[i].data = i; + hmap_insert (&hmap, &elements[i].node, + random_hash (elements[i].data)); + check_hmap (&hmap, values, i + 1, random_hash); + } + hmap_clear (&hmap); + check_hmap (&hmap, NULL, 0, random_hash); + hmap_destroy (&hmap); + } + + free (elements); + free (values); +} + static void test_destroy_null (void) { @@ -922,10 +1038,19 @@ main (void) run_test (test_swap_random_hash, "test swapping tables"); + run_test (test_clear, "test clearing hash table"); + run_test (test_destroy_null, "test destroying null table"); run_test (test_shrink_empty, "test shrinking an empty table"); putchar ('\n'); +#if __GNUC__ == 4 && __GNUC_MINOR__ == 3 + /* We skipped some of the tests, so return a value that + Automake will interpret as "skipped", instead of one that + means success. */ + return 77; +#else return 0; +#endif }