diff options
| author | jvoisin | 2023-12-06 21:45:57 +0100 |
|---|---|---|
| committer | jvoisin | 2023-12-07 17:29:06 +0100 |
| commit | b5d5cebc2b4218ca2c04c52546849df7625a53a0 (patch) | |
| tree | 096dfaebcf9306a9e955fd44e4aa18d2865f3733 | |
| parent | 9064a508d5f1ed3514d3e5b4734576e80f7048ae (diff) | |
Add qsort
| -rw-r--r-- | include/stdlib.h | 17 | ||||
| -rw-r--r-- | tests/Makefile | 2 | ||||
| -rw-r--r-- | tests/test_qsort_dynamic.c | 26 | ||||
| -rw-r--r-- | tests/test_qsort_static.c | 26 |
4 files changed, 71 insertions, 0 deletions
diff --git a/include/stdlib.h b/include/stdlib.h index 5d89c9c..4a5cfde 100644 --- a/include/stdlib.h +++ b/include/stdlib.h | |||
| @@ -37,6 +37,23 @@ __extension__ | |||
| 37 | extern "C" { | 37 | extern "C" { |
| 38 | #endif | 38 | #endif |
| 39 | 39 | ||
| 40 | #undef qsort | ||
| 41 | #if __has_builtin(__builtin_qsort) | ||
| 42 | __diagnose_as_builtin(__builtin_qsort, 1, 2, 3, 4) | ||
| 43 | #endif | ||
| 44 | __access(read_write, 1) | ||
| 45 | _FORTIFY_FN(qsort) void qsort(void * _FORTIFY_POS0 base, size_t nmemb, size_t size, | ||
| 46 | int (*compar)(const void *, const void *)) | ||
| 47 | { | ||
| 48 | size_t __b = __bos(base, 0); | ||
| 49 | |||
| 50 | if (__bmo(nmemb, size)) | ||
| 51 | __builtin_trap(); | ||
| 52 | if (nmemb * size> __b) | ||
| 53 | __builtin_trap(); | ||
| 54 | |||
| 55 | return __orig_qsort(base, nmemb, size, compar); | ||
| 56 | } | ||
| 40 | 57 | ||
| 41 | /* FIXME clang */ | 58 | /* FIXME clang */ |
| 42 | #if !defined(__clang__) | 59 | #if !defined(__clang__) |
diff --git a/tests/Makefile b/tests/Makefile index f91bff0..352e6f8 100644 --- a/tests/Makefile +++ b/tests/Makefile | |||
| @@ -71,6 +71,8 @@ RUNTIME_TARGETS= \ | |||
| 71 | test_printf \ | 71 | test_printf \ |
| 72 | test_pwrite_dynamic \ | 72 | test_pwrite_dynamic \ |
| 73 | test_pwrite_static \ | 73 | test_pwrite_static \ |
| 74 | test_qsort_dynamic \ | ||
| 75 | test_qsort_static \ | ||
| 74 | test_read_dynamic \ | 76 | test_read_dynamic \ |
| 75 | test_read_static \ | 77 | test_read_static \ |
| 76 | test_readlink_dynamic \ | 78 | test_readlink_dynamic \ |
diff --git a/tests/test_qsort_dynamic.c b/tests/test_qsort_dynamic.c new file mode 100644 index 0000000..4ce48aa --- /dev/null +++ b/tests/test_qsort_dynamic.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <stdlib.h> | ||
| 4 | |||
| 5 | static int cmp(const void *p1, const void *p2); | ||
| 6 | |||
| 7 | int main(int argc, char** argv) { | ||
| 8 | char buffer[] = {'a', 'b', 'c', 'd', 'e', '\0'}; | ||
| 9 | |||
| 10 | qsort(buffer, 6, sizeof(char), cmp); | ||
| 11 | |||
| 12 | puts(buffer); | ||
| 13 | |||
| 14 | CHK_FAIL_START | ||
| 15 | qsort(buffer, argc, sizeof(char), cmp); | ||
| 16 | CHK_FAIL_END | ||
| 17 | |||
| 18 | puts(buffer); | ||
| 19 | |||
| 20 | return ret; | ||
| 21 | } | ||
| 22 | |||
| 23 | static int cmp(const void *p1, const void *p2) | ||
| 24 | { | ||
| 25 | return (* (char*) p1 > * (char*) p2); | ||
| 26 | } | ||
diff --git a/tests/test_qsort_static.c b/tests/test_qsort_static.c new file mode 100644 index 0000000..6046ac8 --- /dev/null +++ b/tests/test_qsort_static.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | #include "common.h" | ||
| 2 | |||
| 3 | #include <stdlib.h> | ||
| 4 | |||
| 5 | static int cmp(const void *p1, const void *p2); | ||
| 6 | |||
| 7 | int main(int argc, char** argv) { | ||
| 8 | char buffer[] = {'a', 'b', 'c', 'd', 'e', '\0'}; | ||
| 9 | |||
| 10 | qsort(buffer, 6, sizeof(char), cmp); | ||
| 11 | |||
| 12 | puts(buffer); | ||
| 13 | |||
| 14 | CHK_FAIL_START | ||
| 15 | qsort(buffer, 12, sizeof(char), cmp); | ||
| 16 | CHK_FAIL_END | ||
| 17 | |||
| 18 | puts(buffer); | ||
| 19 | |||
| 20 | return ret; | ||
| 21 | } | ||
| 22 | |||
| 23 | static int cmp(const void *p1, const void *p2) | ||
| 24 | { | ||
| 25 | return (* (char*) p1 > * (char*) p2); | ||
| 26 | } | ||
