https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124352
Bug ID: 124352
Summary: Forced inlining and constexpr combined change
diagnostics of ill-formed code
Product: gcc
Version: 16.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: ---
```
template <typename>
struct arg_store {
int data;
static constexpr int create() {
static_assert(false);
return 0;
}
#ifdef CONSTEXPR
constexpr
#endif
arg_store(auto&&) : data(create()) {}
};
#ifdef INLINE
[[__gnu__::__always_inline__]]
#endif
constexpr auto make_format_args(auto& arg) {
return arg_store<int>(arg);
}
struct S {};
void fn() {
S s;
(void)make_format_args(s);
}
```
This code is ill-formed, regardless whether `INLINE` or `CONSTEXPR` are
defined.
Consider 3 compilations, with flags:
1) "-std=c++26 -DCONSTEXPR -fdiagnostics-plain-output"
2) "-std=c++26 -DINLINE -fdiagnostics-plain-output"
3) "-std=c++26 -DINLINE -DCONSTEXPR -fdiagnostics-plain-output"
1 and 2 produce (near) identical diagnostics:
```
<source>: In instantiation of 'static constexpr int arg_store<
<template-parameter-1-1> >::create() [with <template-parameter-1-1> = int]':
<source>:13:34: required from '**constexpr** arg_store<
<template-parameter-1-1> >::arg_store(auto:1&&) [with auto:1 = S&;
<template-parameter-1-1> = int]'
<source>:20:10: required from 'constexpr auto make_format_args(auto:2&) [with
auto:2 = S]'
<source>:27:25: required from here
<source>:6:19: error: static assertion failed
<source>:6:19: note: 'false' evaluates to false
```
They only differ in the **constexpr** part.
3 produces significantly different diagnostic:
```
<source>: In instantiation of 'static constexpr int arg_store<
<template-parameter-1-1> >::create() [with <template-parameter-1-1> = int]':
<source>:13:34: required from here
<source>:27:25: in 'constexpr' expansion of 'make_format_args<S>(s)'
<source>:20:10: in 'constexpr' expansion of 'arg_store<int>((* & arg))'
<source>:6:19: error: static assertion failed
<source>:6:19: note: 'false' evaluates to false
```
The "required from here" is now pointing at a different line,
arg_store constructor instead of the preferred make_format_args function call.
Godbolt link showcasing the 3 compilations: https://godbolt.org/z/Tcvx4oWfo