From ea6d97c881b0c0a28082e1f71c6476641c0f19ae Mon Sep 17 00:00:00 2001 From: Weaselbot Date: Sun, 21 Jun 2026 12:42:27 -0400 Subject: [PATCH] Make ConflictSet non-copyable in C++98/C++03 `ConflictSet(const ConflictSet&)` and `operator=(const ConflictSet&)` were only deleted for C++11 and later. In C++98/C++03 the compiler implicitly generated public copy operations, so copying a ConflictSet shared the opaque `Impl*` and caused a double-free on destruction. Declare both operations private and leave them undefined when `__cplusplus <= 199711L`, matching the standard pre-C++11 idiom for move-only types. Guard the declarations with `defined(__cplusplus)` so they are not exposed to C90 compilation units. Closes #48 --- include/ConflictSet.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/ConflictSet.h b/include/ConflictSet.h index a100e01..0b91d6a 100644 --- a/include/ConflictSet.h +++ b/include/ConflictSet.h @@ -132,6 +132,13 @@ struct __attribute__((__visibility__("default"))) ConflictSet { private: Impl *impl; +#if defined(__cplusplus) && __cplusplus <= 199711L + /* Declared private and left undefined to prevent copying in C++98/C++03. + The compiler would otherwise implicitly generate public copy operations, + which share the opaque Impl* and cause a double-free. */ + ConflictSet(const ConflictSet &); + ConflictSet &operator=(const ConflictSet &); +#endif }; } /* namespace weaselab */