@@ -91,6 +91,12 @@ __attribute__((__unused__)) static void print_string(const char* str) {
9191// prevents Clang from replacing function calls with builtins
9292#if RENAME_FUNCTIONS
9393
94+ // this does not have __attribute__((malloc)) so we can test aliasing
95+ void * T_malloc (size_t size );
96+
97+ // this does not have __attribute__((malloc)) so we can test aliasing
98+ void * T_calloc (size_t nmemb , size_t size );
99+
94100void T_bzero (void * s , size_t n );
95101
96102void * T_memccpy (void * __restrict dest , const void * __restrict src , int c , size_t n )
@@ -182,6 +188,8 @@ char *T_strtok_r(char *__restrict s, const char *__restrict delim, char **__rest
182188
183189#else
184190
191+ #define T_malloc malloc
192+ #define T_calloc calloc
185193#define T_bzero bzero
186194#define T_memccpy memccpy
187195#define T_memchr memchr
@@ -571,12 +579,6 @@ int memccpy_tests(void) {
571579 return __LINE__ ;
572580 }
573581
574- /* check that no crashes occur with small calloc sizes */
575- buf = (char * )calloc (1 , sizeof (char ));
576- free (buf );
577- buf = (char * )calloc (0 , sizeof (char ));
578- free (buf );
579-
580582 buf = (char * )calloc (file_size + 1 , sizeof (char ));
581583 if (buf == NULL ) {
582584 perror ("calloc failure" );
@@ -662,7 +664,7 @@ int bzero_test(void) {
662664 if (T_strlen (& data [2 ]) != 0 ) {
663665 return __LINE__ ;
664666 }
665- T_bzero ( NULL , 0 );
667+
666668 T_bzero (& data [8 ], 17 );
667669 int cmp = T_memcmp (data , truth , 32 );
668670 if (cmp != 0 ) {
@@ -1520,8 +1522,57 @@ int mem65536_test(void) {
15201522 return 0 ;
15211523}
15221524
1525+ int alloc_test (void ) {
1526+ /* test that malloc works and returns mutable memory */
1527+
1528+ buf = (char * )T_malloc (1 );
1529+ C (buf != NULL );
1530+ * buf = 0xFF ;
1531+ C (T_memcmp (buf , SINK , 1 ) > 0 );
1532+ * buf = 0x00 ;
1533+ C (T_memcmp (buf , SINK , 1 ) == 0 );
1534+ free (buf );
1535+
1536+ /* check that no crashes occur with small calloc sizes */
1537+
1538+ buf = (char * )T_calloc (1 , sizeof (char ));
1539+ C (buf != NULL && * buf == 0x00 );
1540+ free (buf );
1541+
1542+ buf = (char * )T_calloc (2 , sizeof (char ));
1543+ C (buf != NULL && buf [0 ] == 0x00 && buf [1 ] == 0x00 );
1544+ free (buf );
1545+
1546+ /* test allocating zero bytes */
1547+
1548+ /**
1549+ * malloc(0) is implementation defined, but it should be safe to assume
1550+ * that it does not return `buf`
1551+ */
1552+ char * const Pointer_Not_From_Malloc = (char * )& buf ;
1553+
1554+ buf = (char * )T_malloc (0 );
1555+ C (buf != Pointer_Not_From_Malloc );
1556+ free (buf );
1557+
1558+ buf = (char * )T_calloc (0 , sizeof (char ));
1559+ C (buf != Pointer_Not_From_Malloc );
1560+ free (buf );
1561+
1562+ // ensure that we do not free twice
1563+ buf = NULL ;
1564+ return 0 ;
1565+ }
1566+
15231567int run_tests (void ) {
15241568 int ret = 0 ;
1569+ buf = NULL ;
1570+
1571+ /* malloc and calloc */
1572+ ret = alloc_test ();
1573+ free (buf ); buf = NULL ;
1574+ if (ret != 0 ) { return ret ; }
1575+
15251576 /* boot_asprintf */
15261577 ret = boot_sprintf_tests ();
15271578 free (buf ); buf = NULL ;
0 commit comments