codeql-coding-standards
codeql-coding-standards copied to clipboard
`M2-13-3`: Fails to test for octal and binary literals and literals of different types such a L or LL
Affected rules
- M2-13-3
Description
The test here:
https://github.com/github/codeql-coding-standards/blob/main/cpp/autosar/test/rules/M2-13-3/test.cpp
Is overly simple and fails to test for octal and binary literals, or literals with a type suffix such a L or LL. Notice also that the non-decimal integer literals will switch between signed and unsigned types as their size increases, so there are several different ranges of unsigned values.
void test_unsigned_literals_without_suffix() {
0xFFFFFFFFU; // COMPLIANT - literal explicitly marked as unsigned
0xFFFFFFFF; // NON_COMPLIANT - literal is too large for a signed int, so has
// type unsigned int
}
Example
Add some more tests:
Here is a an example that includes code to print the type of the integer literals:
#include <iostream>
#include <string_view>
template <typename T>
constexpr auto type_name() {
std::string_view name, prefix, suffix;
#ifdef __clang__
name = __PRETTY_FUNCTION__;
prefix = "auto type_name() [T = ";
suffix = "]";
#elif defined(__GNUC__)
name = __PRETTY_FUNCTION__;
prefix = "constexpr auto type_name() [with T = ";
suffix = "]";
#elif defined(_MSC_VER)
name = __FUNCSIG__;
prefix = "auto __cdecl type_name<";
suffix = ">(void)";
#endif
name.remove_prefix(prefix.size());
name.remove_suffix(suffix.size());
return name;
}
int main() {
auto v1 = 2'147'483'647;
std::cout << "decltype(v1) is " << type_name<decltype(v1)>() << '\n';
auto v2 = 2'147'483'648;
std::cout << "decltype(v2) is " << type_name<decltype(v2)>() << '\n';
auto v3 = 32'768L;
std::cout << "decltype(v3) is " << type_name<decltype(v3)>() << '\n';
auto v4a = 0x7FFFFFFF;
std::cout << "decltype(v4a) is " << type_name<decltype(v4a)>() << '\n';
auto v4b = 0xFFFFFFFF; // NON-COMPLIANT
std::cout << "decltype(v4b) is " << type_name<decltype(v4b)>() << '\n';
auto v4b1 = 0x1FFFFFFFF; // NON-COMPLIANT - can't be represented as a int
std::cout << "decltype(v4b1) is " << type_name<decltype(v4b1)>() << '\n';
auto v4c = 0x7FFFFFFFFFFFFFFF;
std::cout << "decltype(v4c) is " << type_name<decltype(v4c)>() << '\n';
auto v4d = 0xFFFFFFFFFFFFFFFF;
std::cout << "decltype(v4d) is " << type_name<decltype(v4d)>() << '\n';
/*
auto v4e = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
std::cout << "decltype(v4e) is " << type_name<decltype(v4e)>() << '\n';
auto v4f = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
std::cout << "decltype(v4f) is " << type_name<decltype(v4f)>() << '\n';
*/
auto v5 = -2'147'483'648;
std::cout << "decltype(v5) is " << type_name<decltype(v5)>() << '\n';
auto v5p = -v5;
std::cout << "decltype(v5p) is " << type_name<decltype(v5p)>() << '\n';
auto v5q = -2'147'483'647 - 1;
std::cout << "decltype(v5q) is " << type_name<decltype(v5q)>() << '\n';
auto v5r = (int)-2'147'483'648;
std::cout << "decltype(v5r) is " << type_name<decltype(v5r)>() << '\n';
auto v6 = 037'777'777'777; // NON-COMPLIANT
std::cout << "decltype(v6) is " << type_name<decltype(v6)>() << '\n';
auto v7 = 017'777'777'777;
std::cout << "decltype(v7) is " << type_name<decltype(v7)>() << '\n';
auto v8 = 0b1111'1111'1111'1111'1111'1111'1111'1111; // Non-compliant
std::cout << "decltype(v8) is " << type_name<decltype(v8)>() << '\n';
auto v9 = 0b0111'1111'1111'1111'1111'1111'1111'1111;
std::cout << "decltype(v9) is " << type_name<decltype(v9)>() << '\n';
}