https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127750
Bug ID: 127750
Summary: [17 Regression] Lambda in polymorphic typeid operand
mangled with wrong discriminator (undocumented ABI
break vs 16)
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: ABI, wrong-code
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: gabravier at gmail dot com
CC: vladislav.semykin at gmail dot com
Target Milestone: ---
#include <typeinfo>
struct B { virtual ~B(); }; // polymorphic -> typeid operand is
evaluated -> reparse
inline auto g(B* p) {
(void)typeid(*[&]{ return p; }()); // lambda inside the probed/reparsed
operand
}
void use(B* p) {
g(p);
}
Compiling this code with GCC 16.2 (and -O0) emits a function symbol named:
_ZZ1gP1BENKUlvE_clEv (g(B*)::{lambda()#1}::operator()() const)
GCC trunk:
_ZZ1gP1BENKUlvE0_clEv (g(B*)::{lambda()#2}::operator()() const)
The latter seems incorrect, since the Itanium ABI would expect that the first
lambda with the signature "()" (which this is) be UlvE_, AIUI. In particular,
it appears to rather directly be an ABI break (both are currently on ABI
20/__GXX_ABI_VERSION == 1020).
I am not particularly certain but my *guess* is that r17-2200-g621661f7d2e915
is the cause. This in particular looks quite suspect to me:
+ if (expression != error_mark_node
+ && processing_template_decl == 0
+ && !cp_unevaluated_operand
+ && typeid_evaluated_p (expression))
+ {
+ /* Re-parse the operand evaluated so the /4 side-effects occur.
+ The unevaluated pass above called no mark_used and captured
+ nothing, so rolling back has nothing to undo. */
+ cp_lexer_rollback_tokens (parser->lexer);
+ expression = cp_parser_expression (parser, &idk);
+ }
...because I would have to imagine that lambda expression must surely have
rather elaborate parse-time side effects (the closure type, the discriminator,
etc.). This could, perchance, result in every lambda in an evaluated typeid
operand being numbered twice (at least, that is my analysis :))
...although I haven't actually tested that this is the particular commit that
causes the issue, nor am I sufficiently an expert in C++ to be able to say so
definitely.