]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
typecheck-gcc.h: fix the typechecks
authorDaniel Stenberg <daniel@haxx.se>
Tue, 22 Apr 2025 20:20:27 +0000 (22:20 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 23 Apr 2025 21:48:18 +0000 (23:48 +0200)
Refreshed, cleaned up, improved and now checks *all* options.

This must have stopped working at some point. gcc-14 least shows these
warnings with this change, not without.

Add test 745 to verify that all options listed in curl.h is also checked
by the typechecker.

This improved checker found almost 30 mistakes in the curl git
repository.

Closes #17143

include/curl/typecheck-gcc.h
tests/Makefile.am
tests/data/Makefile.am
tests/data/test745 [new file with mode: 0644]
tests/test745.pl [new file with mode: 0755]

index e532e6997db44103ba6ef294e8b2e8172f57138a..0dcbdd1f328a7245faa7e4613a9e877d1d07edc9 100644 (file)
  * To add an option that uses the same type as an existing option, you will
  * just need to extend the appropriate _curl_*_option macro
  */
+
 #define curl_easy_setopt(handle, option, value)                         \
   __extension__({                                                       \
-      CURLoption _curl_opt = (option);                                  \
-      if(__builtin_constant_p(_curl_opt)) {                             \
+      if(__builtin_constant_p(option)) {                                \
         CURL_IGNORE_DEPRECATION(                                        \
-          if(curlcheck_long_option(_curl_opt))                          \
+          if(curlcheck_long_option(option))                             \
             if(!curlcheck_long(value))                                  \
               _curl_easy_setopt_err_long();                             \
-          if(curlcheck_off_t_option(_curl_opt))                         \
+          if(curlcheck_off_t_option(option))                            \
             if(!curlcheck_off_t(value))                                 \
               _curl_easy_setopt_err_curl_off_t();                       \
-          if(curlcheck_string_option(_curl_opt))                        \
+          if(curlcheck_string_option(option))                           \
             if(!curlcheck_string(value))                                \
               _curl_easy_setopt_err_string();                           \
-          if(curlcheck_write_cb_option(_curl_opt))                      \
+          if((option) == CURLOPT_PRIVATE) { }                           \
+          if(curlcheck_write_cb_option(option))                         \
             if(!curlcheck_write_cb(value))                              \
               _curl_easy_setopt_err_write_callback();                   \
-          if((_curl_opt) == CURLOPT_RESOLVER_START_FUNCTION)            \
+          if(curlcheck_curl_option(option))                             \
+            if(!curlcheck_curl(value))                                  \
+              _curl_easy_setopt_err_curl();                             \
+          if((option) == CURLOPT_RESOLVER_START_FUNCTION)               \
             if(!curlcheck_resolver_start_callback(value))               \
               _curl_easy_setopt_err_resolver_start_callback();          \
-          if((_curl_opt) == CURLOPT_READFUNCTION)                       \
+          if((option) == CURLOPT_READFUNCTION)                          \
             if(!curlcheck_read_cb(value))                               \
               _curl_easy_setopt_err_read_cb();                          \
-          if((_curl_opt) == CURLOPT_IOCTLFUNCTION)                      \
+          if((option) == CURLOPT_IOCTLFUNCTION)                         \
             if(!curlcheck_ioctl_cb(value))                              \
               _curl_easy_setopt_err_ioctl_cb();                         \
-          if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION)                    \
+          if((option) == CURLOPT_SOCKOPTFUNCTION)                       \
             if(!curlcheck_sockopt_cb(value))                            \
               _curl_easy_setopt_err_sockopt_cb();                       \
-          if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION)                 \
+          if((option) == CURLOPT_OPENSOCKETFUNCTION)                    \
             if(!curlcheck_opensocket_cb(value))                         \
               _curl_easy_setopt_err_opensocket_cb();                    \
-          if((_curl_opt) == CURLOPT_PROGRESSFUNCTION)                   \
+          if((option) == CURLOPT_PROGRESSFUNCTION)                      \
             if(!curlcheck_progress_cb(value))                           \
               _curl_easy_setopt_err_progress_cb();                      \
-          if((_curl_opt) == CURLOPT_DEBUGFUNCTION)                      \
+          if((option) == CURLOPT_XFERINFOFUNCTION)                      \
+            if(!curlcheck_xferinfo_cb(value))                           \
+              _curl_easy_setopt_err_xferinfo_cb();                      \
+          if((option) == CURLOPT_DEBUGFUNCTION)                         \
             if(!curlcheck_debug_cb(value))                              \
               _curl_easy_setopt_err_debug_cb();                         \
-          if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION)                   \
+          if((option) == CURLOPT_SSL_CTX_FUNCTION)                      \
             if(!curlcheck_ssl_ctx_cb(value))                            \
               _curl_easy_setopt_err_ssl_ctx_cb();                       \
-          if(curlcheck_conv_cb_option(_curl_opt))                       \
+          if(curlcheck_conv_cb_option(option))                          \
             if(!curlcheck_conv_cb(value))                               \
               _curl_easy_setopt_err_conv_cb();                          \
-          if((_curl_opt) == CURLOPT_SEEKFUNCTION)                       \
+          if((option) == CURLOPT_SEEKFUNCTION)                          \
             if(!curlcheck_seek_cb(value))                               \
               _curl_easy_setopt_err_seek_cb();                          \
-          if(curlcheck_cb_data_option(_curl_opt))                       \
+          if((option) == CURLOPT_CHUNK_BGN_FUNCTION)                    \
+            if(!curlcheck_chunk_bgn_cb(value))                          \
+              _curl_easy_setopt_err_chunk_bgn_cb();                     \
+          if((option) == CURLOPT_CHUNK_END_FUNCTION)                    \
+            if(!curlcheck_chunk_end_cb(value))                          \
+              _curl_easy_setopt_err_chunk_end_cb();                     \
+          if((option) == CURLOPT_CLOSESOCKETFUNCTION)                   \
+            if(!curlcheck_close_socket_cb(value))                       \
+              _curl_easy_setopt_err_close_socket_cb();                  \
+          if((option) == CURLOPT_FNMATCH_FUNCTION)                      \
+            if(!curlcheck_fnmatch_cb(value))                            \
+              _curl_easy_setopt_err_fnmatch_cb();                       \
+          if((option) == CURLOPT_HSTSREADFUNCTION)                      \
+            if(!curlcheck_hstsread_cb(value))                           \
+              _curl_easy_setopt_err_hstsread_cb();                      \
+          if((option) == CURLOPT_HSTSWRITEFUNCTION)                     \
+            if(!curlcheck_hstswrite_cb(value))                          \
+              _curl_easy_setopt_err_hstswrite_cb();                     \
+          if((option) == CURLOPT_SSH_HOSTKEYFUNCTION)                   \
+            if(!curlcheck_ssh_hostkey_cb(value))                        \
+              _curl_easy_setopt_err_ssh_hostkey_cb();                   \
+          if((option) == CURLOPT_SSH_KEYFUNCTION)                       \
+            if(!curlcheck_ssh_key_cb(value))                            \
+              _curl_easy_setopt_err_ssh_key_cb();                       \
+          if((option) == CURLOPT_INTERLEAVEFUNCTION)                    \
+            if(!curlcheck_interleave_cb(value))                         \
+              _curl_easy_setopt_err_interleave_cb();                    \
+          if((option) == CURLOPT_PREREQFUNCTION)                        \
+            if(!curlcheck_prereq_cb(value))                             \
+              _curl_easy_setopt_err_prereq_cb();                        \
+          if((option) == CURLOPT_TRAILERFUNCTION)                       \
+            if(!curlcheck_trailer_cb(value))                            \
+              _curl_easy_setopt_err_trailer_cb();                       \
+          if(curlcheck_cb_data_option(option))                          \
             if(!curlcheck_cb_data(value))                               \
               _curl_easy_setopt_err_cb_data();                          \
-          if((_curl_opt) == CURLOPT_ERRORBUFFER)                        \
+          if((option) == CURLOPT_ERRORBUFFER)                           \
             if(!curlcheck_error_buffer(value))                          \
               _curl_easy_setopt_err_error_buffer();                     \
-          if((_curl_opt) == CURLOPT_STDERR)                             \
+          if((option) == CURLOPT_CURLU)                                 \
+            if(!curlcheck_ptr((value), CURLU))                          \
+              _curl_easy_setopt_err_curlu();                    \
+          if((option) == CURLOPT_STDERR)                                \
             if(!curlcheck_FILE(value))                                  \
               _curl_easy_setopt_err_FILE();                             \
-          if(curlcheck_postfields_option(_curl_opt))                    \
+          if(curlcheck_postfields_option(option))                       \
             if(!curlcheck_postfields(value))                            \
               _curl_easy_setopt_err_postfields();                       \
-          if((_curl_opt) == CURLOPT_HTTPPOST)                           \
+          if((option) == CURLOPT_HTTPPOST)                              \
             if(!curlcheck_arr((value), struct curl_httppost))           \
               _curl_easy_setopt_err_curl_httpost();                     \
-          if((_curl_opt) == CURLOPT_MIMEPOST)                           \
+          if((option) == CURLOPT_MIMEPOST)                              \
             if(!curlcheck_ptr((value), curl_mime))                      \
               _curl_easy_setopt_err_curl_mimepost();                    \
-          if(curlcheck_slist_option(_curl_opt))                         \
+          if(curlcheck_slist_option(option))                            \
             if(!curlcheck_arr((value), struct curl_slist))              \
               _curl_easy_setopt_err_curl_slist();                       \
-          if((_curl_opt) == CURLOPT_SHARE)                              \
+          if((option) == CURLOPT_SHARE)                                 \
             if(!curlcheck_ptr((value), CURLSH))                         \
               _curl_easy_setopt_err_CURLSH();                           \
-        )                                                               \
-      }                                                                 \
-      curl_easy_setopt(handle, _curl_opt, value);                       \
+          )                                                             \
+          }                                                             \
+      curl_easy_setopt(handle, option, value);                          \
     })
 
 /* wraps curl_easy_getinfo() with typechecking */
 #define curl_easy_getinfo(handle, info, arg)                            \
   __extension__({                                                       \
-      CURLINFO _curl_info = (info);                                     \
-      if(__builtin_constant_p(_curl_info)) {                            \
+      if(__builtin_constant_p(info)) {                                  \
         CURL_IGNORE_DEPRECATION(                                        \
-          if(curlcheck_string_info(_curl_info))                         \
+          if(curlcheck_string_info(info))                               \
             if(!curlcheck_arr((arg), char *))                           \
               _curl_easy_getinfo_err_string();                          \
-          if(curlcheck_long_info(_curl_info))                           \
+          if(curlcheck_long_info(info))                                 \
             if(!curlcheck_arr((arg), long))                             \
               _curl_easy_getinfo_err_long();                            \
-          if(curlcheck_double_info(_curl_info))                         \
+          if(curlcheck_double_info(info))                               \
             if(!curlcheck_arr((arg), double))                           \
               _curl_easy_getinfo_err_double();                          \
-          if(curlcheck_slist_info(_curl_info))                          \
+          if(curlcheck_slist_info(info))                                \
             if(!curlcheck_arr((arg), struct curl_slist *))              \
               _curl_easy_getinfo_err_curl_slist();                      \
-          if(curlcheck_tlssessioninfo_info(_curl_info))                 \
+          if(curlcheck_tlssessioninfo_info(info))                       \
             if(!curlcheck_arr((arg), struct curl_tlssessioninfo *))     \
               _curl_easy_getinfo_err_curl_tlssesssioninfo();            \
-          if(curlcheck_certinfo_info(_curl_info))                       \
+          if(curlcheck_certinfo_info(info))                             \
             if(!curlcheck_arr((arg), struct curl_certinfo *))           \
               _curl_easy_getinfo_err_curl_certinfo();                   \
-          if(curlcheck_socket_info(_curl_info))                         \
+          if(curlcheck_socket_info(info))                               \
             if(!curlcheck_arr((arg), curl_socket_t))                    \
               _curl_easy_getinfo_err_curl_socket();                     \
-          if(curlcheck_off_t_info(_curl_info))                          \
+          if(curlcheck_off_t_info(info))                                \
             if(!curlcheck_arr((arg), curl_off_t))                       \
               _curl_easy_getinfo_err_curl_off_t();                      \
-        )                                                               \
-      }                                                                 \
-      curl_easy_getinfo(handle, _curl_info, arg);                       \
+          )                                                             \
+          }                                                             \
+      curl_easy_getinfo(handle, info, arg);                             \
     })
 
 /*
 #define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param)
 #define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param)
 
-
 /* the actual warnings, triggered by calling the _curl_easy_setopt_err*
  * functions */
 
   id(void) { __asm__(""); }
 
 CURLWARNING(_curl_easy_setopt_err_long,
-  "curl_easy_setopt expects a long argument for this option")
+            "curl_easy_setopt expects a long argument")
 CURLWARNING(_curl_easy_setopt_err_curl_off_t,
-  "curl_easy_setopt expects a curl_off_t argument for this option")
+            "curl_easy_setopt expects a curl_off_t argument")
 CURLWARNING(_curl_easy_setopt_err_string,
-              "curl_easy_setopt expects a "
-              "string ('char *' or char[]) argument for this option"
-  )
+            "curl_easy_setopt expects a "
+            "string ('char *' or char[]) argument")
 CURLWARNING(_curl_easy_setopt_err_write_callback,
-  "curl_easy_setopt expects a curl_write_callback argument for this option")
+            "curl_easy_setopt expects a curl_write_callback argument")
 CURLWARNING(_curl_easy_setopt_err_resolver_start_callback,
-              "curl_easy_setopt expects a "
-              "curl_resolver_start_callback argument for this option"
-  )
+            "curl_easy_setopt expects a "
+            "curl_resolver_start_callback argument")
 CURLWARNING(_curl_easy_setopt_err_read_cb,
-  "curl_easy_setopt expects a curl_read_callback argument for this option")
+            "curl_easy_setopt expects a curl_read_callback argument")
 CURLWARNING(_curl_easy_setopt_err_ioctl_cb,
-  "curl_easy_setopt expects a curl_ioctl_callback argument for this option")
+            "curl_easy_setopt expects a curl_ioctl_callback argument")
 CURLWARNING(_curl_easy_setopt_err_sockopt_cb,
-  "curl_easy_setopt expects a curl_sockopt_callback argument for this option")
+            "curl_easy_setopt expects a curl_sockopt_callback argument")
 CURLWARNING(_curl_easy_setopt_err_opensocket_cb,
-              "curl_easy_setopt expects a "
-              "curl_opensocket_callback argument for this option"
-  )
+            "curl_easy_setopt expects a "
+            "curl_opensocket_callback argument")
 CURLWARNING(_curl_easy_setopt_err_progress_cb,
-  "curl_easy_setopt expects a curl_progress_callback argument for this option")
+            "curl_easy_setopt expects a curl_progress_callback argument")
+CURLWARNING(_curl_easy_setopt_err_xferinfo_cb,
+            "curl_easy_setopt expects a curl_xferinfo_callback argument")
 CURLWARNING(_curl_easy_setopt_err_debug_cb,
-  "curl_easy_setopt expects a curl_debug_callback argument for this option")
+            "curl_easy_setopt expects a curl_debug_callback argument")
 CURLWARNING(_curl_easy_setopt_err_ssl_ctx_cb,
-  "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option")
+            "curl_easy_setopt expects a curl_ssl_ctx_callback argument")
 CURLWARNING(_curl_easy_setopt_err_conv_cb,
-  "curl_easy_setopt expects a curl_conv_callback argument for this option")
+            "curl_easy_setopt expects a curl_conv_callback argument")
 CURLWARNING(_curl_easy_setopt_err_seek_cb,
-  "curl_easy_setopt expects a curl_seek_callback argument for this option")
+            "curl_easy_setopt expects a curl_seek_callback argument")
 CURLWARNING(_curl_easy_setopt_err_cb_data,
-              "curl_easy_setopt expects a "
-              "private data pointer as argument for this option")
+            "curl_easy_setopt expects a "
+            "private data pointer as argument")
+CURLWARNING(_curl_easy_setopt_err_chunk_bgn_cb,
+            "curl_easy_setopt expects a curl_chunk_bgn_callback argument")
+CURLWARNING(_curl_easy_setopt_err_chunk_end_cb,
+            "curl_easy_setopt expects a curl_chunk_end_callback argument")
+CURLWARNING(_curl_easy_setopt_err_close_socket_cb,
+            "curl_easy_setopt expects a curl_closesocket_callback argument")
+CURLWARNING(_curl_easy_setopt_err_fnmatch_cb,
+            "curl_easy_setopt expects a curl_fnmatch_callback argument")
+CURLWARNING(_curl_easy_setopt_err_hstsread_cb,
+            "curl_easy_setopt expects a curl_hstsread_callback argument")
+CURLWARNING(_curl_easy_setopt_err_hstswrite_cb,
+            "curl_easy_setopt expects a curl_hstswrite_callback argument")
+CURLWARNING(_curl_easy_setopt_err_ssh_key_cb,
+            "curl_easy_setopt expects a curl_sshkeycallback argument")
+CURLWARNING(_curl_easy_setopt_err_ssh_hostkey_cb,
+            "curl_easy_setopt expects a curl_sshhostkeycallback argument")
+CURLWARNING(_curl_easy_setopt_err_interleave_cb,
+            "curl_easy_setopt expects a curl_interleave_callback argument")
+CURLWARNING(_curl_easy_setopt_err_prereq_cb,
+            "curl_easy_setopt expects a curl_prereq_callback argument")
+CURLWARNING(_curl_easy_setopt_err_trailer_cb,
+            "curl_easy_setopt expects a curl_trailerfunc_ok argument")
 CURLWARNING(_curl_easy_setopt_err_error_buffer,
-              "curl_easy_setopt expects a "
-              "char buffer of CURL_ERROR_SIZE as argument for this option")
+            "curl_easy_setopt expects a "
+            "char buffer of CURL_ERROR_SIZE as argument")
+CURLWARNING(_curl_easy_setopt_err_curlu,
+            "curl_easy_setopt expects a 'CURLU *' argument")
+CURLWARNING(_curl_easy_setopt_err_curl,
+            "curl_easy_setopt expects a 'CURL *' argument")
 CURLWARNING(_curl_easy_setopt_err_FILE,
-  "curl_easy_setopt expects a 'FILE *' argument for this option")
+            "curl_easy_setopt expects a 'FILE *' argument")
 CURLWARNING(_curl_easy_setopt_err_postfields,
-  "curl_easy_setopt expects a 'void *' or 'char *' argument for this option")
+            "curl_easy_setopt expects a 'void *' or 'char *' argument")
 CURLWARNING(_curl_easy_setopt_err_curl_httpost,
-              "curl_easy_setopt expects a 'struct curl_httppost *' "
-              "argument for this option")
+            "curl_easy_setopt expects a 'struct curl_httppost *' "
+            "argument")
 CURLWARNING(_curl_easy_setopt_err_curl_mimepost,
-              "curl_easy_setopt expects a 'curl_mime *' "
-              "argument for this option")
+            "curl_easy_setopt expects a 'curl_mime *' "
+            "argument")
 CURLWARNING(_curl_easy_setopt_err_curl_slist,
-  "curl_easy_setopt expects a 'struct curl_slist *' argument for this option")
+            "curl_easy_setopt expects a 'struct curl_slist *' argument")
 CURLWARNING(_curl_easy_setopt_err_CURLSH,
-  "curl_easy_setopt expects a CURLSH* argument for this option")
-
+            "curl_easy_setopt expects a CURLSH* argument")
 CURLWARNING(_curl_easy_getinfo_err_string,
-  "curl_easy_getinfo expects a pointer to 'char *' for this info")
+            "curl_easy_getinfo expects a pointer to 'char *'")
 CURLWARNING(_curl_easy_getinfo_err_long,
-  "curl_easy_getinfo expects a pointer to long for this info")
+            "curl_easy_getinfo expects a pointer to long")
 CURLWARNING(_curl_easy_getinfo_err_double,
-  "curl_easy_getinfo expects a pointer to double for this info")
+            "curl_easy_getinfo expects a pointer to double")
 CURLWARNING(_curl_easy_getinfo_err_curl_slist,
-  "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info")
+            "curl_easy_getinfo expects a pointer to 'struct curl_slist *'")
 CURLWARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo,
-              "curl_easy_getinfo expects a pointer to "
-              "'struct curl_tlssessioninfo *' for this info")
+            "curl_easy_getinfo expects a pointer to "
+            "'struct curl_tlssessioninfo *'")
 CURLWARNING(_curl_easy_getinfo_err_curl_certinfo,
-              "curl_easy_getinfo expects a pointer to "
-              "'struct curl_certinfo *' for this info")
+            "curl_easy_getinfo expects a pointer to "
+            "'struct curl_certinfo *'")
 CURLWARNING(_curl_easy_getinfo_err_curl_socket,
-  "curl_easy_getinfo expects a pointer to curl_socket_t for this info")
+            "curl_easy_getinfo expects a pointer to curl_socket_t")
 CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
-  "curl_easy_getinfo expects a pointer to curl_off_t for this info")
+            "curl_easy_getinfo expects a pointer to curl_off_t")
 
 /* groups of curl_easy_setops options that take the same type of argument */
 
@@ -253,102 +318,108 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
 #define curlcheck_long_option(option)                   \
   (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT)
 
-#define curlcheck_off_t_option(option)          \
+#define curlcheck_off_t_option(option)                                  \
   (((option) > CURLOPTTYPE_OFF_T) && ((option) < CURLOPTTYPE_BLOB))
 
+/* option takes a CURL * argument */
+#define curlcheck_curl_option(option)                                 \
+  ((option) == CURLOPT_STREAM_DEPENDS ||                              \
+   (option) == CURLOPT_STREAM_DEPENDS_E ||                            \
+   0)
+
 /* evaluates to true if option takes a char* argument */
-#define curlcheck_string_option(option)                                       \
-  ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET ||                                \
-   (option) == CURLOPT_ACCEPT_ENCODING ||                                     \
-   (option) == CURLOPT_ALTSVC ||                                              \
-   (option) == CURLOPT_CAINFO ||                                              \
-   (option) == CURLOPT_CAPATH ||                                              \
-   (option) == CURLOPT_COOKIE ||                                              \
-   (option) == CURLOPT_COOKIEFILE ||                                          \
-   (option) == CURLOPT_COOKIEJAR ||                                           \
-   (option) == CURLOPT_COOKIELIST ||                                          \
-   (option) == CURLOPT_CRLFILE ||                                             \
-   (option) == CURLOPT_CUSTOMREQUEST ||                                       \
-   (option) == CURLOPT_DEFAULT_PROTOCOL ||                                    \
-   (option) == CURLOPT_DNS_INTERFACE ||                                       \
-   (option) == CURLOPT_DNS_LOCAL_IP4 ||                                       \
-   (option) == CURLOPT_DNS_LOCAL_IP6 ||                                       \
-   (option) == CURLOPT_DNS_SERVERS ||                                         \
-   (option) == CURLOPT_DOH_URL ||                                             \
-   (option) == CURLOPT_ECH        ||                                          \
-   (option) == CURLOPT_EGDSOCKET ||                                           \
-   (option) == CURLOPT_FTP_ACCOUNT ||                                         \
-   (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER ||                             \
-   (option) == CURLOPT_FTPPORT ||                                             \
-   (option) == CURLOPT_HSTS ||                                                \
-   (option) == CURLOPT_HAPROXY_CLIENT_IP ||                                   \
-   (option) == CURLOPT_INTERFACE ||                                           \
-   (option) == CURLOPT_ISSUERCERT ||                                          \
-   (option) == CURLOPT_KEYPASSWD ||                                           \
-   (option) == CURLOPT_KRBLEVEL ||                                            \
-   (option) == CURLOPT_LOGIN_OPTIONS ||                                       \
-   (option) == CURLOPT_MAIL_AUTH ||                                           \
-   (option) == CURLOPT_MAIL_FROM ||                                           \
-   (option) == CURLOPT_NETRC_FILE ||                                          \
-   (option) == CURLOPT_NOPROXY ||                                             \
-   (option) == CURLOPT_PASSWORD ||                                            \
-   (option) == CURLOPT_PINNEDPUBLICKEY ||                                     \
-   (option) == CURLOPT_PRE_PROXY ||                                           \
-   (option) == CURLOPT_PROTOCOLS_STR ||                                       \
-   (option) == CURLOPT_PROXY ||                                               \
-   (option) == CURLOPT_PROXY_CAINFO ||                                        \
-   (option) == CURLOPT_PROXY_CAPATH ||                                        \
-   (option) == CURLOPT_PROXY_CRLFILE ||                                       \
-   (option) == CURLOPT_PROXY_ISSUERCERT ||                                    \
-   (option) == CURLOPT_PROXY_KEYPASSWD ||                                     \
-   (option) == CURLOPT_PROXY_PINNEDPUBLICKEY ||                               \
-   (option) == CURLOPT_PROXY_SERVICE_NAME ||                                  \
-   (option) == CURLOPT_PROXY_SSL_CIPHER_LIST ||                               \
-   (option) == CURLOPT_PROXY_SSLCERT ||                                       \
-   (option) == CURLOPT_PROXY_SSLCERTTYPE ||                                   \
-   (option) == CURLOPT_PROXY_SSLKEY ||                                        \
-   (option) == CURLOPT_PROXY_SSLKEYTYPE ||                                    \
-   (option) == CURLOPT_PROXY_TLS13_CIPHERS ||                                 \
-   (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD ||                              \
-   (option) == CURLOPT_PROXY_TLSAUTH_TYPE ||                                  \
-   (option) == CURLOPT_PROXY_TLSAUTH_USERNAME ||                              \
-   (option) == CURLOPT_PROXYPASSWORD ||                                       \
-   (option) == CURLOPT_PROXYUSERNAME ||                                       \
-   (option) == CURLOPT_PROXYUSERPWD ||                                        \
-   (option) == CURLOPT_RANDOM_FILE ||                                         \
-   (option) == CURLOPT_RANGE ||                                               \
-   (option) == CURLOPT_REDIR_PROTOCOLS_STR ||                                 \
-   (option) == CURLOPT_REFERER ||                                             \
-   (option) == CURLOPT_REQUEST_TARGET ||                                      \
-   (option) == CURLOPT_RTSP_SESSION_ID ||                                     \
-   (option) == CURLOPT_RTSP_STREAM_URI ||                                     \
-   (option) == CURLOPT_RTSP_TRANSPORT ||                                      \
-   (option) == CURLOPT_SASL_AUTHZID ||                                        \
-   (option) == CURLOPT_SERVICE_NAME ||                                        \
-   (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE ||                               \
-   (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                             \
-   (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 ||                          \
-   (option) == CURLOPT_SSH_KNOWNHOSTS ||                                      \
-   (option) == CURLOPT_SSH_PRIVATE_KEYFILE ||                                 \
-   (option) == CURLOPT_SSH_PUBLIC_KEYFILE ||                                  \
-   (option) == CURLOPT_SSLCERT ||                                             \
-   (option) == CURLOPT_SSLCERTTYPE ||                                         \
-   (option) == CURLOPT_SSLENGINE ||                                           \
-   (option) == CURLOPT_SSLKEY ||                                              \
-   (option) == CURLOPT_SSLKEYTYPE ||                                          \
-   (option) == CURLOPT_SSL_CIPHER_LIST ||                                     \
-   (option) == CURLOPT_TLS13_CIPHERS ||                                       \
-   (option) == CURLOPT_TLSAUTH_PASSWORD ||                                    \
-   (option) == CURLOPT_TLSAUTH_TYPE ||                                        \
-   (option) == CURLOPT_TLSAUTH_USERNAME ||                                    \
-   (option) == CURLOPT_UNIX_SOCKET_PATH ||                                    \
-   (option) == CURLOPT_URL ||                                                 \
-   (option) == CURLOPT_USERAGENT ||                                           \
-   (option) == CURLOPT_USERNAME ||                                            \
-   (option) == CURLOPT_AWS_SIGV4 ||                                           \
-   (option) == CURLOPT_USERPWD ||                                             \
-   (option) == CURLOPT_XOAUTH2_BEARER ||                                      \
-   (option) == CURLOPT_SSL_EC_CURVES ||                                       \
+#define curlcheck_string_option(option)                                 \
+  ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET ||                          \
+   (option) == CURLOPT_ACCEPT_ENCODING ||                               \
+   (option) == CURLOPT_ALTSVC ||                                        \
+   (option) == CURLOPT_CAINFO ||                                        \
+   (option) == CURLOPT_CAPATH ||                                        \
+   (option) == CURLOPT_COOKIE ||                                        \
+   (option) == CURLOPT_COOKIEFILE ||                                    \
+   (option) == CURLOPT_COOKIEJAR ||                                     \
+   (option) == CURLOPT_COOKIELIST ||                                    \
+   (option) == CURLOPT_CRLFILE ||                                       \
+   (option) == CURLOPT_CUSTOMREQUEST ||                                 \
+   (option) == CURLOPT_DEFAULT_PROTOCOL ||                              \
+   (option) == CURLOPT_DNS_INTERFACE ||                                 \
+   (option) == CURLOPT_DNS_LOCAL_IP4 ||                                 \
+   (option) == CURLOPT_DNS_LOCAL_IP6 ||                                 \
+   (option) == CURLOPT_DNS_SERVERS ||                                   \
+   (option) == CURLOPT_DOH_URL ||                                       \
+   (option) == CURLOPT_ECH ||                                           \
+   (option) == CURLOPT_EGDSOCKET ||                                     \
+   (option) == CURLOPT_FTP_ACCOUNT ||                                   \
+   (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER ||                       \
+   (option) == CURLOPT_FTPPORT ||                                       \
+   (option) == CURLOPT_HAPROXY_CLIENT_IP ||                             \
+   (option) == CURLOPT_HSTS ||                                          \
+   (option) == CURLOPT_INTERFACE ||                                     \
+   (option) == CURLOPT_ISSUERCERT ||                                    \
+   (option) == CURLOPT_KEYPASSWD ||                                     \
+   (option) == CURLOPT_KRBLEVEL ||                                      \
+   (option) == CURLOPT_LOGIN_OPTIONS ||                                 \
+   (option) == CURLOPT_MAIL_AUTH ||                                     \
+   (option) == CURLOPT_MAIL_FROM ||                                     \
+   (option) == CURLOPT_NETRC_FILE ||                                    \
+   (option) == CURLOPT_NOPROXY ||                                       \
+   (option) == CURLOPT_PASSWORD ||                                      \
+   (option) == CURLOPT_PINNEDPUBLICKEY ||                               \
+   (option) == CURLOPT_PRE_PROXY ||                                     \
+   (option) == CURLOPT_PROTOCOLS_STR ||                                 \
+   (option) == CURLOPT_PROXY ||                                         \
+   (option) == CURLOPT_PROXY_CAINFO ||                                  \
+   (option) == CURLOPT_PROXY_CAPATH ||                                  \
+   (option) == CURLOPT_PROXY_CRLFILE ||                                 \
+   (option) == CURLOPT_PROXY_ISSUERCERT ||                              \
+   (option) == CURLOPT_PROXY_KEYPASSWD ||                               \
+   (option) == CURLOPT_PROXY_PINNEDPUBLICKEY ||                         \
+   (option) == CURLOPT_PROXY_SERVICE_NAME ||                            \
+   (option) == CURLOPT_PROXY_SSL_CIPHER_LIST ||                         \
+   (option) == CURLOPT_PROXY_SSLCERT ||                                 \
+   (option) == CURLOPT_PROXY_SSLCERTTYPE ||                             \
+   (option) == CURLOPT_PROXY_SSLKEY ||                                  \
+   (option) == CURLOPT_PROXY_SSLKEYTYPE ||                              \
+   (option) == CURLOPT_PROXY_TLS13_CIPHERS ||                           \
+   (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD ||                        \
+   (option) == CURLOPT_PROXY_TLSAUTH_TYPE ||                            \
+   (option) == CURLOPT_PROXY_TLSAUTH_USERNAME ||                        \
+   (option) == CURLOPT_PROXYPASSWORD ||                                 \
+   (option) == CURLOPT_PROXYUSERNAME ||                                 \
+   (option) == CURLOPT_PROXYUSERPWD ||                                  \
+   (option) == CURLOPT_RANDOM_FILE ||                                   \
+   (option) == CURLOPT_RANGE ||                                         \
+   (option) == CURLOPT_REDIR_PROTOCOLS_STR ||                           \
+   (option) == CURLOPT_REFERER ||                                       \
+   (option) == CURLOPT_REQUEST_TARGET ||                                \
+   (option) == CURLOPT_RTSP_SESSION_ID ||                               \
+   (option) == CURLOPT_RTSP_STREAM_URI ||                               \
+   (option) == CURLOPT_RTSP_TRANSPORT ||                                \
+   (option) == CURLOPT_SASL_AUTHZID ||                                  \
+   (option) == CURLOPT_SERVICE_NAME ||                                  \
+   (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE ||                         \
+   (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                       \
+   (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 ||                    \
+   (option) == CURLOPT_SSH_KNOWNHOSTS ||                                \
+   (option) == CURLOPT_SSH_PRIVATE_KEYFILE ||                           \
+   (option) == CURLOPT_SSH_PUBLIC_KEYFILE ||                            \
+   (option) == CURLOPT_SSLCERT ||                                       \
+   (option) == CURLOPT_SSLCERTTYPE ||                                   \
+   (option) == CURLOPT_SSLENGINE ||                                     \
+   (option) == CURLOPT_SSLKEY ||                                        \
+   (option) == CURLOPT_SSLKEYTYPE ||                                    \
+   (option) == CURLOPT_SSL_CIPHER_LIST ||                               \
+   (option) == CURLOPT_TLS13_CIPHERS ||                                 \
+   (option) == CURLOPT_TLSAUTH_PASSWORD ||                              \
+   (option) == CURLOPT_TLSAUTH_TYPE ||                                  \
+   (option) == CURLOPT_TLSAUTH_USERNAME ||                              \
+   (option) == CURLOPT_UNIX_SOCKET_PATH ||                              \
+   (option) == CURLOPT_URL ||                                           \
+   (option) == CURLOPT_USERAGENT ||                                     \
+   (option) == CURLOPT_USERNAME ||                                      \
+   (option) == CURLOPT_AWS_SIGV4 ||                                     \
+   (option) == CURLOPT_USERPWD ||                                       \
+   (option) == CURLOPT_XOAUTH2_BEARER ||                                \
+   (option) == CURLOPT_SSL_EC_CURVES ||                                 \
    0)
 
 /* evaluates to true if option takes a curl_write_callback argument */
@@ -375,7 +446,7 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
    (option) == CURLOPT_IOCTLDATA ||                                           \
    (option) == CURLOPT_OPENSOCKETDATA ||                                      \
    (option) == CURLOPT_PREREQDATA ||                                          \
-   (option) == CURLOPT_PROGRESSDATA ||                                        \
+   (option) == CURLOPT_XFERINFODATA ||                                        \
    (option) == CURLOPT_READDATA ||                                            \
    (option) == CURLOPT_SEEKDATA ||                                            \
    (option) == CURLOPT_SOCKOPTDATA ||                                         \
@@ -479,22 +550,36 @@ CURLWARNING(_curl_easy_getinfo_err_curl_off_t,
    curlcheck_arr((expr), signed char) ||                                \
    curlcheck_arr((expr), unsigned char))
 
+/* evaluates to true if expr is a CURL * */
+#define curlcheck_curl(expr)                                          \
+  (curlcheck_NULL(expr) ||                                              \
+   __builtin_types_compatible_p(__typeof__(expr), CURL *))
+
+
 /* evaluates to true if expr is a long (no matter the signedness)
  * XXX: for now, int is also accepted (and therefore short and char, which
  * are promoted to int when passed to a variadic function) */
-#define curlcheck_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) ||           \
-   __builtin_types_compatible_p(__typeof__(expr), int) ||                     \
-   __builtin_types_compatible_p(__typeof__(expr), signed int) ||              \
-   __builtin_types_compatible_p(__typeof__(expr), unsigned int) ||            \
-   __builtin_types_compatible_p(__typeof__(expr), short) ||                   \
-   __builtin_types_compatible_p(__typeof__(expr), signed short) ||            \
-   __builtin_types_compatible_p(__typeof__(expr), unsigned short) ||          \
-   __builtin_types_compatible_p(__typeof__(expr), char) ||                    \
-   __builtin_types_compatible_p(__typeof__(expr), signed char) ||             \
-   __builtin_types_compatible_p(__typeof__(expr), unsigned char))
+#define curlcheck_long(expr)                                            \
+  (                                                                     \
+  ((sizeof(long) != sizeof(int)) &&                                     \
+   (__builtin_types_compatible_p(__typeof__(expr), long) ||             \
+    __builtin_types_compatible_p(__typeof__(expr), signed long) ||      \
+    __builtin_types_compatible_p(__typeof__(expr), unsigned long)))     \
+  ||                                                                    \
+  ((sizeof(long) == sizeof(int)) &&                                     \
+  (__builtin_types_compatible_p(__typeof__(expr), long) ||              \
+   __builtin_types_compatible_p(__typeof__(expr), signed long) ||       \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned long) ||     \
+   __builtin_types_compatible_p(__typeof__(expr), int) ||               \
+   __builtin_types_compatible_p(__typeof__(expr), signed int) ||        \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned int) ||      \
+   __builtin_types_compatible_p(__typeof__(expr), short) ||             \
+   __builtin_types_compatible_p(__typeof__(expr), signed short) ||      \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned short) ||    \
+   __builtin_types_compatible_p(__typeof__(expr), char) ||              \
+   __builtin_types_compatible_p(__typeof__(expr), signed char) ||       \
+   __builtin_types_compatible_p(__typeof__(expr), unsigned char)))      \
+                                                                  )
 
 /* evaluates to true if expr is of type curl_off_t */
 #define curlcheck_off_t(expr)                                   \
@@ -629,6 +714,11 @@ typedef int (*_curl_progress_callback1)(void *,
 typedef int (*_curl_progress_callback2)(const void *,
     double, double, double, double);
 
+/* evaluates to true if expr is of type curl_xferinfo_callback */
+#define curlcheck_xferinfo_cb(expr)                                     \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_xferinfo_callback))
+
 /* evaluates to true if expr is of type curl_debug_callback or "similar" */
 #define curlcheck_debug_cb(expr)                                        \
   (curlcheck_NULL(expr) ||                                              \
@@ -714,5 +804,69 @@ typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length);
 typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int);
 typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int);
 
+/* evaluates to true if expr is of type curl_chunk_bgn_callback */
+#define curlcheck_chunk_bgn_cb(expr)                                    \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_chunk_bgn_callback) ||          \
+   curlcheck_cb_compatible((expr), _curl_chunk_bgn_callback1) ||        \
+   curlcheck_cb_compatible((expr), _curl_chunk_bgn_callback2))
+typedef long (*_curl_chunk_bgn_callback1)(struct curl_fileinfo *,
+                                          void *, int);
+typedef long (*_curl_chunk_bgn_callback2)(void *, void *, int);
+
+/* evaluates to true if expr is of type curl_chunk_end_callback */
+#define curlcheck_chunk_end_cb(expr)                                    \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_chunk_end_callback))
+
+/* evaluates to true if expr is of type curl_closesocket_callback */
+#define curlcheck_close_socket_cb(expr)                                 \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_closesocket_callback))
+
+/* evaluates to true if expr is of type curl_fnmatch_callback */
+#define curlcheck_fnmatch_cb(expr)                                      \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_fnmatch_callback))
+
+/* evaluates to true if expr is of type curl_hstsread_callback */
+#define curlcheck_hstsread_cb(expr)                                     \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_hstsread_callback))
+
+/* evaluates to true if expr is of type curl_hstswrite_callback */
+#define curlcheck_hstswrite_cb(expr)                                    \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_hstswrite_callback))
+
+/* evaluates to true if expr is of type curl_sshhostkeycallback */
+#define curlcheck_ssh_hostkey_cb(expr)                                  \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), curl_sshhostkeycallback))
+
+/* evaluates to true if expr is of type curl_sshkeycallback */
+#define curlcheck_ssh_key_cb(expr)                                  \
+  (curlcheck_NULL(expr) ||                                          \
+   curlcheck_cb_compatible((expr), curl_sshkeycallback))
+
+/* evaluates to true if expr is of type curl_interleave_callback */
+#define curlcheck_interleave_cb(expr)                                   \
+  (curlcheck_NULL(expr) ||                                              \
+   curlcheck_cb_compatible((expr), _curl_interleave_callback1) ||       \
+   curlcheck_cb_compatible((expr), _curl_interleave_callback2))
+typedef size_t (*_curl_interleave_callback1)(void *p, size_t s,
+                                             size_t n, void *u);
+typedef size_t (*_curl_interleave_callback2)(char *p, size_t s,
+                                             size_t n, void *u);
+
+/* evaluates to true if expr is of type curl_prereq_callback */
+#define curlcheck_prereq_cb(expr)                                    \
+  (curlcheck_NULL(expr) ||                                           \
+   curlcheck_cb_compatible((expr), curl_prereq_callback))
+
+/* evaluates to true if expr is of type curl_trailer_callback */
+#define curlcheck_trailer_cb(expr)                                    \
+  (curlcheck_NULL(expr) ||                                            \
+   curlcheck_cb_compatible((expr), curl_trailer_callback))
 
 #endif /* CURLINC_TYPECHECK_GCC_H */
index 8c40bc3a1a52fcfd32fc2fea3263f121838f71a4..0206135c635723dea6beaf97ddb2096ee5989030 100644 (file)
@@ -51,6 +51,7 @@ TESTSCRIPTS = \
  test1488.pl  \
  test1544.pl  \
  test1707.pl  \
+ test745.pl  \
  test971.pl
 
 EXTRA_DIST =        \
index 5936494fa35278d5bf279142942de114a1ce06c0..39adc2cb2d09fbda88a2ce55b2483424fdb3d1b1 100644 (file)
@@ -107,6 +107,7 @@ test709 test710 test711 test712 test713 test714 test715 test716 test717 \
 test718 test719 test720 test721 test722 test723 test724 test725 test726 \
 test727 test728 test729 test730 test731 test732 test733 test734 test735 \
 test736 test737 test738 test739 test740 test741 test742 test743 test744 \
+test745 \
 \
 test780 test781 test782 test783 test784 test785 test786 test787 test788 \
 test789 test790 test791 \
diff --git a/tests/data/test745 b/tests/data/test745
new file mode 100644 (file)
index 0000000..9761dd5
--- /dev/null
@@ -0,0 +1,31 @@
+<testcase>
+<info>
+<keywords>
+source analysis
+symbols-in-versions
+</keywords>
+</info>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+
+<name>
+Verify that typecheck-gcc and curl.h are in sync
+</name>
+
+<command type="perl">
+%SRCDIR/test745.pl %SRCDIR/..
+</command>
+</client>
+
+<verify>
+<stdout>
+OK
+</stdout>
+</verify>
+
+</testcase>
diff --git a/tests/test745.pl b/tests/test745.pl
new file mode 100755 (executable)
index 0000000..c5c64f6
--- /dev/null
@@ -0,0 +1,85 @@
+#!/usr/bin/env perl
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 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 https://curl.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.
+#
+# SPDX-License-Identifier: curl
+#
+###########################################################################
+#
+#
+
+use strict;
+use warnings;
+
+# we may get the dir root pointed out
+my $root=$ARGV[0] || ".";
+
+my %typecheck; # from the include file
+my %enum; # from libcurl-errors.3
+
+sub gettypecheck {
+    open(my $f, "<", "$root/include/curl/typecheck-gcc.h")
+        || die "no typecheck file";
+    while(<$f>) {
+        chomp;
+        if($_ =~ /\(option\) == (CURL[^ \)]*)/) {
+            $typecheck{$1}++;
+        }
+    }
+    close($f);
+}
+
+sub getinclude {
+    open(my $f, "<", "$root/include/curl/curl.h")
+        || die "no curl.h";
+    while(<$f>) {
+        if($_ =~ /\((CURLOPT[^,]*), (CURLOPTTYPE_[^,]*)/) {
+            my ($opt, $type) = ($1, $2);
+            if($type !~ /LONG|VALUES|BLOB|OFF_T/) {
+                $enum{$opt}++;
+            }
+        }
+    }
+    $enum{"CURLOPT_SOCKS5_GSSAPI_SERVICE"}++;
+    $enum{"CURLOPT_SOMETHING"}++;
+    $enum{"CURLOPT_CONV_FROM_NETWORK_FUNCTION"}++;
+    $enum{"CURLOPT_CONV_FROM_UTF8_FUNCTION"}++;
+    $enum{"CURLOPT_CONV_TO_NETWORK_FUNCTION"}++;
+    close($f);
+}
+
+gettypecheck();
+getinclude();
+
+my $error;
+for(sort keys %typecheck) {
+    if($typecheck{$_} && !$enum{$_}) {
+        print "$_ is not in curl.h\n";
+        $error++;
+    }
+}
+
+for(sort keys %enum) {
+    if($enum{$_} && !$typecheck{$_}) {
+        print "$_ is not checked in typecheck-gcc-h\n";
+        $error++;
+    }
+}
+print "OK\n" if(!$error);