// RUN: %check_clang_tidy %s bugprone-signed-char-misuse %t /////////////////////////////////////////////////////////////////// /// Test cases correctly caught by the check. typedef __SIZE_TYPE__ size_t; namespace std { template struct array { T &operator[](size_t n); T &at(size_t n); }; } // namespace std int SimpleVarDeclaration() { signed char CCharacter = -5; int NCharacter = CCharacter; // CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] return NCharacter; } int SimpleAssignment() { signed char CCharacter = -5; int NCharacter; NCharacter = CCharacter; // CHECK-MESSAGES: [[@LINE-1]]:16: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] return NCharacter; } int CStyleCast() { signed char CCharacter = -5; int NCharacter; NCharacter = (int)CCharacter; // CHECK-MESSAGES: [[@LINE-1]]:21: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] return NCharacter; } int StaticCast() { signed char CCharacter = -5; int NCharacter; NCharacter = static_cast(CCharacter); // CHECK-MESSAGES: [[@LINE-1]]:33: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] return NCharacter; } int FunctionalCast() { signed char CCharacter = -5; int NCharacter; NCharacter = int(CCharacter); // CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] return NCharacter; } int NegativeConstValue() { const signed char CCharacter = -5; int NCharacter = CCharacter; // CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] return NCharacter; } int CharPointer(signed char *CCharacter) { int NCharacter = *CCharacter; // CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] return NCharacter; } int SignedUnsignedCharEquality(signed char SCharacter) { unsigned char USCharacter = 'a'; if (SCharacter == USCharacter) // CHECK-MESSAGES: [[@LINE]]:7: warning: comparison between 'signed char' and 'unsigned char' [bugprone-signed-char-misuse] return 1; return 0; } int SignedUnsignedCharIneqiality(signed char SCharacter) { unsigned char USCharacter = 'a'; if (SCharacter != USCharacter) // CHECK-MESSAGES: [[@LINE]]:7: warning: comparison between 'signed char' and 'unsigned char' [bugprone-signed-char-misuse] return 1; return 0; } int CompareWithNonAsciiConstant(unsigned char USCharacter) { const signed char SCharacter = -5; if (USCharacter == SCharacter) // CHECK-MESSAGES: [[@LINE]]:7: warning: comparison between 'signed char' and 'unsigned char' [bugprone-signed-char-misuse] return 1; return 0; } int CompareWithUnsignedNonAsciiConstant(signed char SCharacter) { const unsigned char USCharacter = 128; if (USCharacter == SCharacter) // CHECK-MESSAGES: [[@LINE]]:7: warning: comparison between 'signed char' and 'unsigned char' [bugprone-signed-char-misuse] return 1; return 0; } int SignedCharCArraySubscript(signed char SCharacter) { int Array[3] = {1, 2, 3}; return Array[static_cast(SCharacter)]; // CHECK-MESSAGES: [[@LINE]]:42: warning: 'signed char' to 'unsigned int' conversion in array subscript; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] } int SignedCharSTDArraySubscript(std::array Array, signed char SCharacter) { return Array[static_cast(SCharacter)]; // CHECK-MESSAGES: [[@LINE]]:42: warning: 'signed char' to 'unsigned int' conversion in array subscript; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] } /////////////////////////////////////////////////////////////////// /// Test cases correctly ignored by the check. int UnsignedCharCast() { unsigned char CCharacter = 'a'; int NCharacter = CCharacter; return NCharacter; } int PositiveConstValue() { const signed char CCharacter = 5; int NCharacter = CCharacter; return NCharacter; } // singed char -> integer cast is not the direct child of declaration expression. int DescendantCast() { signed char CCharacter = 'a'; int NCharacter = 10 + CCharacter; return NCharacter; } // singed char -> integer cast is not the direct child of assignment expression. int DescendantCastAssignment() { signed char CCharacter = 'a'; int NCharacter; NCharacter = 10 + CCharacter; return NCharacter; } // bool is an integer type in clang; make sure to ignore it. bool BoolVarDeclaration() { signed char CCharacter = 'a'; bool BCharacter = CCharacter == 'b'; return BCharacter; } // bool is an integer type in clang; make sure to ignore it. bool BoolAssignment() { signed char CCharacter = 'a'; bool BCharacter; BCharacter = CCharacter == 'b'; return BCharacter; } // char is an integer type in clang; make sure to ignore it. unsigned char CharToCharCast() { signed char SCCharacter = 'a'; unsigned char USCharacter; USCharacter = SCCharacter; return USCharacter; } int FixComparisonWithSignedCharCast(signed char SCharacter) { unsigned char USCharacter = 'a'; if (SCharacter == static_cast(USCharacter)) return 1; return 0; } int FixComparisonWithUnSignedCharCast(signed char SCharacter) { unsigned char USCharacter = 'a'; if (static_cast(SCharacter) == USCharacter) return 1; return 0; } // Make sure we don't catch other type of char comparison. int SameCharTypeComparison(signed char SCharacter) { signed char SCharacter2 = 'a'; if (SCharacter == SCharacter2) return 1; return 0; } // Make sure we don't catch other type of char comparison. int SameCharTypeComparison2(unsigned char USCharacter) { unsigned char USCharacter2 = 'a'; if (USCharacter == USCharacter2) return 1; return 0; } // Make sure we don't catch integer - char comparison. int CharIntComparison(signed char SCharacter) { int ICharacter = 10; if (SCharacter == ICharacter) return 1; return 0; } int CompareWithAsciiLiteral(unsigned char USCharacter) { if (USCharacter == 'x') // no warning return 1; return 0; } int CompareWithAsciiConstant(unsigned char USCharacter) { const signed char SCharacter = 'a'; if (USCharacter == SCharacter) return 1; return 0; } int CompareWithUnsignedAsciiConstant(signed char SCharacter) { const unsigned char USCharacter = 'a'; if (USCharacter == SCharacter) return 1; return 0; } int UnsignedCharCArraySubscript(unsigned char USCharacter) { int Array[3] = {1, 2, 3}; return Array[static_cast(USCharacter)]; } int CastedCArraySubscript(signed char SCharacter) { int Array[3] = {1, 2, 3}; return Array[static_cast(SCharacter)]; } int UnsignedCharSTDArraySubscript(std::array Array, unsigned char USCharacter) { return Array[static_cast(USCharacter)]; } int CastedSTDArraySubscript(std::array Array, signed char SCharacter) { return Array[static_cast(SCharacter)]; }