-
-
Save jwtowner/7d38d8e2d238e9fa87abc91226bd095f to your computer and use it in GitHub Desktop.
More C26495 false positives in MSVC++ 15.9.3 with templated delegating constructors and anonymous unions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdint> | |
#include <array> | |
#include <iostream> | |
#include <type_traits> | |
// Below, we get C26495 false positive with a templated constructor delegating | |
// to another constructor. A non-templated constructor delegating to another | |
// constructor does not generate the false positive. | |
template <int N> | |
struct Enumeration | |
{ | |
int value; | |
template <int I> | |
struct Enumerator : std::integral_constant<int, I> {}; | |
constexpr Enumeration( int x ) noexcept | |
: value{ x } {} | |
constexpr Enumeration( double x ) noexcept | |
: Enumeration{ static_cast<int>( x ) } {} | |
template <int I, | |
std::enable_if_t<( -1 <= I ) && ( I < N ), int> = 0> | |
constexpr Enumeration( Enumerator<I> ) noexcept // warning C26495: Variable 'Enumeration<5>::value' is uninitialized. Always initialize a member variable (type.6). | |
: Enumeration{ I } {} | |
}; | |
enum class AddressFamily : std::uint16_t { IPv4, IPv6 }; | |
inline std::ostream& operator<<( std::ostream& out, AddressFamily family ) | |
{ | |
return ( out << ( ( family == AddressFamily::IPv6 ) ? "IPv6" : "IPv4" ) ); | |
} | |
// Below, we get a C26495 false positive with an anonymous union, even though | |
// one of the union members was initialized. C26495 should likely only be | |
// generated by the analyzer when it detects that no union members were initialized. | |
struct IPAddress | |
{ | |
struct V4Data | |
{ | |
std::uint32_t address; | |
}; | |
struct V6Data | |
{ | |
std::uint32_t flowInfo; | |
std::array<std::uint8_t, 16> address; | |
std::uint32_t scopeId; | |
}; | |
AddressFamily family; | |
std::uint16_t port; | |
union { | |
V4Data v4; | |
V6Data v6; | |
}; | |
constexpr IPAddress( std::uint32_t addr, std::uint16_t port ) noexcept // warning C26495: Variable 'IPAddress::<anonymous-tag>::v6' is uninitialized. Always initialize a member variable (type.6). | |
: family{ AddressFamily::IPv4 } | |
, port{ port } | |
, v4{ addr } {} | |
constexpr IPAddress( const std::array<std::uint8_t, 16>& addr, std::uint16_t port ) noexcept | |
: IPAddress{ addr, 0u, port } {} | |
constexpr IPAddress( const std::array<std::uint8_t, 16>& addr, std::uint32_t scopeId, std::uint16_t port ) noexcept // warning C26495: Variable 'IPAddress::<anonymous-tag>::v4' is uninitialized. Always initialize a member variable (type.6). | |
: family{ AddressFamily::IPv6 } | |
, port{ port } | |
, v6{ 0, addr, scopeId } {} | |
}; | |
int main() | |
{ | |
using CustomEnum = Enumeration<5>; | |
constexpr CustomEnum e1{ 1 }; | |
constexpr CustomEnum e2{ 2.4 }; | |
constexpr CustomEnum e3{ CustomEnum::Enumerator<3>{} }; | |
std::cout << e1.value << ", " << e2.value << ", " << e3.value << "\n"; | |
constexpr IPAddress a1{ 0xa7000001, 8080 }; | |
constexpr IPAddress a2{ { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1 }, 8080 }; | |
std::cout << a1.family << ", " << a2.family << "\n"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment