boostorg / bimap

Boost.org bimap module
http://boost.org/libs/bimap
20 stars 48 forks source link

allow MSVC mimicry by clang-based compilers #32

Closed ilatypov closed 2 years ago

ilatypov commented 2 years ago

MSVC-like compilers fail to process the older definitions BOOST_BIMAP_MAP_VIEW_BASE_FRIEND and BOOST_BIMAP_SET_VIEW_BASE_FRIEND but are forced into them by checks of the BOOST_MSVC auto-detected define.

Depending on the compiler, Boost defines the above macros to expand into an appropriate form of a friend class declaration. It has to sense the compiler because MSVC did not accept an instance of a template class as a friend "right away".

friend class tplclass<T>;

MSVC needed an additional typedef to make that work.

typedef tplclass<T> tplinstclass;
friend class tplinstclass;

One clang-based static analyzer mimics MSVC in many aspects but does not agree with the Boost work-around. It rejects the above Boost's work-around for MSVC because usage of a typedef-ed class name is not taking the class specifier.

include\boost/bimap/views/map_view.hpp:57:5: error: typedef 'friend_map_view_base' cannot be referenced with a class specifier
include\boost/bimap/views/set_view.hpp:56:5: error: typedef 'template_class_friend' cannot be referenced with a class specifier

I therefore suggest limiting the older friend class declaration to the older MSVC versions,

-#if defined(BOOST_MSVC)
+#if defined(BOOST_MSVC) && (_MSC_VER < 1910)

Alternatively, the typedef-ed name of kind tplinstclass can be used without the class specifier, that is, as friend tplinstclass in the existing BOOST_MSVC branch of the macro definitions. But this may break builds of Boost consumers with older MSVC compilers because those builds are unlikely to be tested with the change.

ilatypov commented 2 years ago

Never mind, an upcoming release of the analyzer will mimic MSVC fully in this regard.

RIscRIpt commented 1 year ago

Could this issue still be addressed? Because the current code for MSVC is ill-formed, and thus not accepted by clang-cl (see llvm/llvm-project#63217).