Hello group,

After having spent some time digging into the origin of the strict-aliasing warnings when compiling with GCC 3.3 (brought about by Stefan Roehrich's post a couple of days ago), I came up with a couple of things that might be of interest in the development of PHP.

First of all, GCC provides an function qualifier __attribute_malloc__, which tells the compiler that the function in question is a malloc-like function, and will therefore never return values that might be aliased by other pointers in the scope of the function that called it. This is quite a boost for the effectiveness of the optimizations, because - the return type of malloc() being void* - the compiler has to take into account that every pointer in scope might be an alias of the resulting value. __attribute_malloc__ fixes that. (Disabled for non-GCC compilers)

The other thing is, that a lot of warnings are being triggered by invocations of zend_hash_find(). This function stores its result in the location pointed to by a void** argument, and returns an int specifying whether the key was found or not. As the comment in the source states, this was a conscious decision, because hashes can also be used to store null pointers.

After looking through some of the code, I found out that in a lot of cases, the pointers are expected not to be zero, and are being dereferenced in the code that immediately follows it [without checking for validity first].

Wouldn't it be more straight-forward to introduce an analogue for zend_hash_find() (eg. 'void *zend_hash_get()') which returns the stored pointer [or NULL on failure]. It could be used for applications where null pointers aren't allowed, and fix current code, where the implicit assumption is made the SUCCESS means the the pointers is non-null.

Last of all, I would like to know if we care about the warnings. Personally I don't really mind, as GCC's capabilities of accurately identifying violations of strict-aliasing rules are limited anyway.

Ard
Index: Zend/zend_alloc.h
===================================================================
RCS file: /repository/ZendEngine2/zend_alloc.h,v
retrieving revision 1.44
diff -u -u -r1.44 zend_alloc.h
--- Zend/zend_alloc.h   18 Aug 2003 21:17:26 -0000      1.44
+++ Zend/zend_alloc.h   27 Aug 2003 13:17:13 -0000
@@ -68,6 +68,7 @@
 #define PLATFORM_ALIGNMENT (__alignof__ (align_test))
 #else
 #define PLATFORM_ALIGNMENT (sizeof(align_test))
+#define __attribute_malloc__
 #endif
 
 #define MEM_HEADER_PADDING 
(((PLATFORM_ALIGNMENT-sizeof(zend_mem_header))%PLATFORM_ALIGNMENT+PLATFORM_ALIGNMENT)%PLATFORM_ALIGNMENT)
@@ -75,15 +76,15 @@
 
 BEGIN_EXTERN_C()
 
-ZEND_API char *zend_strndup(const char *s, unsigned int length);
+ZEND_API char *zend_strndup(const char *s, unsigned int length) __attribute_malloc__;
 
-ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
-ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset 
ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
+ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) 
__attribute_malloc__;
+ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset 
ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) __attribute_malloc__;
 ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
-ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC 
ZEND_FILE_LINE_ORIG_DC);
-ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC 
ZEND_FILE_LINE_ORIG_DC);
-ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
-ZEND_API char *_estrndup(const char *s, unsigned int length ZEND_FILE_LINE_DC 
ZEND_FILE_LINE_ORIG_DC);
+ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC 
ZEND_FILE_LINE_ORIG_DC) __attribute_malloc__;
+ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC 
ZEND_FILE_LINE_ORIG_DC) __attribute_malloc__;
+ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) 
__attribute_malloc__;
+ZEND_API char *_estrndup(const char *s, unsigned int length ZEND_FILE_LINE_DC 
ZEND_FILE_LINE_ORIG_DC) __attribute_malloc__;
 
 /* Standard wrapper macros */
 #define emalloc(size)                                  _emalloc((size) 
ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to