-
Notifications
You must be signed in to change notification settings - Fork 455
CDRIVER-5549 Address -fsanitize=function and -Wcast-function-type-strict warnings #1662
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The efforts to reduce UBSan and warnings are much appreciated. I expect this will ease the eventual upgrade of clang used in UBSan tasks.
LGTM with one suggested change:
Compiling with -Wcast-function-type-strict
locally (on "Homebrew clang version 18.1.8") identifies:
mongoc-util.c:922:48: error: cast from 'size_t (*)(void)' (aka 'unsigned long (*)(void)') to 'uint64_t (*)(void)' (aka 'unsigned long long (*)(void)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]
922 | return _mongoc_rand_java64 (max - min + 1u, (uint64_t (*) (void)) rand) + min;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
Suggest wrapping call to rand
:
static uint64_t
rand_u64 (void)
{
return (uint64_t) rand ();
}
Addressed by removing the
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Summary
Resolves CDRIVER-5549. Verified by this patch.
Recommend reviewing this PR by-commit.
This PR identifies and addresses ~20 UBSan runtime errors (exact number depends on the server version and topology) and 154 instances of
-Wcast-function-type-strict
warnings that were locally observed when building the C Driver with Clang 17. Some instances may still be unaccounted for due to sensitivity to specific build configurations, but this PR aims to provide a template for addressing such instances in the future should they become a problem (note: this PR does not add Clang 17+ test coverage to the EVG config).Description
Clang 17 extends the UBSan check "function", usually enabled for C++ code, to C code as well. This check diagnoses the following clause from the C99 draft:
Many C codebases, including our own, violates this clause, often through the following commonly-seen pattern:
Unfortunately, this pattern is undefined behavior. The type of
*fn
when invoked asfn (ptr)
isvoid (void *)
, which is not compatible with the type of the actual functions being invoked:void (A *)
andvoid (B *)
respectively. The convertibility of individual object pointers of typeT*
to/fromvoid*
does not extend to the parameters of a function type.Therefore, it is necessary to ensure that the type of the function being invoked is always compatible with the type of the function in the invocation expression. Identifying such cases can be assisted by the
-Wcast-function-type-strict
Clang warning, which warns whenever a function is cast to/from an incompatible function type.The solution usually involved one of three kinds of common patterns:
void *
for consistency with the "common" function pointer type and cast back to the object pointer type within the function body. (e.g.TestFuncWC
andTestFunc
callbacks, TS pool callbacks, etc.).bson_destroy_vp
,_apm_func
+_apm_func_defn
, etc.)void *
) instead. (e.g.TestFnCtx
(introduced in CDRIVER-3632 Address pedantic warnings for function pointer conversions #850),make_cursor_helper_t
, etc.)As an exception to the above, the
mongoc_set_t
const-for-each interface needed to be extended, as a pattern that reuses a common implementation that does not violate function type compatibility could not be identified.-Wcast-function-type-strict
warnings pertaining to external libraries are explicitly suppressed or silenced, as there is little we can do about it ourselves (e.g. OpenSSL/Cyrus callback registration APIs).As a drive-by fix (not quite related), a benign UBSan runtime error emitted by the utf8proc library is suppressed by a new
.ubsan-suppressions
file. Details are documented within the suppressions file itself.