From 91e81bf2623af626acf94c37ae43b3b4eef8313d Mon Sep 17 00:00:00 2001 From: Matthew Woehlke Date: Fri, 1 May 2026 14:49:11 -0400 Subject: [PATCH] Diagnostics: Ensure correct ordering Create a constexpr function that recursively validates that [a portion of] the diagnostics tree is in proper depth-first order. Use this to ensure at compile time that the diagnostics are, in fact, in the correct order. This will make it harder to accidentally introduce order errors, since any C++17 build will throw a compile error if the list is not correctly ordered. --- Source/cmDiagnostics.cxx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Source/cmDiagnostics.cxx b/Source/cmDiagnostics.cxx index 60d3ec4067..50d3c02b32 100644 --- a/Source/cmDiagnostics.cxx +++ b/Source/cmDiagnostics.cxx @@ -12,6 +12,28 @@ #include "cmStringAlgorithms.h" namespace { + +#if __cplusplus >= 201703L +constexpr unsigned validateDiagnosticsSubtree(unsigned parent, unsigned index) +{ + // Ensure that all diagnostics, starting from the specified index, have the + // specified parent as an ancestor. Return the first index that violates + // this condition. + while (index < cmDiagnostics::CategoryCount && + cmDiagnostics::CategoryInfo[index].Parent == parent) { + unsigned const child = index; + // For each diagnostic, 'consume' its children (if any). + index = validateDiagnosticsSubtree(child, ++index); + } + return index; +} + +static_assert(validateDiagnosticsSubtree(cmDiagnostics::CMD_NONE, 1) == + cmDiagnostics::CategoryCount, + "Diagnostics are not properly ordered" + " (hint: LHS is the index of the first misordered diagnostic)"); +#endif + cm::optional stringToCategory(cm::string_view input) { using Map = std::map;