checkedc / checkedc-fork

This was a fork of Checked C used from 2021-2024. The changes have been merged into the original Checked C repo.
Other
26 stars 3 forks source link

`redeclare_libs_{explicit,implicit}.c` tests fail when `_CHECKEDC_MOCKUP_THREADS` is removed on a system that supports threads #458

Open secure-sw-dev-bot opened 2 years ago

secure-sw-dev-bot commented 2 years ago

This issue was copied from https://github.com/microsoft/checkedc/issues/459


I noticed a mistake in threads_checked.h (the return type of cnd_init should be int, not void) and plan to fix it in #448. I hoped to use the tests in tests/checked_headers to demonstrate the original problem and verify that no other problems remain after my fix. However, these tests use #define _CHECKEDC_MOCKUP_THREADS 1, which causes the system's threads.h not to be loaded, so any inconsistency between the Checked C and system declarations would not be detected. (Can anything be done to improve this situation? Can we assume that if __has_include_next(<threads.h>) is true, then threads.h can be used for the test? Maybe a separate issue should be filed for this.)

In any case, since my Linux system does have a compliant threads.h, I tried manually running the tests with the #define _CHECKEDC_MOCKUP_THREADS 1 removed. This exposed a different problem in redeclare_libs_{explicit,implicit}.c (coincidentally, redeclare_libs_mixed.c is not affected). On my system, threads.h contains #include <time.h>. When implicit checked header inclusion is enabled, this causes time_checked.h to be included during the processing of the #include <threads.h> (or #include <threads_checked.h>) in the test. When the test subsequently does a direct #include <time.h> (or #include <time_checked.h>), parts of those files are skipped due to header guards. The end result is that the foo_checked.h and #pragma CHECKED_SCOPE on strings appear in the preprocessed output in a different order than the CHECK_ENABLED directives expect, and the tests fail.

One solution is to just move time.h before threads.h in the tests; when I did that, the tests passed. More generally, assuming the dependencies among the system headers are acyclic, we'd ensure that the order of headers in the tests is consistent with the dependencies among the system headers, so that no #include in a test causes a premature implicit inclusion of a different checked header that is referenced by the same test. This would be a bit of a hack, but I don't know whether there's another reasonable solution that maintains the test coverage we want.