usbguard: fix bundled PEGTL demangle static_assert with GCC 16

The bundled PEGTL parses __PRETTY_FUNCTION__ at compile time and trips a
static_assert under GCC 16:

  src/ThirdParty/PEGTL/include/tao/pegtl/demangle.hpp:118:23:
  error: static assertion failed

usbguard demangles PEGTL rules built from ascii::one<'\000', '\012'>,
i.e. types with a char non-type template parameter whose value is '\0'.
GCC 16 renders such a parameter as a literal NUL byte and truncates
__PRETTY_FUNCTION__ there:

  constexpr std::string_view demangle() [with T = seq<one<'

so the trailing "; std::string_view = ...]" and even the closing ']' are
gone, and rfind(';')/rfind(']') both return npos.

Patch demangle() to fall back to the remainder of the string when no
';'/']' terminator survives, instead of failing the build; the demangled
name is only used for tracing diagnostics. Type names without a '\0' char
parameter are unaffected.

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
This commit is contained in:
Khem Raj
2026-06-25 06:17:18 +00:00
parent 884e0c9ff7
commit 9c02e30bef
2 changed files with 60 additions and 0 deletions
@@ -0,0 +1,59 @@
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 25 Jun 2026 00:00:00 +0000
Subject: [PATCH] PEGTL: fix demangle() static_assert with GCC 16
The bundled PEGTL demangles type names at compile time by parsing
__PRETTY_FUNCTION__, which looks like
...[with T = X; std::string_view = std::basic_string_view<char>]
and locating the end of the type name via rfind(';').
usbguard instantiates demangle() for PEGTL rules built from
ascii::one<'\000', '\012'> (and friends), i.e. types that carry a char
non-type template parameter whose value is '\0'. GCC 16 renders such a
parameter as a literal NUL byte in __PRETTY_FUNCTION__ and truncates the
generated string at that byte:
constexpr std::string_view demangle() [with T = seq<one<'
so the trailing "; std::string_view = ...]" alias and even the closing
']' are gone. rfind(';') and rfind(']') both return npos and the
demangler trips:
src/ThirdParty/PEGTL/include/tao/pegtl/demangle.hpp:118:23:
error: static assertion failed
The demangled name is only used for human-readable tracing diagnostics,
so rather than fail the build, fall back to the remainder of the string
when no ';' or ']' terminator survives. Type names without a '\0' char
parameter are unaffected.
Upstream-Status: Pending
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
src/ThirdParty/PEGTL/include/tao/pegtl/demangle.hpp | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
--- a/src/ThirdParty/PEGTL/include/tao/pegtl/demangle.hpp
+++ b/src/ThirdParty/PEGTL/include/tao/pegtl/demangle.hpp
@@ -114,8 +114,17 @@
constexpr auto begin = sv.find( '=' );
static_assert( begin != std::string_view::npos );
constexpr auto tmp = sv.substr( begin + 2 );
- constexpr auto end = tmp.rfind( ';' );
- static_assert( end != std::string_view::npos );
+ // GCC 16 renders a char non-type template parameter whose value is '\0'
+ // (e.g. PEGTL's ascii::one<'\000', ...>) as a literal NUL byte inside
+ // __PRETTY_FUNCTION__ and truncates the generated string there, dropping
+ // the trailing "; std::string_view = ...]" alias and even the closing
+ // ']'. Fall back to the remainder of the string instead of failing a
+ // static_assert (the demangled name is only used for tracing output).
+ constexpr auto semi = tmp.rfind( ';' );
+ constexpr auto brak = tmp.rfind( ']' );
+ constexpr auto end = ( semi != std::string_view::npos ) ? semi
+ : ( brak != std::string_view::npos ) ? brak
+ : tmp.size();
return tmp.substr( 0, end );
}
@@ -13,6 +13,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263"
SRC_URI = "https://github.com/USBGuard/usbguard/releases/download/${BPN}-${PV}/${BPN}-${PV}.tar.gz \
file://0001-Add-and-use-pkgconfig-instead-of-libgcrypt-config.patch \
file://0001-PEGTL-fix-demangle-static_assert-with-GCC-16.patch \
"
SRC_URI[sha256sum] = "7d76b75e779e3c9e6c2fc10e7389dfa34056864c9f0c6eaca722687b7e75893c"