---
 docs/examples/10-at-a-time.c        |    2 
 docs/examples/anyauthput.c          |    4 
 docs/examples/debug.c               |    2 
 docs/examples/ftpget.c              |    2 
 docs/examples/multi-debugcallback.c |    2 
 include/curl/Makefile.am            |    3 
 include/curl/curl.h                 |    5 
 include/curl/typecheck-gcc.h        |  463 ++++++++++++++++++++++++++++++++++++
 lib/easy.c                          |    2 
 tests/libtest/lib506.c              |    8 
 10 files changed, 481 insertions(+), 12 deletions(-)

--- include/curl/Makefile.am.orig
+++ include/curl/Makefile.am
@@ -1,5 +1,6 @@
 pkginclude_HEADERS = \
-	curl.h curlver.h easy.h mprintf.h stdcheaders.h types.h multi.h
+	curl.h curlver.h easy.h mprintf.h stdcheaders.h types.h multi.h \
+	typecheck-gcc.h
 pkgincludedir= $(includedir)/curl
 
 CLEANFILES = *dist
--- include/curl/curl.h.orig
+++ include/curl/curl.h
@@ -1791,4 +1791,9 @@ CURL_EXTERN CURLcode curl_easy_pause(CUR
 #include "easy.h" /* nothing in curl is fun without the easy stuff */
 #include "multi.h"
 
+/* the typechecker doesn't work in C++ (yet) */
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__cplusplus)
+#include "typecheck-gcc.h"
+#endif /* gcc >= 4.3 && !__cplusplus */
+
 #endif /* __CURL_CURL_H */
--- /dev/null
+++ include/curl/typecheck-gcc.h
@@ -0,0 +1,463 @@
+#ifndef __CURL_TYPECHECK_GCC_H
+#define __CURL_TYPECHECK_GCC_H
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ * $Id$
+ ***************************************************************************/
+
+/* wraps curl_easy_setopt() with typechecking */
+#define curl_easy_setopt(handle, option, value)                               \
+({                                                                            \
+  __typeof__ (option) _curl_opt = option;                                     \
+  if (__builtin_constant_p(_curl_opt)) {                                      \
+    if (_curl_long_option(_curl_opt) && !_curl_is_long(value))                \
+      _curl_easy_setopt_err_long();                                           \
+    if (_curl_off_t_option(_curl_opt) && !_curl_is_off_t(value))              \
+      _curl_easy_setopt_err_curl_off_t();                                     \
+    if (_curl_string_option(_curl_opt) && !_curl_is_string(value))            \
+      _curl_easy_setopt_err_string();                                         \
+    if (_curl_write_cb_option(_curl_opt) && !_curl_is_write_cb(value))        \
+      _curl_easy_setopt_err_write_callback();                                 \
+    if ((_curl_opt) == CURLOPT_READFUNCTION && !_curl_is_read_cb(value))      \
+      _curl_easy_setopt_err_read_cb();                                        \
+    if ((_curl_opt) == CURLOPT_IOCTLFUNCTION && !_curl_is_ioctl_cb(value))    \
+      _curl_easy_setopt_err_ioctl_cb();                                       \
+    if ((_curl_opt) == CURLOPT_SOCKOPTFUNCTION && !_curl_is_sockopt_cb(value))\
+      _curl_easy_setopt_err_sockopt_cb();                                     \
+    if ((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION &&                          \
+            !_curl_is_opensocket_cb(value))                                   \
+      _curl_easy_setopt_err_opensocket_cb();                                  \
+    if ((_curl_opt) == CURLOPT_PROGRESSFUNCTION &&                            \
+            !_curl_is_progress_cb(value))                                     \
+      _curl_easy_setopt_err_progress_cb();                                    \
+    if ((_curl_opt) == CURLOPT_DEBUGFUNCTION && !_curl_is_debug_cb(value))    \
+      _curl_easy_setopt_err_debug_cb();                                       \
+    if ((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION &&                            \
+            !_curl_is_ssl_ctx_cb(value))                                      \
+      _curl_easy_setopt_err_ssl_ctx_cb();                                     \
+    if (_curl_conv_cb_option(_curl_opt) && !_curl_is_conv_cb(value))          \
+      _curl_easy_setopt_err_conv_cb();                                        \
+    if ((_curl_opt) == CURLOPT_SEEKFUNCTION && !_curl_is_seek_cb(value))      \
+      _curl_easy_setopt_err_seek_cb();                                        \
+    if (_curl_cb_data_option(_curl_opt) && !_curl_is_cb_data(value))          \
+      _curl_easy_setopt_err_cb_data();                                        \
+    if ((_curl_opt) == CURLOPT_ERRORBUFFER && !_curl_is_error_buffer(value))  \
+      _curl_easy_setopt_err_error_buffer();                                   \
+    if ((_curl_opt) == CURLOPT_STDERR && !_curl_is_FILE(value))               \
+      _curl_easy_setopt_err_FILE();                                           \
+    if (_curl_postfields_option(_curl_opt) && !_curl_is_postfields(value))    \
+      _curl_easy_setopt_err_postfields();                                     \
+    if ((_curl_opt) == CURLOPT_HTTPPOST &&                                    \
+            !_curl_is_ptr((value), struct curl_httppost))                     \
+      _curl_easy_setopt_err_curl_httpost();                                   \
+    if (_curl_slist_option(_curl_opt) &&                                      \
+            !_curl_is_ptr((value), struct curl_slist))                        \
+      _curl_easy_setopt_err_curl_slist();                                     \
+    if ((_curl_opt) == CURLOPT_SHARE && !_curl_is_ptr((value), CURLSH))       \
+      _curl_easy_setopt_err_CURLSH();                                         \
+  }                                                                           \
+  curl_easy_setopt(handle, _curl_opt, value);                                 \
+})
+
+/* XXX: hack to make gcc emit the warnings
+ * a proper way would be to add this libcurl.so */
+static int _curl_err_hack(void) { return 1; }
+
+/* the actual warnings, triggered by calling the functions */
+static int _curl_easy_setopt_err_long(void) __attribute__((warning
+  ("curl_easy_setopt expects a long argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_curl_off_t() __attribute__((warning
+  ("curl_easy_setopt expects a curl_off_t argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_string() __attribute__((warning
+  ("curl_easy_setopt expects a string (char* or char[]) argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_write_callback() __attribute__((warning
+  ("curl_easy_setopt expects a curl_write_callback argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_read_cb() __attribute__((warning
+  ("curl_easy_setopt expects a curl_read_callback argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_ioctl_cb() __attribute__((warning
+  ("curl_easy_setopt expects a curl_ioctl_callback argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_sockopt_cb() __attribute__((warning
+  ("curl_easy_setopt expects a curl_sockopt_callback argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_opensocket_cb() __attribute__((warning
+  ("curl_easy_setopt expects a curl_opensocket_callback argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_progress_cb() __attribute__((warning
+  ("curl_easy_setopt expects a curl_progress_callback argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_debug_cb() __attribute__((warning
+  ("curl_easy_setopt expects a curl_debug_callback argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_ssl_ctx_cb() __attribute__((warning
+  ("curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_conv_cb() __attribute__((warning
+  ("curl_easy_setopt expects a curl_conv_callback argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_seek_cb() __attribute__((warning
+  ("curl_easy_setopt expects a curl_seek_callback argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_cb_data() __attribute__((warning
+  ("curl_easy_setopt expects a private data pointer as argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_error_buffer() __attribute__((warning
+  ("curl_easy_setopt expects a char buffer of CURL_ERROR_SIZE as argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_FILE() __attribute__((warning
+  ("curl_easy_setopt expects a FILE* argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_postfields() __attribute__((warning
+  ("curl_easy_setopt expects a void* or char* argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_curl_httpost() __attribute__((warning
+  ("curl_easy_setopt expects a struct curl_httppost* argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_curl_slist() __attribute__((warning
+  ("curl_easy_setopt expects a struct curl_slist* argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+static int _curl_easy_setopt_err_CURLSH() __attribute__((warning
+  ("curl_easy_setopt expects a CURLSH* argument for this option")))
+  __attribute__((alias("_curl_err_hack")));
+
+/* groups of options that take the same type of argument */
+
+/* evaluates to true if option takes a long argument
+ * XXX: tolerate int? */
+#define _curl_long_option(option)                                             \
+  (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
+
+#define _curl_off_t_option(option)                                            \
+  ((option) > CURLOPTTYPE_OFF_T)
+
+/* evaluates to true if option takes a char* argument */
+#define _curl_string_option(option)                                           \
+  ((option) == CURLOPT_URL ||                                                 \
+   (option) == CURLOPT_PROXY ||                                               \
+   (option) == CURLOPT_INTERFACE ||                                           \
+   (option) == CURLOPT_NETRC_FILE ||                                          \
+   (option) == CURLOPT_USERPWD ||                                             \
+   (option) == CURLOPT_PROXYUSERPWD ||                                        \
+   (option) == CURLOPT_ENCODING ||                                            \
+   (option) == CURLOPT_REFERER ||                                             \
+   (option) == CURLOPT_USERAGENT ||                                           \
+   (option) == CURLOPT_COOKIE ||                                              \
+   (option) == CURLOPT_COOKIEFILE ||                                          \
+   (option) == CURLOPT_COOKIEJAR ||                                           \
+   (option) == CURLOPT_COOKIELIST ||                                          \
+   (option) == CURLOPT_FTPPORT ||                                             \
+   (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER ||                             \
+   (option) == CURLOPT_FTP_ACCOUNT ||                                         \
+   (option) == CURLOPT_RANGE ||                                               \
+   (option) == CURLOPT_CUSTOMREQUEST ||                                       \
+   (option) == CURLOPT_SSLCERT ||                                             \
+   (option) == CURLOPT_SSLCERTTYPE ||                                         \
+   (option) == CURLOPT_SSLKEY ||                                              \
+   (option) == CURLOPT_SSLKEYTYPE ||                                          \
+   (option) == CURLOPT_KEYPASSWD ||                                           \
+   (option) == CURLOPT_SSLENGINE ||                                           \
+   (option) == CURLOPT_CAINFO ||                                              \
+   (option) == CURLOPT_CAPATH ||                                              \
+   (option) == CURLOPT_RANDOM_FILE ||                                         \
+   (option) == CURLOPT_EGDSOCKET ||                                           \
+   (option) == CURLOPT_SSL_CIPHER_LIST ||                                     \
+   (option) == CURLOPT_KRBLEVEL ||                                            \
+   (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                             \
+   (option) == CURLOPT_SSH_PUBLIC_KEYFILE ||                                  \
+   (option) == CURLOPT_SSH_PRIVATE_KEYFILE ||                                 \
+   0)
+
+/* evaluates to true if option takes a curl_write_callback argument */
+#define _curl_write_cb_option(option)                                         \
+  ((option) == CURLOPT_HEADERFUNCTION ||                                      \
+   (option) == CURLOPT_WRITEFUNCTION)
+
+/* evaluates to true if option takes a curl_conv_callback argument */
+#define _curl_conv_cb_option(option)                                          \
+  ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION ||                            \
+   (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION ||                          \
+   (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION)
+
+/* evaluates to true if option takes a data argument to pass to a callback */
+#define _curl_cb_data_option(option)                                          \
+  ((option) == CURLOPT_WRITEDATA ||                                           \
+   (option) == CURLOPT_READDATA ||                                            \
+   (option) == CURLOPT_IOCTLDATA ||                                           \
+   (option) == CURLOPT_SOCKOPTDATA ||                                         \
+   (option) == CURLOPT_OPENSOCKETDATA ||                                      \
+   (option) == CURLOPT_PROGRESSDATA ||                                        \
+   (option) == CURLOPT_WRITEHEADER ||                                         \
+   (option) == CURLOPT_DEBUGDATA ||                                           \
+   (option) == CURLOPT_SSL_CTX_DATA ||                                        \
+   (option) == CURLOPT_SEEKDATA ||                                            \
+   (option) == CURLOPT_PRIVATE ||                                             \
+   0)
+
+/* evaluates to true if option takes a POST data argument (void* or char*) */
+#define _curl_postfields_option(option)                                       \
+  ((option) == CURLOPT_POSTFIELDS ||                                          \
+   (option) == CURLOPT_COPYPOSTFIELDS ||                                      \
+   0)
+
+/* evaluates to true if option takes a struct curl_slist * argument */
+#define _curl_slist_option(option)                                            \
+  ((option) == CURLOPT_HTTPHEADER ||                                          \
+   (option) == CURLOPT_HTTP200ALIASES ||                                      \
+   (option) == CURLOPT_QUOTE ||                                               \
+   (option) == CURLOPT_POSTQUOTE ||                                           \
+   (option) == CURLOPT_PREQUOTE ||                                            \
+   (option) == CURLOPT_TELNETOPTIONS ||                                       \
+   0)
+
+/* typecheck helpers */
+
+/* XXX: should evaluate to true iff expr is a pointer */
+#define _curl_is_any_ptr(expr)                                                \
+  (sizeof(expr) == sizeof(void*))
+
+/* evaluates to true if expr is NULL */
+/* XXX: must not evaluate expr, so this check is not accurate */
+#define _curl_is_NULL(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL)))
+
+/* evaluates to true if expr is type*, const type* or NULL */
+#define _curl_is_ptr(expr, type)                                              \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), type *) ||                  \
+   __builtin_types_compatible_p(__typeof__(expr), const type *))
+
+/* evaluates to true if expr is one of type[], type*, NULL or const type* */
+#define _curl_is_arr(expr, type)                                              \
+  (_curl_is_ptr((expr), type) ||                                              \
+   __builtin_types_compatible_p(__typeof__(expr), type []))
+
+/* evaluates to true if expr is a string */
+#define _curl_is_string(expr)                                                 \
+  (_curl_is_arr((expr), char) ||                                              \
+   _curl_is_arr((expr), signed char) ||                                       \
+   _curl_is_arr((expr), unsigned char))
+
+/* evaluates to true if expr is a long (no matter the signedness) */
+#define _curl_is_long(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), long) ||                    \
+   __builtin_types_compatible_p(__typeof__(expr), signed long) ||             \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned long))
+
+/* evaluates to true if expr is of type curl_off_t */
+#define _curl_is_off_t(expr)                                                  \
+  (__builtin_types_compatible_p(__typeof__(expr), curl_off_t))
+
+/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */
+/* XXX: also check size of an char[] array? */
+#define _curl_is_error_buffer(expr)                                           \
+  (__builtin_types_compatible_p(__typeof__(expr), char *) ||                  \
+   __builtin_types_compatible_p(__typeof__(expr), char[]))
+
+/* evaluates to true if expr is of type (const) void* or (const) FILE* */
+#if 0
+#define _curl_is_cb_data(expr)                                                \
+  (_curl_is_ptr((expr), void) ||                                              \
+   _curl_is_ptr((expr), FILE))
+#else /* be less strict */
+#define _curl_is_cb_data(expr)                                                \
+  _curl_is_any_ptr(expr)
+#endif
+
+/* evaluates to true if expr is of type FILE* */
+#define _curl_is_FILE(expr)                                                   \
+  (__builtin_types_compatible_p(__typeof__(expr), FILE *))
+
+/* evaluates to true if expr can be passed as POST data (void* or char*) */
+#define _curl_is_postfields(expr)                                             \
+  (_curl_is_ptr((expr), void) ||                                              \
+   _curl_is_arr((expr), char))
+
+/* FIXME: the whole callback checking is messy... */
+/* helper: __builtin_types_compatible_p distinguishes between functions and
+ * function pointers, hide it */
+#define _curl_callback_compatible(func, type)                                 \
+  (__builtin_types_compatible_p(__typeof__(func), type) ||                    \
+   __builtin_types_compatible_p(__typeof__(func), type*))
+
+/* evaluates to true if expr is of type curl_read_callback or "similar" */
+#define _curl_is_read_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) ||       \
+   __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) ||      \
+   _curl_callback_compatible((expr), _curl_read_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback2) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback3) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback4) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback5) ||                 \
+   _curl_callback_compatible((expr), _curl_read_callback6))
+typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*);
+typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*);
+typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*);
+typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*);
+typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*);
+typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
+
+/* evaluates to true if expr is of type curl_write_callback or "similar" */
+#define _curl_is_write_cb(expr)                                               \
+  (_curl_is_read_cb(expr) ||                                            \
+   __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) ||      \
+   __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) ||     \
+   _curl_callback_compatible((expr), _curl_write_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback4) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback5) ||                \
+   _curl_callback_compatible((expr), _curl_write_callback6))
+typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback2)(const char *, size_t, size_t, const void*);
+typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*);
+typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*);
+typedef size_t (_curl_write_callback5)(const void *, size_t, size_t, const void*);
+typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
+
+/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
+#define _curl_is_ioctl_cb(expr)                                         \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) ||     \
+   _curl_callback_compatible((expr), _curl_ioctl_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_ioctl_callback4))
+typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*);
+typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*);
+typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*);
+typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*);
+
+/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
+#define _curl_is_sockopt_cb(expr)                                       \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) ||   \
+   _curl_callback_compatible((expr), _curl_sockopt_callback1) ||              \
+   _curl_callback_compatible((expr), _curl_sockopt_callback2))
+typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype);
+typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t, curlsocktype);
+
+/* evaluates to true if expr is of type curl_opensocket_callback or "similar" */
+#define _curl_is_opensocket_cb(expr)                                    \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\
+   _curl_callback_compatible((expr), _curl_opensocket_callback1) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback2) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback3) ||           \
+   _curl_callback_compatible((expr), _curl_opensocket_callback4))
+typedef curl_socket_t (_curl_opensocket_callback1)
+  (void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback2)
+  (void *, curlsocktype, const struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback3)
+  (const void *, curlsocktype, struct curl_sockaddr *);
+typedef curl_socket_t (_curl_opensocket_callback4)
+  (const void *, curlsocktype, const struct curl_sockaddr *);
+
+/* evaluates to true if expr is of type curl_progress_callback or "similar" */
+#define _curl_is_progress_cb(expr)                                      \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) ||  \
+   _curl_callback_compatible((expr), _curl_progress_callback1) ||             \
+   _curl_callback_compatible((expr), _curl_progress_callback2))
+typedef int (_curl_progress_callback1)(void *,
+    double, double, double, double);
+typedef int (_curl_progress_callback2)(const void *,
+    double, double, double, double);
+
+/* evaluates to true if expr is of type curl_debug_callback or "similar" */
+#define _curl_is_debug_cb(expr)                                         \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) ||     \
+   _curl_callback_compatible((expr), _curl_debug_callback1) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback2) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback3) ||                \
+   _curl_callback_compatible((expr), _curl_debug_callback4))
+typedef int (_curl_debug_callback1) (CURL *,
+    curl_infotype, char *, size_t, void *);
+typedef int (_curl_debug_callback2) (CURL *,
+    curl_infotype, char *, size_t, const void *);
+typedef int (_curl_debug_callback3) (CURL *,
+    curl_infotype, const char *, size_t, void *);
+typedef int (_curl_debug_callback4) (CURL *,
+    curl_infotype, const char *, size_t, const void *);
+
+/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */
+/* this is getting even messier... */
+#define _curl_is_ssl_ctx_cb(expr)                                       \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) ||   \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) ||              \
+   _curl_callback_compatible((expr), _curl_ssl_ctx_callback8))
+typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *);
+typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *);
+typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *);
+typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *);
+#ifdef HEADER_SSL_H
+/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX
+ * this will of course break if we're included before OpenSSL headers...
+ */
+typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *);
+typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *);
+typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *);
+typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, const void *);
+#else
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7;
+typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8;
+#endif
+
+/* evaluates to true if expr is of type curl_conv_callback or "similar" */
+#define _curl_is_conv_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) ||      \
+   _curl_callback_compatible((expr), _curl_conv_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback2) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback3) ||                 \
+   _curl_callback_compatible((expr), _curl_conv_callback4))
+typedef CURLcode (*_curl_conv_callback1)(char *, size_t length);
+typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length);
+typedef CURLcode (*_curl_conv_callback3)(void *, size_t length);
+typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
+
+/* evaluates to true if expr is of type curl_seek_callback or "similar" */
+#define _curl_is_seek_cb(expr)                                          \
+  (_curl_is_NULL(expr) ||                                                     \
+   __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) ||      \
+   _curl_callback_compatible((expr), _curl_seek_callback1) ||                 \
+   _curl_callback_compatible((expr), _curl_seek_callback2))
+typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
+typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
+
+
+#endif /* __CURL_TYPECHECK_GCC_H */
--- lib/easy.c.orig
+++ lib/easy.c
@@ -347,7 +347,7 @@ CURL *curl_easy_init(void)
  * curl_easy_setopt() is the external interface for setting options on an
  * easy handle.
  */
-
+#undef curl_easy_setopt
 CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
 {
   va_list arg;
--- tests/libtest/lib506.c.orig
+++ tests/libtest/lib506.c
@@ -107,10 +107,10 @@ static void *fire(void *ptr)
 
   headers = sethost(NULL);
   curl_easy_setopt(curl, CURLOPT_VERBOSE,    1);
-  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, (void*)headers);
-  curl_easy_setopt(curl, CURLOPT_URL,        (void*)tdata->url);
+  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+  curl_easy_setopt(curl, CURLOPT_URL,        tdata->url);
   printf( "CURLOPT_SHARE\n" );
-  curl_easy_setopt(curl, CURLOPT_SHARE, (void*)tdata->share);
+  curl_easy_setopt(curl, CURLOPT_SHARE, tdata->share);
 
   printf( "PERFORM\n" );
   code = curl_easy_perform(curl);
@@ -222,7 +222,7 @@ int test(char *URL)
 
   url = suburl( URL, i );
   headers = sethost( NULL );
-  curl_easy_setopt( curl, CURLOPT_HTTPHEADER, (void*)headers );
+  curl_easy_setopt( curl, CURLOPT_HTTPHEADER, headers );
   curl_easy_setopt( curl, CURLOPT_URL,        url );
   printf( "CURLOPT_SHARE\n" );
   curl_easy_setopt( curl, CURLOPT_SHARE,      share );
--- docs/examples/10-at-a-time.c.orig
+++ docs/examples/10-at-a-time.c
@@ -77,7 +77,7 @@ static const char *urls[] = {
 #define MAX 10 /* number of simultaneous transfers */
 #define CNT sizeof(urls)/sizeof(char*) /* total number of transfers to do */
 
-static int cb(char *d, size_t n, size_t l, void *p)
+static size_t cb(char *d, size_t n, size_t l, void *p)
 {
   /* take care of the data here, ignored in this example */
   (void)d;
--- docs/examples/anyauthput.c.orig
+++ docs/examples/anyauthput.c
@@ -100,13 +100,13 @@ int main(int argc, char **argv)
     curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
 
     /* which file to upload */
-    curl_easy_setopt(curl, CURLOPT_READDATA, hd);
+    curl_easy_setopt(curl, CURLOPT_READDATA, (void*)hd);
 
     /* set the ioctl function */
     curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
 
     /* pass the file descriptor to the ioctl callback as well */
-    curl_easy_setopt(curl, CURLOPT_IOCTLDATA, hd);
+    curl_easy_setopt(curl, CURLOPT_IOCTLDATA, (void*)hd);
 
     /* enable "uploading" (which means PUT when doing HTTP) */
     curl_easy_setopt(curl, CURLOPT_UPLOAD, TRUE) ;
--- docs/examples/debug.c.orig
+++ docs/examples/debug.c
@@ -65,7 +65,7 @@ void dump(const char *text,
 
 static
 int my_trace(CURL *handle, curl_infotype type,
-             unsigned char *data, size_t size,
+             char *data, size_t size,
              void *userp)
 {
   struct data *config = (struct data *)userp;
--- docs/examples/ftpget.c.orig
+++ docs/examples/ftpget.c
@@ -26,7 +26,7 @@ struct FtpFile {
   FILE *stream;
 };
 
-static int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
+static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
 {
   struct FtpFile *out=(struct FtpFile *)stream;
   if(out && !out->stream) {
--- docs/examples/multi-debugcallback.c.orig
+++ docs/examples/multi-debugcallback.c
@@ -74,7 +74,7 @@ void dump(const char *text,
 
 static
 int my_trace(CURL *handle, curl_infotype type,
-             unsigned char *data, size_t size,
+             char *data, size_t size,
              void *userp)
 {
   const char *text;


