Detect thread safety attribute support in mutex.h (#2263) - #2275
Detect thread safety attribute support in mutex.h (#2263)#2275devtejasx wants to merge 1 commit into
Conversation
| // Enable thread safety attributes only with clang. | ||
| // The attributes can be safely erased when compiling with other compilers. | ||
| // | ||
| // Detect support instead of relying on the build system to opt in: build |
There was a problem hiding this comment.
but nothing has been changed in the build system so this is not "instead of" is it?
a3f4607 to
c283274
Compare
|
Correct — nothing in the build system changes, and the wording was wrong. Reworded to state the situation plainly rather than describe it as a replacement:
|
| // | ||
| // HAVE_THREAD_SAFETY_ATTRIBUTES is left to whoever compiles the library, and | ||
| // no build in this tree defines it. That is fine as long as -Wthread-safety is | ||
| // off, but Bazel turns it on by default, and there the wrappers below get |
There was a problem hiding this comment.
i'm a bit confused. if Bazel turns it on, then the macro HAVE_THREAD_SAFETY_ATTRIBUTES should be enabled. or is this trying to suggest that Bazel turns it on but doesn't enable the macro?
either way, i think this whole comment should be focused on why we need to do this check here (and not, say, in the build system: if we know Bazel enables it then why not set the cc_defines in the build script?)
| defined(__has_attribute) | ||
| #if __has_attribute(capability) | ||
| #define HAVE_THREAD_SAFETY_ATTRIBUTES | ||
| #endif |
There was a problem hiding this comment.
(I think something like this overall diff should be done.)
Is there any compiler other than clang that supports TSA anyway?
Can we just check for clang, and perhaps do a version check?
There was a problem hiding this comment.
(to be more specific, i strongly suspect that __has_attribute(capability) is bogus/unsufficient,
that only covers CAPABILITY(), what about others? Can we just assume they are implied by it?)
The annotations in mutex.h are only active when HAVE_THREAD_SAFETY_ATTRIBUTES is defined, which is left to whoever compiles the library, and nothing in this tree defines it. That is invisible until something turns on -Wthread-safety anyway -- Bazel's default toolchain adds it whenever the compiler accepts it -- and the wrappers are then analyzed with their own annotations erased. Where the standard library annotates std::mutex itself (libc++, hence macOS) that is a hard error: src/mutex.h:79:40: error: mutex 'mut_' is still held at the end of function src/mutex.h:80:34: error: releasing mutex 'mut_' that was not held Turn the annotations on for clang, which is the only compiler that implements them. Setting the macro from BUILD.bazel instead would fix that one build but not the general case: the same build file also has to serve compilers that reject the attributes, so the decision belongs next to the attributes. An external definition still wins. Verified with clang 21 + libc++ (reproduces before, clean after), clang 21 + libstdc++, gcc 15 and MSVC; the full library builds clean under -Wall -Wextra -Wthread-safety -Werror with clang.
c283274 to
929be6c
Compare
|
Both addressed. @LebedevRI — dropped #if !defined(HAVE_THREAD_SAFETY_ATTRIBUTES) && defined(__clang__)
#define HAVE_THREAD_SAFETY_ATTRIBUTES
#endifNo version check: the attributes used here have all been in clang since 3.x, well below anything this project supports. @dmah42 — on the confusion: yes, Bazel turns on the warning without defining the macro. Its default C++ toolchain adds On setting it from Verified against clang 21 + libc++ (reproduces before, clean after), clang 21 + libstdc++, gcc 15 and MSVC; the library still builds clean under |
|
i would have thought https://bazel.build/docs/configurable-attributes would be the right way to solve it for compiler. |
|
That works for the Bazel build, and if it is what you want I will send it — The reason I did not: So the trade-off as I see it: one line in the header that every build system inherits, versus a |
The thread safety annotations were only enabled when the surrounding build system defined HAVE_THREAD_SAFETY_ATTRIBUTES, but nothing in the tree ever defines it. Build systems that turn on -Wthread-safety by default -- Bazel does on macOS -- therefore analyzed Mutex/MutexLock with every annotation erased. Where the standard library annotates std::mutex itself (libc++), that makes the analysis conclude that Mutex::lock() leaks the lock and that Mutex::unlock() releases a lock that was never held, which is a hard error under -Werror:
src/mutex.h:79:40: error: mutex 'mut_' is still held at the end of function
src/mutex.h:80:34: error: releasing mutex 'mut_' that was not held
Enable the annotations whenever the compiler actually supports them, probed with __has_attribute(capability), so the wrappers are analyzed with the contract they are meant to have. An explicit HAVE_THREAD_SAFETY_ATTRIBUTES from the build system still takes precedence, and
BENCHMARK_DISABLE_THREAD_SAFETY_ATTRIBUTES forces the previous no-op behaviour back.
Verified with clang 21 + libc++ (reproduces before, clean after), clang 21 + libstdc++, gcc 15 and MSVC; the full library builds clean under -Wall -Wextra -Wthread-safety -Werror with clang.
Per AGENTS.md: AI-assisted — the patch was drafted with AI assistance
(Claude) and then reviewed, tested, and understood by me. I take full
responsibility for it.