https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127537
Bug ID: 127537
Summary: nondeterministic compilation related to reflection
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: ivan.lazaric.gcc at gmail dot com
Target Milestone: ---
```cpp
namespace fmt::inline v12 {
template<class> struct Y;
template<class> class parse_context;
inline namespace detail {
template<class Context>
struct value {
void (*f)(void*, parse_context<int>&, Context&);
template<class T>
static constexpr void format_custom(void*, parse_context<typename
Context::char_type>&, Context&) {
Y<T>().f();
}
template<class T>
constexpr value(T&) { f = format_custom<T>; }
};
}
struct context { using char_type = int; };
template<class T> using at = value<T>;
struct fas { at<context> a; };
inline auto f(auto&&... a) { fas{a...}; }
using R = decltype(^^int);
template<>
struct Y<R> { consteval void f(); };
constexpr auto b(int, auto... a) { f(a...); }
consteval { b(0, ^^int); }
}
```
Store this file as `prog.ii` so it gets recognized as `c++-cpp-output`,
or add `-xc++-cpp-output` to compilation flags.
Flags: "-fimplicit-constexpr -std=c++29 -freflection -fsyntax-only"
If we try to compile this multiple times, we get different outcomes.
Outcome 1:
```
prog.ii:29:30: warning: inline function 'consteval void
fmt::v12::Y<std::meta::info>::f()' used but never defined
29 | struct Y<R> { consteval void f(); };
| ^
EXIT CODE: 0
```
Outcome 2:
```
prog.ii:29:30: warning: inline function 'consteval void
fmt::v12::Y<std::meta::info>::f()' used but never defined
29 | struct Y<R> { consteval void f(); };
| ^
prog.ii: In function 'auto fmt::v12::f(auto:1&& ...) [with auto:1 =
{std::meta::info&}]':
prog.ii:25:30: error: call to consteval function
'fmt::v12::detail::value<fmt::v12::context>(a#0)' is not a constant expression
25 | inline auto f(auto&&... a) { fas{a...}; }
| ^~~
prog.ii:25:30: error: immediate evaluation returns address of immediate
function 'static constexpr void
fmt::v12::detail::value<Context>::format_custom(void*,
fmt::v12::parse_context<typename Context::char_type>&, Context&) [with T =
std::meta::info; Context = fmt::v12::context; typename Context::char_type =
int]'
prog.ii:25:30: note: 'constexpr fmt::v12::detail::value<Context>::value(T&)
[with T = std::meta::info; Context = fmt::v12::context]' was promoted to an
immediate function
EXIT CODE: 1
```
Distribution between them is around 50/50.
If instead we store it as `prog.cpp` (or `-xc++`),
distribution becomes around 85/15.
Godbolt: https://godbolt.org/z/T9n81Yc49
At bottom of compiler window there is a "recompile" button,
click multiple times to observe this nondeterminism.