Skip to content

Commit 5eb083b

Browse files
committed
rules-qt: warn() walks the message by index, because gcc 16 refuses to inline the iterator here
The range-for walked a `std::string` through `__gnu_cxx::__normal_iterator`, whose `operator*` and `operator++` are `always_inline` and reach this module from the `std` module. Once this file imported one module more, gcc 16.1.0 refused both: error: inlining failed in call to 'always_inline' 'constexpr __gnu_cxx::__normal_iterator<...>::operator*() const' note: called from here for (char c : message) in `warn@mcpp.rules.qt` alone, while every other range-for in the collection compiled. Measured on this machine with `MCPP_TOOLCHAIN=gcc@16.1.0`: two errors before, none after, and the qt consumer builds. An index touches no iterator, so it does not depend on what a BMI carries across a module boundary -- the same hazard class the engine records for a clang 20.1.7 crash, where the error names a file the change never touched.
1 parent 141f416 commit 5eb083b

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

‎rules/qt.cppm‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,26 @@ inline std::filesystem::path absolute_from_root(const std::string& p) {
129129
return path.lexically_normal();
130130
}
131131

132+
// INDEXED, NOT A RANGE-FOR, FOR A COMPILER REASON (gcc 16.1.0, 0.19.0). The
133+
// range-for walked a `std::string` through `__gnu_cxx::__normal_iterator`, whose
134+
// `operator*` and `operator++` are `always_inline` and reach this module from
135+
// the `std` module. Once this file imported one module more, gcc refused both:
136+
//
137+
// error: inlining failed in call to 'always_inline'
138+
// 'constexpr __gnu_cxx::__normal_iterator<...>::operator*() const'
139+
// note: called from here for (char c : message)
140+
//
141+
// in `warn@mcpp.rules.qt` alone, while every other range-for in the collection
142+
// compiled. An index touches no iterator, so it does not depend on what a BMI
143+
// carries across a module boundary. The same hazard class is on record in the
144+
// engine (a clang 20.1.7 crash from an exported `std::pair` specialization): the
145+
// error names a file the change never touched.
132146
inline void warn(const std::string& message) {
133147
std::cerr << message << '\n';
134148
std::string folded;
135149
bool space = false;
136-
for (char c : message) {
150+
for (std::size_t i = 0; i < message.size(); ++i) {
151+
const char c = message[i];
137152
if (c == '\n') { space = true; continue; }
138153
if (space) { if (c == ' ') continue; folded += ' '; space = false; }
139154
folded += c;

0 commit comments

Comments
 (0)