Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 6 Aug 2023 23:40:00 +0200
From:      Christoph Moench-Tegeder <cmt@burggraben.net>
To:        toolchain@freebsd.org
Subject:   c++: dynamic_cast woes
Message-ID:  <ZNATMN6sbaxcqE6n@elch.exwg.net>

next in thread | raw e-mail | index | archive | help
Hi,
while updating our kicad port I'm facing major problems with
dynamic_cast on FreeBSD 13.2/amd64 - issues are seen with both base
clang and devel/llvm15, and I guess we're rather talking libc++ here.
Specifically, dynamic_cast fails when casting from a base to a derived
type ("downcast" as in C++ lingo?). I already know about "--export-dynamic"
but that does not help here - and as far as I read other platform's
build scripts, no other platform requires any kind of "special
handling" for dynamic_cast to work - what am I holding wrong here,
or what's missing from the picture?

But for the gory details: here's exhibit A, the code in question:
https://gitlab.com/kicad/code/kicad/-/blob/7.0/include/settings/settings_manager.h?ref_type=heads#L110
That m_settings is declared as
 std::vector<std::unique_ptr<JSON_SETTINGS>> m_settings;
and contains objects of types derived from JSON_SETTINGS (there's
the intermediate type APP_SETTINGS_BASE, and specific types like
KICAD_SETTINGS etc.) The function GetAppSettings<KICAD_SETTING>() is
called, so that the find_if() in there should return that one
KICAD_SETTINGS object from m_settings as only that should
satisfy dynamic_cast - but in fact, no object is found.
That also happens if I unwind the find_if() and build a simple
for-loop (as one did, back in the last millenium).

If I point gdb at that m_settings (with "set print object on" and
"set print vtbl on"), I do find my KICAD_SETTINGS object smack
in the middle of m_settings:

(gdb) print *(m_settings[5])
$18 = (KICAD_SETTINGS) {<APP_SETTINGS_BASE> = {<JSON_SETTINGS> = {
      _vptr$JSON_SETTINGS = 0xed1578 <vtable for KICAD_SETTINGS+16>,

so the type info isn't totally lost here.

When testing this, CXXFLAGS passed via cmake are rather minimal,
like "-std=c++17 -O0 -fstack-protector-strong -fno-strict-aliasing
-Wl,--export-dynamic" (and cmake sprinkles some "-g" and a few
other standard flags into the mix), LDFLAGS ("CMAKE_...LINKER_FLAGS")
are set up similarly) (I have some inkling that these cmakefiles
in this project are not always very strict on compiling vs linking).

I had similar issues with dynamic_cast before, as witnessed here:
https://cgit.freebsd.org/ports/tree/cad/kicad/files/patch-job_use_dynamic_cast_for_updating
but now that I'm facing the current problem, I have a strong feeling
that my diagnosis back than was rather bullshit.

Help?

Thanks,
Christoph

-- 
Spare Space



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?ZNATMN6sbaxcqE6n>