codeql-coding-standards icon indicating copy to clipboard operation
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

Open rcseacord opened this issue 2 years ago • 0 comments

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';
}

rcseacord avatar Sep 23 '22 17:09 rcseacord