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.

Reply via email to