Fix compile error in strbuf_local_buf() with CFLAGS=-g

The strbuf_local_buf() function attempted to detect if its argument was
not an array but a pointer, and fail at compile time.  This worked fine
when compiling with standard optimisation (-O2).

However, specifying the gcc -g option disables compiler optimisation, so
the compiler does not optimise away the call to the function with
__attribute__(error("...")), and so the compile fails.

The solution is to perform the check at run time using assert(), like
strbuf_local() already does.
This commit is contained in:
Andrew Bettison 2017-12-11 21:37:40 +10:30
parent 5fa8c1ffcf
commit 71e654a615

View File

@ -300,14 +300,19 @@ typedef const struct strbuf *const_strbuf;
* @author Andrew Bettison <andrew@servalproject.com> * @author Andrew Bettison <andrew@servalproject.com>
*/ */
#if defined(__GNUC__) && defined(HAVE_FUNC_ATTRIBUTE_ALLOC_SIZE) #if defined(__GNUC__) && defined(HAVE_FUNC_ATTRIBUTE_ALLOC_SIZE)
# define strbuf_local_buf(buf) strbuf_local((char*)(buf), (sizeof(buf) == __builtin_object_size(buf, 1)) ? sizeof(buf) : __buffer_arg_is_not_array())
// If the following error occurs at compile time or this function is not # define strbuf_local_buf(buf) strbuf_local((char*)(buf), (__buffer_size_chk(sizeof(buf), __builtin_object_size(buf, 1))))
// resolved at link time, it means that the argument to strbuf_local_buf()
// was not an array whose size is known at compile time. The most common // If the following assertion fails, it means that the argument to
// cause of this is passing a pointer as the argument. The solution is to // strbuf_local_buf() was not an array whose size is known at compile time.
// use strbuf_local(b, len) instead of strbuf_local_buf(b), and supply the // The most common cause of this is passing a pointer as the argument. The
// length of the buffer explicitly. // solution is to use strbuf_local(b, len) instead of strbuf_local_buf(b),
size_t __buffer_arg_is_not_array() __attribute__ ((__ATTRIBUTE_error("argument to strbuf_local_buf() must be an array not a pointer"))); // and supply the length of the buffer explicitly.
__STRBUF_INLINE size_t __buffer_size_chk(size_t size, size_t chk) {
assert(chk == (size_t)-1 || size == chk);
return size;
}
#else #else
# define strbuf_local_buf(buf) strbuf_local((char*)(buf), sizeof(buf)) # define strbuf_local_buf(buf) strbuf_local((char*)(buf), sizeof(buf))
#endif #endif