Skip to content

Instantly share code, notes, and snippets.

@jwtowner
Created December 1, 2018 02:49
Show Gist options
  • Save jwtowner/7d38d8e2d238e9fa87abc91226bd095f to your computer and use it in GitHub Desktop.
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
#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