From 9fa5cb207fd9a5c21fc45727402dc7d1b41ddc2c Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Thu, 10 Jul 2025 14:25:31 -0700 Subject: [PATCH 01/11] Add more test cases - 1. Assigning a char to another char - 1-1. Assigning a char to a char variable - 1-2. Assigning a char to a char member - 1-3. Assigning a char to a char through a pointer - 2. Passing a char argument to a char parameter - 2-1. Passing char argument to a char parameter of a regular function - 2-2. Passing char argument to a char parameter through a template - 2-3. Passing a char argument to a char parameter through a template --- cpp/autosar/test/rules/M5-0-12/test.cpp | 363 +++++++++++++++++++++++- 1 file changed, 353 insertions(+), 10 deletions(-) diff --git a/cpp/autosar/test/rules/M5-0-12/test.cpp b/cpp/autosar/test/rules/M5-0-12/test.cpp index 453c37bf1e..355c9cbc4f 100644 --- a/cpp/autosar/test/rules/M5-0-12/test.cpp +++ b/cpp/autosar/test/rules/M5-0-12/test.cpp @@ -1,16 +1,359 @@ #include -void f1() { - unsigned char a1 = 'c'; // NON_COMPLIANT - unsigned char a2 = 10; - signed char a3 = 'c'; // NON_COMPLIANT - signed char a4 = 10; +template class C1 { +public: + C1() : x(y) {} - std::int8_t a5 = 'c'; // NON_COMPLIANT - std::int8_t a6 = 10; +private: + unsigned char x; +}; - std::uint8_t a7 = 'c'; // NON_COMPLIANT - std::uint8_t a8 = 10; +template class C2 { +public: + C2() : x(y) {} - char a9 = 'c'; +private: + signed char x; +}; + +template class C3 { +public: + C3() : x(y) {} + +private: + unsigned char x; +}; + +template class C4 { +public: + C4() : x(y) {} + +private: + signed char x; +}; + +/* Twin templates for std::uint8_t and std::int8_t */ +template class C9 { +public: + C9() : x(y) {} + +private: + std::uint8_t x; +}; + +template class C10 { +public: + C10() : x(y) {} + +private: + std::int8_t x; +}; + +template class C11 { +public: + C11() : x(y) {} + +private: + std::uint8_t x; +}; + +template class C12 { +public: + C12() : x(y) {} + +private: + std::int8_t x; +}; + +void f1(unsigned char x) {} +void f2(signed char x) {} +void f3(unsigned char x) {} +void f4(signed char x) {} + +/* Twin functions for std::uint8_t and std::int8_t */ +void f9(std::uint8_t x) {} +void f10(std::int8_t x) {} +void f11(std::uint8_t x) {} +void f12(std::int8_t x) {} + +template void f5(T x) { unsigned char y = x; } +template void f6(T x) { signed char y = x; } +template void f7(T x) { signed char y = x; } +template void f8(T x) { signed char y = x; } + +/* Twin template functions for std::uint8_t and std::int8_t */ +template void f13(T x) { std::uint8_t y = x; } +template void f14(T x) { std::int8_t y = x; } +template void f15(T x) { std::int8_t y = x; } +template void f16(T x) { std::int8_t y = x; } + +template class C5 { +public: + C5(T y) : x(y) {} + +private: + unsigned char x; +}; + +template class C6 { +public: + C6(T y) : x(y) {} + +private: + signed char x; +}; + +template class C7 { +public: + C7(T y) : x(y) {} + +private: + signed char x; +}; + +template class C8 { +public: + C8(T y) : x(y) {} + +private: + signed char x; +}; + +/* Twin template classes for std::uint8_t and std::int8_t */ +template class C13 { +public: + C13(T y) : x(y) {} + +private: + std::uint8_t x; +}; + +template class C14 { +public: + C14(T y) : x(y) {} + +private: + std::int8_t x; +}; + +template class C15 { +public: + C15(T y) : x(y) {} + +private: + std::int8_t x; +}; + +template class C16 { +public: + C16(T y) : x(y) {} + +private: + std::int8_t x; +}; + +int main() { + + /* ========== 1. Assigning a char to another char ========== */ + + /* ===== 1-1. Assigning a char to a char variable ===== */ + + unsigned char x1 = 1; + unsigned char y1 = + x1; // COMPLIANT: unsigned char assigned to an unsigned char + + signed char x2 = 1; + signed char y2 = x2; // COMPLIANT: signed char assigned to a signed char + + char x3 = 'x'; + unsigned char y3 = x3; // NON-COMPLIANT: plain char assigned to a unsigned char + + char x4 = 'x'; + signed char y4 = x4; // NON-COMPLIANT: plain char assigned to a signed char + + /* Twin cases with std::uint8_t and std::int8_t */ + std::uint8_t x5 = 1; + std::uint8_t y5 = + x5; // COMPLIANT: std::uint8_t assigned to a std::uint8_t + + std::int8_t x6 = 1; + std::int8_t y6 = x6; // COMPLIANT: std::int8_t assigned to a std::int8_t + + char x7 = 'x'; + std::uint8_t y7 = x7; // NON-COMPLIANT: plain char assigned to a std::uint8_t + + char x8 = 'x'; + std::int8_t y8 = x8; // NON-COMPLIANT: plain char assigned to a std::int8_t + + /* ===== 1-2. Assigning a char to a char member ===== */ + + C1 c1; // COMPLIANT: unsigned char arg passed to an unsigned + // char member through a template + + C2 c2; // COMPLIANT: signed char arg passed to a signed char + // member through a template + + C3 c3; // NON-COMPLIANT: plain char arg passed to a unsigned char + // member through a template + + C4 c4; // NON-COMPLIANT: plain char arg passed to a signed char + // member through a template + + /* Twin cases with std::uint8_t and std::int8_t */ + C9 c9; // COMPLIANT: std::uint8_t arg passed to a std::uint8_t + // member through a template + + C10 c10; // COMPLIANT: std::int8_t arg passed to a std::int8_t + // member through a template + + C11 c11; // NON-COMPLIANT: plain char arg passed to a std::uint8_t + // member through a template + + C12 c12; // NON-COMPLIANT: plain char arg passed to a std::int8_t + // member through a template + + /* ========== 1-3. Assigning a char to a char through a pointer ========== */ + + unsigned char x9 = 1; + unsigned char *y9 = &x9; + signed char z1 = + *y9; // COMPLIANT: unsigned char assigned to a *&unsigned char + + unsigned char x10 = 1; + unsigned char *y10 = &x10; + signed char z2 = *y10; // COMPLIANT: signed char assigned to an *&signed char + + char x11 = 1; + char *y11 = &x11; + unsigned char z3 = + *y11; // NON-COMPLIANT: plain char assigned to an *&unsigned char + + char x12 = 1; + char *y12 = &x12; + signed char z4 = + *y12; // NON-COMPLIANT: plain char assigned to an *&signed char + + /* Twin cases with std::uint8_t and std::int8_t */ + std::uint8_t x13 = 1; + std::uint8_t *y13 = &x13; + std::int8_t z5 = + *y13; // COMPLIANT: std::uint8_t assigned to a *&std::uint8_t + + std::uint8_t x14 = 1; + std::uint8_t *y14 = &x14; + std::int8_t z6 = *y14; // COMPLIANT: std::int8_t assigned to an *&std::int8_t + + char x15 = 1; + char *y15 = &x15; + std::uint8_t z7 = + *y15; // NON-COMPLIANT: plain char assigned to an *&std::uint8_t + + char x16 = 1; + char *y16 = &x16; + std::int8_t z8 = + *y16; // NON-COMPLIANT: plain char assigned to an *&std::int8_t + + /* ========== 2. Passing a char argument to a char parameter ========== */ + + /* ===== 2-1. Passing char argument to a char parameter of a regular function + * ===== */ + + unsigned char a1 = 1; + f1(a1); // COMPLIANT: unsigned char arg passed to an unsigned char parameter + + signed char a2 = 1; + f2(a2); // COMPLIANT: signed char arg passed to a signed char parameter + + char a3 = 'a'; + f3(a3); // NON-COMPLIANT: plain char arg passed to a unsigned char parameter + + char a4 = 'a'; + f4(a4); // NON-COMPLIANT: plain char arg passed to a signed char parameter + + /* Twin cases with std::uint8_t and std::int8_t */ + std::uint8_t a5 = 1; + f9(a5); // COMPLIANT: std::uint8_t arg passed to a std::uint8_t parameter + + std::int8_t a6 = 1; + f10(a6); // COMPLIANT: std::int8_t arg passed to a std::int8_t parameter + + char a7 = 'a'; + f11(a7); // NON-COMPLIANT: plain char arg passed to a std::uint8_t parameter + + char a8 = 'a'; + f12(a8); // NON-COMPLIANT: plain char arg passed to a std::int8_t parameter + + /* ===== 2-2. Passing char argument to a char parameter through a template + * ===== */ + + unsigned char a9 = 'a'; + f5(a9); // COMPLIANT: unsigned char arg passed to an unsigned char parameter + // through a template + + signed char a10 = 'a'; + f6(a10); // COMPLIANT: signed char arg passed to a signed char parameter + // through a template + + char a11 = 'a'; + f7(a11); // NON-COMPLIANT: plain char arg passed to a unsigned char parameter + // through a template + + char a12 = 'a'; + f8(a12); // COMPLIANT: plain char arg passed to a signed char parameter through + // a template + + /* Twin cases with std::uint8_t and std::int8_t */ + std::uint8_t a13 = 'a'; + f13(a13); // COMPLIANT: std::uint8_t arg passed to a std::uint8_t parameter + // through a template + + std::int8_t a14 = 'a'; + f14(a14); // COMPLIANT: std::int8_t arg passed to a std::int8_t parameter + // through a template + + char a15 = 'a'; + f15(a15); // NON-COMPLIANT: plain char arg passed to a std::uint8_t parameter + // through a template + + char a16 = 'a'; + f16(a16); // COMPLIANT: plain char arg passed to a std::int8_t parameter through + // a template + + /* ========== 2-3. Passing a char argument to a char parameter through a + * template ========== */ + + unsigned char a17 = 1; + C5 c5( + a17); // COMPLIANT: unsigned char arg passed to an unsigned char parameter + // of a constructor through a template + + signed char a18 = 1; + C6 c6(a18); // COMPLIANT: signed char arg passed to an signed + // char parameter of a constructor through a template + + char a19 = 'a'; + C7 c7(a19); // NON-COMPLIANT: plain char arg passed to an unsigned char + // parameter of a constructor through a template + + char a20 = 'a'; + C8 c8(a20); // NON-COMPLIANT: plain char arg passed to an signed char + // parameter of a constructor through a template + + /* Twin cases with std::uint8_t and std::int8_t */ + std::uint8_t a21 = 1; + C13 c13( + a21); // COMPLIANT: std::uint8_t arg passed to a std::uint8_t parameter + // of a constructor through a template + + std::int8_t a22 = 1; + C14 c14(a22); // COMPLIANT: std::int8_t arg passed to a std::int8_t + // parameter of a constructor through a template + + char a23 = 'a'; + C15 c15(a23); // NON-COMPLIANT: plain char arg passed to a std::uint8_t + // parameter of a constructor through a template + + char a24 = 'a'; + C16 c16(a24); // NON-COMPLIANT: plain char arg passed to a std::int8_t + // parameter of a constructor through a template } \ No newline at end of file From fb544876bb2ce448934362c7ce5ce495803a807c Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Thu, 10 Jul 2025 14:39:44 -0700 Subject: [PATCH 02/11] Renumber definitions and objects, and fix wrong labels --- cpp/autosar/test/rules/M5-0-12/test.cpp | 70 ++++++++++++------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/cpp/autosar/test/rules/M5-0-12/test.cpp b/cpp/autosar/test/rules/M5-0-12/test.cpp index 355c9cbc4f..57530dae16 100644 --- a/cpp/autosar/test/rules/M5-0-12/test.cpp +++ b/cpp/autosar/test/rules/M5-0-12/test.cpp @@ -33,33 +33,33 @@ template class C4 { }; /* Twin templates for std::uint8_t and std::int8_t */ -template class C9 { +template class C5 { public: - C9() : x(y) {} + C5() : x(y) {} private: std::uint8_t x; }; -template class C10 { +template class C6 { public: - C10() : x(y) {} + C6() : x(y) {} private: std::int8_t x; }; -template class C11 { +template class C7 { public: - C11() : x(y) {} + C7() : x(y) {} private: std::uint8_t x; }; -template class C12 { +template class C8 { public: - C12() : x(y) {} + C8() : x(y) {} private: std::int8_t x; @@ -87,33 +87,33 @@ template void f14(T x) { std::int8_t y = x; } template void f15(T x) { std::int8_t y = x; } template void f16(T x) { std::int8_t y = x; } -template class C5 { +template class C9 { public: - C5(T y) : x(y) {} + C9(T y) : x(y) {} private: unsigned char x; }; -template class C6 { +template class C10 { public: - C6(T y) : x(y) {} + C10(T y) : x(y) {} private: signed char x; }; -template class C7 { +template class C11 { public: - C7(T y) : x(y) {} + C11(T y) : x(y) {} private: signed char x; }; -template class C8 { +template class C12 { public: - C8(T y) : x(y) {} + C12(T y) : x(y) {} private: signed char x; @@ -200,27 +200,27 @@ int main() { // member through a template /* Twin cases with std::uint8_t and std::int8_t */ - C9 c9; // COMPLIANT: std::uint8_t arg passed to a std::uint8_t + C5 c5; // COMPLIANT: std::uint8_t arg passed to a std::uint8_t // member through a template - C10 c10; // COMPLIANT: std::int8_t arg passed to a std::int8_t + C6 c6; // COMPLIANT: std::int8_t arg passed to a std::int8_t // member through a template - C11 c11; // NON-COMPLIANT: plain char arg passed to a std::uint8_t + C7 c7; // NON-COMPLIANT: plain char arg passed to a std::uint8_t // member through a template - C12 c12; // NON-COMPLIANT: plain char arg passed to a std::int8_t + C8 c8; // NON-COMPLIANT: plain char arg passed to a std::int8_t // member through a template /* ========== 1-3. Assigning a char to a char through a pointer ========== */ unsigned char x9 = 1; unsigned char *y9 = &x9; - signed char z1 = + unsigned char z1 = *y9; // COMPLIANT: unsigned char assigned to a *&unsigned char - unsigned char x10 = 1; - unsigned char *y10 = &x10; + signed char x10 = 1; + signed char *y10 = &x10; signed char z2 = *y10; // COMPLIANT: signed char assigned to an *&signed char char x11 = 1; @@ -236,11 +236,11 @@ int main() { /* Twin cases with std::uint8_t and std::int8_t */ std::uint8_t x13 = 1; std::uint8_t *y13 = &x13; - std::int8_t z5 = + std::uint8_t z5 = *y13; // COMPLIANT: std::uint8_t assigned to a *&std::uint8_t - std::uint8_t x14 = 1; - std::uint8_t *y14 = &x14; + std::int8_t x14 = 1; + std::int8_t *y14 = &x14; std::int8_t z6 = *y14; // COMPLIANT: std::int8_t assigned to an *&std::int8_t char x15 = 1; @@ -295,11 +295,11 @@ int main() { // through a template char a11 = 'a'; - f7(a11); // NON-COMPLIANT: plain char arg passed to a unsigned char parameter + f7(a11); // NON-COMPLIANT: plain char arg passed to a signed char parameter // through a template char a12 = 'a'; - f8(a12); // COMPLIANT: plain char arg passed to a signed char parameter through + f8(a12); // NON-COMPLIANT: plain char arg passed to a signed char parameter through // a template /* Twin cases with std::uint8_t and std::int8_t */ @@ -312,31 +312,31 @@ int main() { // through a template char a15 = 'a'; - f15(a15); // NON-COMPLIANT: plain char arg passed to a std::uint8_t parameter + f15(a15); // NON-COMPLIANT: plain char arg passed to a std::int8_t parameter // through a template char a16 = 'a'; - f16(a16); // COMPLIANT: plain char arg passed to a std::int8_t parameter through + f16(a16); // NON-COMPLIANT: plain char arg passed to a std::int8_t parameter through // a template /* ========== 2-3. Passing a char argument to a char parameter through a * template ========== */ unsigned char a17 = 1; - C5 c5( + C9 c9( a17); // COMPLIANT: unsigned char arg passed to an unsigned char parameter // of a constructor through a template signed char a18 = 1; - C6 c6(a18); // COMPLIANT: signed char arg passed to an signed + C10 c10(a18); // COMPLIANT: signed char arg passed to an signed // char parameter of a constructor through a template char a19 = 'a'; - C7 c7(a19); // NON-COMPLIANT: plain char arg passed to an unsigned char + C11 c11(a19); // NON-COMPLIANT: plain char arg passed to a signed char // parameter of a constructor through a template char a20 = 'a'; - C8 c8(a20); // NON-COMPLIANT: plain char arg passed to an signed char + C12 c12(a20); // NON-COMPLIANT: plain char arg passed to an signed char // parameter of a constructor through a template /* Twin cases with std::uint8_t and std::int8_t */ @@ -350,7 +350,7 @@ int main() { // parameter of a constructor through a template char a23 = 'a'; - C15 c15(a23); // NON-COMPLIANT: plain char arg passed to a std::uint8_t + C15 c15(a23); // NON-COMPLIANT: plain char arg passed to a std::int8_t // parameter of a constructor through a template char a24 = 'a'; From 808b5fd13a620c6401af427b676d871861f9b6a5 Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Thu, 10 Jul 2025 14:56:37 -0700 Subject: [PATCH 03/11] Fix cases 1. Change signed char / int8_t case to their opposites. 2. Assign a numeral to the unsigned char / signed char than a character. --- cpp/autosar/test/rules/M5-0-12/test.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cpp/autosar/test/rules/M5-0-12/test.cpp b/cpp/autosar/test/rules/M5-0-12/test.cpp index 57530dae16..99cb995854 100644 --- a/cpp/autosar/test/rules/M5-0-12/test.cpp +++ b/cpp/autosar/test/rules/M5-0-12/test.cpp @@ -78,13 +78,13 @@ void f12(std::int8_t x) {} template void f5(T x) { unsigned char y = x; } template void f6(T x) { signed char y = x; } -template void f7(T x) { signed char y = x; } +template void f7(T x) { unsigned char y = x; } template void f8(T x) { signed char y = x; } /* Twin template functions for std::uint8_t and std::int8_t */ template void f13(T x) { std::uint8_t y = x; } template void f14(T x) { std::int8_t y = x; } -template void f15(T x) { std::int8_t y = x; } +template void f15(T x) { std::uint8_t y = x; } template void f16(T x) { std::int8_t y = x; } template class C9 { @@ -286,16 +286,16 @@ int main() { /* ===== 2-2. Passing char argument to a char parameter through a template * ===== */ - unsigned char a9 = 'a'; + unsigned char a9 = 1; f5(a9); // COMPLIANT: unsigned char arg passed to an unsigned char parameter // through a template - signed char a10 = 'a'; + signed char a10 = 1; f6(a10); // COMPLIANT: signed char arg passed to a signed char parameter // through a template char a11 = 'a'; - f7(a11); // NON-COMPLIANT: plain char arg passed to a signed char parameter + f7(a11); // NON-COMPLIANT: plain char arg passed to an unsigned char parameter // through a template char a12 = 'a'; @@ -303,16 +303,16 @@ int main() { // a template /* Twin cases with std::uint8_t and std::int8_t */ - std::uint8_t a13 = 'a'; + std::uint8_t a13 = 1; f13(a13); // COMPLIANT: std::uint8_t arg passed to a std::uint8_t parameter // through a template - std::int8_t a14 = 'a'; + std::int8_t a14 = 1; f14(a14); // COMPLIANT: std::int8_t arg passed to a std::int8_t parameter // through a template char a15 = 'a'; - f15(a15); // NON-COMPLIANT: plain char arg passed to a std::int8_t parameter + f15(a15); // NON-COMPLIANT: plain char arg passed to a std::uint8_t parameter // through a template char a16 = 'a'; From 80029970d8bf7f242cb4de49e8b0a3c3bbbf9c6e Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Fri, 11 Jul 2025 16:43:26 -0700 Subject: [PATCH 04/11] Add a working draft of the query --- ...eUsedForTheStorageAndUseOfNumericValues.ql | 207 ++++++++++++++++-- 1 file changed, 189 insertions(+), 18 deletions(-) diff --git a/cpp/autosar/src/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.ql b/cpp/autosar/src/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.ql index 3b6e436c56..7ffc47e50f 100644 --- a/cpp/autosar/src/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.ql +++ b/cpp/autosar/src/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.ql @@ -16,23 +16,194 @@ import cpp import codingstandards.cpp.autosar -from Variable v, Expr aexp +newtype TTemplatedElement = + TClassTemplate(TemplateClass c) or + TFunctionTemplate(TemplateFunction f) or + TVariableTemplate(TemplateVariable v) + +class TemplatedElement extends TTemplatedElement { + TemplateClass asTemplateClass() { this = TClassTemplate(result) } + + TemplateFunction asTemplateFunction() { this = TFunctionTemplate(result) } + + TemplateVariable asTemplateVariable() { this = TVariableTemplate(result) } + + string toString() { + result = this.asTemplateClass().toString() or + result = this.asTemplateFunction().toString() or + result = this.asTemplateVariable().toString() + } + + Location getLocation() { + result = this.asTemplateClass().getLocation() or + result = this.asTemplateFunction().getLocation() or + result = this.asTemplateVariable().getLocation() + } + + string getName() { + result = this.asTemplateClass().getName() or + result = this.asTemplateFunction().getName() or + result = this.asTemplateVariable().getName() + } +} + +newtype TTemplateInstantiation = + TClassTemplateInstantiation(ClassTemplateInstantiation c) or + TFunctionTemplateInstantiation(FunctionTemplateInstantiation f) or + TVariableTemplateInstantiation(VariableTemplateInstantiation v) + +class TemplateInstantiation extends TTemplateInstantiation { + ClassTemplateInstantiation asClassTemplateInstantiation() { + this = TClassTemplateInstantiation(result) + } + + FunctionTemplateInstantiation asFunctionTemplateInstantiation() { + this = TFunctionTemplateInstantiation(result) + } + + VariableTemplateInstantiation asVariableTemplateInstantiation() { + this = TVariableTemplateInstantiation(result) + } + + string toString() { + result = this.asClassTemplateInstantiation().toString() or + result = this.asFunctionTemplateInstantiation().toString() or + result = this.asVariableTemplateInstantiation().toString() + } + + Location getLocation() { + result = this.asClassTemplateInstantiation().getLocation() or + result = this.asFunctionTemplateInstantiation().getLocation() or + result = this.asVariableTemplateInstantiation().getLocation() + } + + Element asElement() { + result = this.asClassTemplateInstantiation() or + result = this.asFunctionTemplateInstantiation() or + result = this.asVariableTemplateInstantiation() + } + + TemplatedElement getTemplate() { + result.asTemplateClass() = this.asClassTemplateInstantiation().getTemplate() or + result.asTemplateFunction() = this.asFunctionTemplateInstantiation().getTemplate() or + result.asTemplateVariable() = this.asVariableTemplateInstantiation().getTemplate() + } + + /** + * Gets a use of an instantiation of this template. i.e. + * 1. For a class template, it's where the instantiated type is used by the name. + * 2. For a function template, it's where the instantiated function is called. + * 3. For a variable template, it's where the instantiated variable is initialized. + */ + Element getAUse() { + result = this.asClassTemplateInstantiation().getATypeNameUse() or + result = this.asFunctionTemplateInstantiation().getACallToThisFunction() or + result = this.asVariableTemplateInstantiation() + } +} + +class ImplicitConversionFromPlainCharType extends Conversion { + ImplicitConversionFromPlainCharType() { + this.isImplicit() and + this.getExpr().getUnspecifiedType() instanceof PlainCharType and + ( + this.getUnspecifiedType() instanceof SignedCharType or + this.getUnspecifiedType() instanceof UnsignedCharType + ) + } +} + +newtype TImplicitConversionElement = + TImplicitConversionOutsideTemplate(ImplicitConversionFromPlainCharType implicitConversion) { + not exists(TemplateInstantiation instantiation | + implicitConversion.isFromTemplateInstantiation(instantiation.asElement()) + ) + } or + TInstantiationOfImplicitConversionTemplate( + TemplateInstantiation templateInstantiation, + ImplicitConversionFromPlainCharType implicitConversion + ) { + implicitConversion.getEnclosingElement+() = templateInstantiation.asElement() + } + +class ImplicitConversionLocation extends TImplicitConversionElement { + ImplicitConversionFromPlainCharType asImplicitConversionOutsideTemplate() { + this = TImplicitConversionOutsideTemplate(result) + } + + TemplateInstantiation asInstantiationOfImplicitConversionTemplate( + ImplicitConversionFromPlainCharType implicitConversion + ) { + this = TInstantiationOfImplicitConversionTemplate(result, implicitConversion) + } + + predicate isImplicitConversionOutsideTemplate() { + exists(this.asImplicitConversionOutsideTemplate()) + } + + predicate isInstantiationOfImplicitConversionTemplate() { + exists( + TemplateInstantiation templateInstantiation, + ImplicitConversionFromPlainCharType implicitConversion + | + templateInstantiation = this.asInstantiationOfImplicitConversionTemplate(implicitConversion) + ) + } + + ImplicitConversionFromPlainCharType getImplicitConversion() { + result = this.asImplicitConversionOutsideTemplate() or + exists(TemplateInstantiation templateInstantiation | + this = TInstantiationOfImplicitConversionTemplate(templateInstantiation, result) + ) + } + + string toString() { + result = this.asImplicitConversionOutsideTemplate().toString() or + exists(ImplicitConversionFromPlainCharType implicitConversion | + result = this.asInstantiationOfImplicitConversionTemplate(implicitConversion).toString() + ) + } + + Location getLocation() { + result = this.asImplicitConversionOutsideTemplate().getLocation() or + exists(ImplicitConversionFromPlainCharType implicitConversion | + result = this.asInstantiationOfImplicitConversionTemplate(implicitConversion).getLocation() + ) + } + + Element asElement() { + result = this.asImplicitConversionOutsideTemplate() or + exists(ImplicitConversionFromPlainCharType implicitConversion | + result = this.asInstantiationOfImplicitConversionTemplate(implicitConversion).getAUse() + ) + } +} + +string getMessageTemplate(ImplicitConversionLocation implicitConversionLocation) { + exists(ImplicitConversionFromPlainCharType implicitConversion | + implicitConversion = implicitConversionLocation.getImplicitConversion() + | + implicitConversionLocation.isImplicitConversionOutsideTemplate() and + result = + "Implicit conversion of plain char $@ to " + implicitConversion.getType().getName() + "." + or + implicitConversionLocation.isInstantiationOfImplicitConversionTemplate() and + result = + "Implicit conversion of plain char $@ to " + implicitConversion.getType().getName() + + " from instantiating template '" + + implicitConversionLocation + .asInstantiationOfImplicitConversionTemplate(implicitConversion) + .getTemplate() + .getName() + "'." + ) +} + +from + ImplicitConversionLocation implicitConversionLocation, + ImplicitConversionFromPlainCharType implicitConversion where - not isExcluded(v, + not isExcluded(implicitConversionLocation.asElement(), StringsPackage::signedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValuesQuery()) and - // We find cases where it is an explicitly signed char type with an assignment - // to a non-numeric type. NOTE: This rule addresses cases where the char type - // is used character data only, the rule does not explicitly cover this. - // Please see M5-0-11 for explicit handling of this case. Get types that are - // char, except for ones that are 'plain', meaning the sign is explicit. - ( - v.getUnspecifiedType() instanceof SignedCharType or - v.getUnspecifiedType() instanceof UnsignedCharType - ) and - // Identify places where these explicitly signed types are being assigned to a - // non-numeric type. - aexp = v.getAnAssignedValue() and - aexp.getUnspecifiedType() instanceof CharType -select aexp, - "Assignment of an non-integer type to variable $@ which is a variable with an explicitly signed char type", - v, v.getName() + implicitConversion = implicitConversionLocation.getImplicitConversion() +select implicitConversionLocation.asElement(), getMessageTemplate(implicitConversionLocation), + implicitConversion.getExpr(), "expression" From 2ed4443c02d8e1b31cf2058d8321e61d99573a92 Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Mon, 14 Jul 2025 10:01:00 -0400 Subject: [PATCH 05/11] Deduplicate the test cases and update the expected results. --- ...orTheStorageAndUseOfNumericValues.expected | 28 +++- cpp/autosar/test/rules/M5-0-12/test.cpp | 121 +++++------------- 2 files changed, 54 insertions(+), 95 deletions(-) diff --git a/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected b/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected index 1be5b7b9fc..cafd6c64b2 100644 --- a/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected +++ b/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected @@ -1,4 +1,24 @@ -| test.cpp:4:22:4:24 | 99 | Assignment of an non-integer type to variable $@ which is a variable with an explicitly signed char type | test.cpp:4:17:4:18 | a1 | a1 | -| test.cpp:6:20:6:22 | 99 | Assignment of an non-integer type to variable $@ which is a variable with an explicitly signed char type | test.cpp:6:15:6:16 | a3 | a3 | -| test.cpp:9:20:9:22 | 99 | Assignment of an non-integer type to variable $@ which is a variable with an explicitly signed char type | test.cpp:9:15:9:16 | a5 | a5 | -| test.cpp:12:21:12:23 | 99 | Assignment of an non-integer type to variable $@ which is a variable with an explicitly signed char type | test.cpp:12:16:12:17 | a7 | a7 | +| test.cpp:106:7:106:8 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:106:7:106:8 | x3 | expression | +| test.cpp:109:20:109:21 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:109:20:109:21 | x4 | expression | +| test.cpp:119:21:119:22 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:119:21:119:22 | x7 | expression | +| test.cpp:122:20:122:21 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:122:20:122:21 | x8 | expression | +| test.cpp:132:17:132:18 | definition of c3 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'C1'. | test.cpp:5:12:5:12 | 120 | expression | +| test.cpp:135:17:135:18 | definition of c4 | Implicit conversion of plain char $@ to signed char from instantiating template 'C2'. | test.cpp:13:12:13:12 | 120 | expression | +| test.cpp:145:15:145:16 | definition of c7 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'C5'. | test.cpp:22:12:22:12 | 1 | expression | +| test.cpp:148:15:148:16 | definition of c8 | Implicit conversion of plain char $@ to int8_t from instantiating template 'C6'. | test.cpp:30:12:30:12 | 1 | expression | +| test.cpp:165:7:165:10 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:165:7:165:10 | * ... | expression | +| test.cpp:170:7:170:10 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:170:7:170:10 | * ... | expression | +| test.cpp:185:7:185:10 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:185:7:185:10 | * ... | expression | +| test.cpp:190:7:190:10 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:190:7:190:10 | * ... | expression | +| test.cpp:204:6:204:7 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:204:6:204:7 | a3 | expression | +| test.cpp:207:6:207:7 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:207:6:207:7 | a4 | expression | +| test.cpp:217:7:217:8 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:217:7:217:8 | a7 | expression | +| test.cpp:220:7:220:8 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:220:7:220:8 | a8 | expression | +| test.cpp:234:3:234:4 | call to f7 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'f7'. | test.cpp:49:56:49:56 | x | expression | +| test.cpp:238:3:238:4 | call to f8 | Implicit conversion of plain char $@ to signed char from instantiating template 'f8'. | test.cpp:50:54:50:54 | x | expression | +| test.cpp:251:3:251:5 | call to f15 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'f15'. | test.cpp:55:56:55:56 | x | expression | +| test.cpp:255:3:255:5 | call to f16 | Implicit conversion of plain char $@ to int8_t from instantiating template 'f16'. | test.cpp:56:55:56:55 | x | expression | +| test.cpp:272:12:272:14 | definition of c11 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'C9'. | test.cpp:60:15:60:15 | y | expression | +| test.cpp:277:13:277:15 | definition of c12 | Implicit conversion of plain char $@ to signed char from instantiating template 'C10'. | test.cpp:68:16:68:16 | y | expression | +| test.cpp:292:13:292:15 | definition of c15 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'C13'. | test.cpp:77:16:77:16 | y | expression | +| test.cpp:296:13:296:15 | definition of c16 | Implicit conversion of plain char $@ to int8_t from instantiating template 'C14'. | test.cpp:85:16:85:16 | y | expression | diff --git a/cpp/autosar/test/rules/M5-0-12/test.cpp b/cpp/autosar/test/rules/M5-0-12/test.cpp index 99cb995854..91106b8211 100644 --- a/cpp/autosar/test/rules/M5-0-12/test.cpp +++ b/cpp/autosar/test/rules/M5-0-12/test.cpp @@ -16,22 +16,6 @@ template class C2 { signed char x; }; -template class C3 { -public: - C3() : x(y) {} - -private: - unsigned char x; -}; - -template class C4 { -public: - C4() : x(y) {} - -private: - signed char x; -}; - /* Twin templates for std::uint8_t and std::int8_t */ template class C5 { public: @@ -49,22 +33,6 @@ template class C6 { std::int8_t x; }; -template class C7 { -public: - C7() : x(y) {} - -private: - std::uint8_t x; -}; - -template class C8 { -public: - C8() : x(y) {} - -private: - std::int8_t x; -}; - void f1(unsigned char x) {} void f2(signed char x) {} void f3(unsigned char x) {} @@ -103,22 +71,6 @@ template class C10 { signed char x; }; -template class C11 { -public: - C11(T y) : x(y) {} - -private: - signed char x; -}; - -template class C12 { -public: - C12(T y) : x(y) {} - -private: - signed char x; -}; - /* Twin template classes for std::uint8_t and std::int8_t */ template class C13 { public: @@ -136,22 +88,6 @@ template class C14 { std::int8_t x; }; -template class C15 { -public: - C15(T y) : x(y) {} - -private: - std::int8_t x; -}; - -template class C16 { -public: - C16(T y) : x(y) {} - -private: - std::int8_t x; -}; - int main() { /* ========== 1. Assigning a char to another char ========== */ @@ -166,15 +102,15 @@ int main() { signed char y2 = x2; // COMPLIANT: signed char assigned to a signed char char x3 = 'x'; - unsigned char y3 = x3; // NON-COMPLIANT: plain char assigned to a unsigned char + unsigned char y3 = + x3; // NON-COMPLIANT: plain char assigned to a unsigned char char x4 = 'x'; signed char y4 = x4; // NON-COMPLIANT: plain char assigned to a signed char /* Twin cases with std::uint8_t and std::int8_t */ std::uint8_t x5 = 1; - std::uint8_t y5 = - x5; // COMPLIANT: std::uint8_t assigned to a std::uint8_t + std::uint8_t y5 = x5; // COMPLIANT: std::uint8_t assigned to a std::uint8_t std::int8_t x6 = 1; std::int8_t y6 = x6; // COMPLIANT: std::int8_t assigned to a std::int8_t @@ -193,24 +129,24 @@ int main() { C2 c2; // COMPLIANT: signed char arg passed to a signed char // member through a template - C3 c3; // NON-COMPLIANT: plain char arg passed to a unsigned char + C1 c3; // NON-COMPLIANT: plain char arg passed to a unsigned char // member through a template - C4 c4; // NON-COMPLIANT: plain char arg passed to a signed char + C2 c4; // NON-COMPLIANT: plain char arg passed to a signed char // member through a template /* Twin cases with std::uint8_t and std::int8_t */ - C5 c5; // COMPLIANT: std::uint8_t arg passed to a std::uint8_t - // member through a template + C5 c5; // COMPLIANT: std::uint8_t arg passed to a + // std::uint8_t member through a template C6 c6; // COMPLIANT: std::int8_t arg passed to a std::int8_t - // member through a template + // member through a template - C7 c7; // NON-COMPLIANT: plain char arg passed to a std::uint8_t - // member through a template + C5 c7; // NON-COMPLIANT: plain char arg passed to a + // std::uint8_t member through a template - C8 c8; // NON-COMPLIANT: plain char arg passed to a std::int8_t - // member through a template + C6 c8; // NON-COMPLIANT: plain char arg passed to a std::int8_t + // member through a template /* ========== 1-3. Assigning a char to a char through a pointer ========== */ @@ -299,8 +235,8 @@ int main() { // through a template char a12 = 'a'; - f8(a12); // NON-COMPLIANT: plain char arg passed to a signed char parameter through - // a template + f8(a12); // NON-COMPLIANT: plain char arg passed to a signed char parameter + // through a template /* Twin cases with std::uint8_t and std::int8_t */ std::uint8_t a13 = 1; @@ -316,8 +252,8 @@ int main() { // through a template char a16 = 'a'; - f16(a16); // NON-COMPLIANT: plain char arg passed to a std::int8_t parameter through - // a template + f16(a16); // NON-COMPLIANT: plain char arg passed to a std::int8_t parameter + // through a template /* ========== 2-3. Passing a char argument to a char parameter through a * template ========== */ @@ -328,16 +264,18 @@ int main() { // of a constructor through a template signed char a18 = 1; - C10 c10(a18); // COMPLIANT: signed char arg passed to an signed - // char parameter of a constructor through a template + C10 c10( + a18); // COMPLIANT: signed char arg passed to an signed + // char parameter of a constructor through a template char a19 = 'a'; - C11 c11(a19); // NON-COMPLIANT: plain char arg passed to a signed char - // parameter of a constructor through a template + C9 c11( + a19); // NON-COMPLIANT: plain char arg passed to a unsigned signed char + // parameter of a constructor through a template char a20 = 'a'; - C12 c12(a20); // NON-COMPLIANT: plain char arg passed to an signed char - // parameter of a constructor through a template + C10 c12(a20); // NON-COMPLIANT: plain char arg passed to an signed char + // parameter of a constructor through a template /* Twin cases with std::uint8_t and std::int8_t */ std::uint8_t a21 = 1; @@ -346,14 +284,15 @@ int main() { // of a constructor through a template std::int8_t a22 = 1; - C14 c14(a22); // COMPLIANT: std::int8_t arg passed to a std::int8_t - // parameter of a constructor through a template + C14 c14( + a22); // COMPLIANT: std::int8_t arg passed to a std::int8_t + // parameter of a constructor through a template char a23 = 'a'; - C15 c15(a23); // NON-COMPLIANT: plain char arg passed to a std::int8_t + C13 c15(a23); // NON-COMPLIANT: plain char arg passed to a std::uint8_t // parameter of a constructor through a template char a24 = 'a'; - C16 c16(a24); // NON-COMPLIANT: plain char arg passed to a std::int8_t + C14 c16(a24); // NON-COMPLIANT: plain char arg passed to a std::int8_t // parameter of a constructor through a template -} \ No newline at end of file +} From 11a277f4289d3be792c3c74c34966f703873b2f8 Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Mon, 14 Jul 2025 10:23:11 -0400 Subject: [PATCH 06/11] Deduplicate more test cases and fix expected results --- ...orTheStorageAndUseOfNumericValues.expected | 48 +++++++++---------- cpp/autosar/test/rules/M5-0-12/test.cpp | 24 ++++------ 2 files changed, 32 insertions(+), 40 deletions(-) diff --git a/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected b/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected index cafd6c64b2..d5dc9af7e8 100644 --- a/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected +++ b/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected @@ -1,24 +1,24 @@ -| test.cpp:106:7:106:8 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:106:7:106:8 | x3 | expression | -| test.cpp:109:20:109:21 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:109:20:109:21 | x4 | expression | -| test.cpp:119:21:119:22 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:119:21:119:22 | x7 | expression | -| test.cpp:122:20:122:21 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:122:20:122:21 | x8 | expression | -| test.cpp:132:17:132:18 | definition of c3 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'C1'. | test.cpp:5:12:5:12 | 120 | expression | -| test.cpp:135:17:135:18 | definition of c4 | Implicit conversion of plain char $@ to signed char from instantiating template 'C2'. | test.cpp:13:12:13:12 | 120 | expression | -| test.cpp:145:15:145:16 | definition of c7 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'C5'. | test.cpp:22:12:22:12 | 1 | expression | -| test.cpp:148:15:148:16 | definition of c8 | Implicit conversion of plain char $@ to int8_t from instantiating template 'C6'. | test.cpp:30:12:30:12 | 1 | expression | -| test.cpp:165:7:165:10 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:165:7:165:10 | * ... | expression | -| test.cpp:170:7:170:10 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:170:7:170:10 | * ... | expression | -| test.cpp:185:7:185:10 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:185:7:185:10 | * ... | expression | -| test.cpp:190:7:190:10 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:190:7:190:10 | * ... | expression | -| test.cpp:204:6:204:7 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:204:6:204:7 | a3 | expression | -| test.cpp:207:6:207:7 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:207:6:207:7 | a4 | expression | -| test.cpp:217:7:217:8 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:217:7:217:8 | a7 | expression | -| test.cpp:220:7:220:8 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:220:7:220:8 | a8 | expression | -| test.cpp:234:3:234:4 | call to f7 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'f7'. | test.cpp:49:56:49:56 | x | expression | -| test.cpp:238:3:238:4 | call to f8 | Implicit conversion of plain char $@ to signed char from instantiating template 'f8'. | test.cpp:50:54:50:54 | x | expression | -| test.cpp:251:3:251:5 | call to f15 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'f15'. | test.cpp:55:56:55:56 | x | expression | -| test.cpp:255:3:255:5 | call to f16 | Implicit conversion of plain char $@ to int8_t from instantiating template 'f16'. | test.cpp:56:55:56:55 | x | expression | -| test.cpp:272:12:272:14 | definition of c11 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'C9'. | test.cpp:60:15:60:15 | y | expression | -| test.cpp:277:13:277:15 | definition of c12 | Implicit conversion of plain char $@ to signed char from instantiating template 'C10'. | test.cpp:68:16:68:16 | y | expression | -| test.cpp:292:13:292:15 | definition of c15 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'C13'. | test.cpp:77:16:77:16 | y | expression | -| test.cpp:296:13:296:15 | definition of c16 | Implicit conversion of plain char $@ to int8_t from instantiating template 'C14'. | test.cpp:85:16:85:16 | y | expression | +| test.cpp:98:7:98:8 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:98:7:98:8 | x3 | expression | +| test.cpp:101:20:101:21 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:101:20:101:21 | x4 | expression | +| test.cpp:111:21:111:22 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:111:21:111:22 | x7 | expression | +| test.cpp:114:20:114:21 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:114:20:114:21 | x8 | expression | +| test.cpp:124:17:124:18 | definition of c3 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'C1'. | test.cpp:5:12:5:12 | 120 | expression | +| test.cpp:127:17:127:18 | definition of c4 | Implicit conversion of plain char $@ to signed char from instantiating template 'C2'. | test.cpp:13:12:13:12 | 120 | expression | +| test.cpp:137:15:137:16 | definition of c7 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'C5'. | test.cpp:22:12:22:12 | 1 | expression | +| test.cpp:140:15:140:16 | definition of c8 | Implicit conversion of plain char $@ to int8_t from instantiating template 'C6'. | test.cpp:30:12:30:12 | 1 | expression | +| test.cpp:157:7:157:10 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:157:7:157:10 | * ... | expression | +| test.cpp:162:7:162:10 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:162:7:162:10 | * ... | expression | +| test.cpp:177:7:177:10 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:177:7:177:10 | * ... | expression | +| test.cpp:182:7:182:10 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:182:7:182:10 | * ... | expression | +| test.cpp:196:6:196:7 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:196:6:196:7 | a3 | expression | +| test.cpp:199:6:199:7 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:199:6:199:7 | a4 | expression | +| test.cpp:209:6:209:7 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:209:6:209:7 | a7 | expression | +| test.cpp:212:7:212:8 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:212:7:212:8 | a8 | expression | +| test.cpp:226:3:226:4 | call to f5 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'f5'. | test.cpp:43:56:43:56 | x | expression | +| test.cpp:230:3:230:4 | call to f6 | Implicit conversion of plain char $@ to signed char from instantiating template 'f6'. | test.cpp:44:54:44:54 | x | expression | +| test.cpp:243:3:243:5 | call to f13 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'f13'. | test.cpp:47:56:47:56 | x | expression | +| test.cpp:247:3:247:5 | call to f14 | Implicit conversion of plain char $@ to int8_t from instantiating template 'f14'. | test.cpp:48:55:48:55 | x | expression | +| test.cpp:264:12:264:14 | definition of c11 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'C9'. | test.cpp:52:15:52:15 | y | expression | +| test.cpp:269:13:269:15 | definition of c12 | Implicit conversion of plain char $@ to signed char from instantiating template 'C10'. | test.cpp:60:16:60:16 | y | expression | +| test.cpp:284:13:284:15 | definition of c15 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'C13'. | test.cpp:69:16:69:16 | y | expression | +| test.cpp:288:13:288:15 | definition of c16 | Implicit conversion of plain char $@ to int8_t from instantiating template 'C14'. | test.cpp:77:16:77:16 | y | expression | diff --git a/cpp/autosar/test/rules/M5-0-12/test.cpp b/cpp/autosar/test/rules/M5-0-12/test.cpp index 91106b8211..9687743402 100644 --- a/cpp/autosar/test/rules/M5-0-12/test.cpp +++ b/cpp/autosar/test/rules/M5-0-12/test.cpp @@ -35,25 +35,17 @@ template class C6 { void f1(unsigned char x) {} void f2(signed char x) {} -void f3(unsigned char x) {} -void f4(signed char x) {} /* Twin functions for std::uint8_t and std::int8_t */ void f9(std::uint8_t x) {} void f10(std::int8_t x) {} -void f11(std::uint8_t x) {} -void f12(std::int8_t x) {} template void f5(T x) { unsigned char y = x; } template void f6(T x) { signed char y = x; } -template void f7(T x) { unsigned char y = x; } -template void f8(T x) { signed char y = x; } /* Twin template functions for std::uint8_t and std::int8_t */ template void f13(T x) { std::uint8_t y = x; } template void f14(T x) { std::int8_t y = x; } -template void f15(T x) { std::uint8_t y = x; } -template void f16(T x) { std::int8_t y = x; } template class C9 { public: @@ -201,10 +193,10 @@ int main() { f2(a2); // COMPLIANT: signed char arg passed to a signed char parameter char a3 = 'a'; - f3(a3); // NON-COMPLIANT: plain char arg passed to a unsigned char parameter + f1(a3); // NON-COMPLIANT: plain char arg passed to a unsigned char parameter char a4 = 'a'; - f4(a4); // NON-COMPLIANT: plain char arg passed to a signed char parameter + f2(a4); // NON-COMPLIANT: plain char arg passed to a signed char parameter /* Twin cases with std::uint8_t and std::int8_t */ std::uint8_t a5 = 1; @@ -214,10 +206,10 @@ int main() { f10(a6); // COMPLIANT: std::int8_t arg passed to a std::int8_t parameter char a7 = 'a'; - f11(a7); // NON-COMPLIANT: plain char arg passed to a std::uint8_t parameter + f9(a7); // NON-COMPLIANT: plain char arg passed to a std::uint8_t parameter char a8 = 'a'; - f12(a8); // NON-COMPLIANT: plain char arg passed to a std::int8_t parameter + f10(a8); // NON-COMPLIANT: plain char arg passed to a std::int8_t parameter /* ===== 2-2. Passing char argument to a char parameter through a template * ===== */ @@ -231,11 +223,11 @@ int main() { // through a template char a11 = 'a'; - f7(a11); // NON-COMPLIANT: plain char arg passed to an unsigned char parameter + f5(a11); // NON-COMPLIANT: plain char arg passed to an unsigned char parameter // through a template char a12 = 'a'; - f8(a12); // NON-COMPLIANT: plain char arg passed to a signed char parameter + f6(a12); // NON-COMPLIANT: plain char arg passed to a signed char parameter // through a template /* Twin cases with std::uint8_t and std::int8_t */ @@ -248,11 +240,11 @@ int main() { // through a template char a15 = 'a'; - f15(a15); // NON-COMPLIANT: plain char arg passed to a std::uint8_t parameter + f13(a15); // NON-COMPLIANT: plain char arg passed to a std::uint8_t parameter // through a template char a16 = 'a'; - f16(a16); // NON-COMPLIANT: plain char arg passed to a std::int8_t parameter + f14(a16); // NON-COMPLIANT: plain char arg passed to a std::int8_t parameter // through a template /* ========== 2-3. Passing a char argument to a char parameter through a From 10c3a2c08ab66c1a5749195367b7426b9ba7e44d Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Mon, 14 Jul 2025 10:59:06 -0400 Subject: [PATCH 07/11] Minor label editing --- cpp/autosar/test/rules/M5-0-12/test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cpp/autosar/test/rules/M5-0-12/test.cpp b/cpp/autosar/test/rules/M5-0-12/test.cpp index 9687743402..0fe008436c 100644 --- a/cpp/autosar/test/rules/M5-0-12/test.cpp +++ b/cpp/autosar/test/rules/M5-0-12/test.cpp @@ -121,7 +121,7 @@ int main() { C2 c2; // COMPLIANT: signed char arg passed to a signed char // member through a template - C1 c3; // NON-COMPLIANT: plain char arg passed to a unsigned char + C1 c3; // NON-COMPLIANT: plain char arg passed to an unsigned char // member through a template C2 c4; // NON-COMPLIANT: plain char arg passed to a signed char @@ -145,7 +145,7 @@ int main() { unsigned char x9 = 1; unsigned char *y9 = &x9; unsigned char z1 = - *y9; // COMPLIANT: unsigned char assigned to a *&unsigned char + *y9; // COMPLIANT: unsigned char assigned to an *&unsigned char signed char x10 = 1; signed char *y10 = &x10; @@ -193,7 +193,7 @@ int main() { f2(a2); // COMPLIANT: signed char arg passed to a signed char parameter char a3 = 'a'; - f1(a3); // NON-COMPLIANT: plain char arg passed to a unsigned char parameter + f1(a3); // NON-COMPLIANT: plain char arg passed to an unsigned char parameter char a4 = 'a'; f2(a4); // NON-COMPLIANT: plain char arg passed to a signed char parameter @@ -262,7 +262,7 @@ int main() { char a19 = 'a'; C9 c11( - a19); // NON-COMPLIANT: plain char arg passed to a unsigned signed char + a19); // NON-COMPLIANT: plain char arg passed to an unsigned signed char // parameter of a constructor through a template char a20 = 'a'; From 20a30ccc108c6a781b28b917e9edb729ef94b892 Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Mon, 14 Jul 2025 10:59:21 -0400 Subject: [PATCH 08/11] Attach docstrings to query elements --- ...eUsedForTheStorageAndUseOfNumericValues.ql | 61 ++++++++++++++++--- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/cpp/autosar/src/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.ql b/cpp/autosar/src/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.ql index 7ffc47e50f..b81cf2dc64 100644 --- a/cpp/autosar/src/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.ql +++ b/cpp/autosar/src/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.ql @@ -16,17 +16,21 @@ import cpp import codingstandards.cpp.autosar -newtype TTemplatedElement = - TClassTemplate(TemplateClass c) or - TFunctionTemplate(TemplateFunction f) or - TVariableTemplate(TemplateVariable v) +newtype TTemplateElement = + TTemplateClass(TemplateClass c) or + TTemplateFunction(TemplateFunction f) or + TTemplateVariable(TemplateVariable v) -class TemplatedElement extends TTemplatedElement { - TemplateClass asTemplateClass() { this = TClassTemplate(result) } +/** + * A templated element. These are either templated classes, templated functions, + * or templated variables. + */ +class TemplateElement extends TTemplateElement { + TemplateClass asTemplateClass() { this = TTemplateClass(result) } - TemplateFunction asTemplateFunction() { this = TFunctionTemplate(result) } + TemplateFunction asTemplateFunction() { this = TTemplateFunction(result) } - TemplateVariable asTemplateVariable() { this = TVariableTemplate(result) } + TemplateVariable asTemplateVariable() { this = TTemplateVariable(result) } string toString() { result = this.asTemplateClass().toString() or @@ -52,6 +56,10 @@ newtype TTemplateInstantiation = TFunctionTemplateInstantiation(FunctionTemplateInstantiation f) or TVariableTemplateInstantiation(VariableTemplateInstantiation v) +/** + * An instantiation of a templated element, either a templated class, templated + * function, or templated variable. + */ class TemplateInstantiation extends TTemplateInstantiation { ClassTemplateInstantiation asClassTemplateInstantiation() { this = TClassTemplateInstantiation(result) @@ -83,7 +91,11 @@ class TemplateInstantiation extends TTemplateInstantiation { result = this.asVariableTemplateInstantiation() } - TemplatedElement getTemplate() { + /** + * Gets the template this instantiation is from, depending on the kind of the element + * this instantiation is for. + */ + TemplateElement getTemplate() { result.asTemplateClass() = this.asClassTemplateInstantiation().getTemplate() or result.asTemplateFunction() = this.asFunctionTemplateInstantiation().getTemplate() or result.asTemplateVariable() = this.asVariableTemplateInstantiation().getTemplate() @@ -102,6 +114,13 @@ class TemplateInstantiation extends TTemplateInstantiation { } } +/** + * An implicit conversion from a plain char type to an explicitly signed or unsigned char + * type. `std::uint8_t` and `std::int8_t` are also considered as these char types. + * + * Note that this class only includes implicit conversions and does not include explicit + * type conversions, i.e. casts. + */ class ImplicitConversionFromPlainCharType extends Conversion { ImplicitConversionFromPlainCharType() { this.isImplicit() and @@ -126,6 +145,16 @@ newtype TImplicitConversionElement = implicitConversion.getEnclosingElement+() = templateInstantiation.asElement() } +/** + * The locations where the implicit conversion from a plain char to an explicitly signed / unsigned + * char is taking place on a high level. It splits case on whether the conversion is caused by + * instantiating a template: + * + * - For conversions not due to template usage (i.e. outside a templated element), this refers to + * the same element as the one associated with the conversion. + * - For conversions due to template usage, this refers to the element that uses the instantiation + * of a template where an implicit char conversion happens. + */ class ImplicitConversionLocation extends TImplicitConversionElement { ImplicitConversionFromPlainCharType asImplicitConversionOutsideTemplate() { this = TImplicitConversionOutsideTemplate(result) @@ -137,10 +166,17 @@ class ImplicitConversionLocation extends TImplicitConversionElement { this = TInstantiationOfImplicitConversionTemplate(result, implicitConversion) } + /** + * Holds if this is a location of a conversion happening outside of a template. + */ predicate isImplicitConversionOutsideTemplate() { exists(this.asImplicitConversionOutsideTemplate()) } + /** + * Holds if this is a location of a conversion happening due to instantiating a + * template. + */ predicate isInstantiationOfImplicitConversionTemplate() { exists( TemplateInstantiation templateInstantiation, @@ -150,6 +186,13 @@ class ImplicitConversionLocation extends TImplicitConversionElement { ) } + /** + * Gets the implicit conversion that this location is associated with. + * - In cases of conversions not involving a template, this is the same as the + * location associated with the conversion. + * - In cases of conversions due to using a template, this is the conversion that + * happens in the instantiated template. + */ ImplicitConversionFromPlainCharType getImplicitConversion() { result = this.asImplicitConversionOutsideTemplate() or exists(TemplateInstantiation templateInstantiation | From f3cee16926b6b78f14da4680e8c5b10a052f0fed Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Mon, 14 Jul 2025 11:13:11 -0400 Subject: [PATCH 09/11] Add cases of template variable instantiation --- ...orTheStorageAndUseOfNumericValues.expected | 52 ++++++++++--------- cpp/autosar/test/rules/M5-0-12/test.cpp | 23 ++++++++ 2 files changed, 51 insertions(+), 24 deletions(-) diff --git a/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected b/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected index d5dc9af7e8..d0aeaebd41 100644 --- a/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected +++ b/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected @@ -1,24 +1,28 @@ -| test.cpp:98:7:98:8 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:98:7:98:8 | x3 | expression | -| test.cpp:101:20:101:21 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:101:20:101:21 | x4 | expression | -| test.cpp:111:21:111:22 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:111:21:111:22 | x7 | expression | -| test.cpp:114:20:114:21 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:114:20:114:21 | x8 | expression | -| test.cpp:124:17:124:18 | definition of c3 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'C1'. | test.cpp:5:12:5:12 | 120 | expression | -| test.cpp:127:17:127:18 | definition of c4 | Implicit conversion of plain char $@ to signed char from instantiating template 'C2'. | test.cpp:13:12:13:12 | 120 | expression | -| test.cpp:137:15:137:16 | definition of c7 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'C5'. | test.cpp:22:12:22:12 | 1 | expression | -| test.cpp:140:15:140:16 | definition of c8 | Implicit conversion of plain char $@ to int8_t from instantiating template 'C6'. | test.cpp:30:12:30:12 | 1 | expression | -| test.cpp:157:7:157:10 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:157:7:157:10 | * ... | expression | -| test.cpp:162:7:162:10 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:162:7:162:10 | * ... | expression | -| test.cpp:177:7:177:10 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:177:7:177:10 | * ... | expression | -| test.cpp:182:7:182:10 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:182:7:182:10 | * ... | expression | -| test.cpp:196:6:196:7 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:196:6:196:7 | a3 | expression | -| test.cpp:199:6:199:7 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:199:6:199:7 | a4 | expression | -| test.cpp:209:6:209:7 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:209:6:209:7 | a7 | expression | -| test.cpp:212:7:212:8 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:212:7:212:8 | a8 | expression | -| test.cpp:226:3:226:4 | call to f5 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'f5'. | test.cpp:43:56:43:56 | x | expression | -| test.cpp:230:3:230:4 | call to f6 | Implicit conversion of plain char $@ to signed char from instantiating template 'f6'. | test.cpp:44:54:44:54 | x | expression | -| test.cpp:243:3:243:5 | call to f13 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'f13'. | test.cpp:47:56:47:56 | x | expression | -| test.cpp:247:3:247:5 | call to f14 | Implicit conversion of plain char $@ to int8_t from instantiating template 'f14'. | test.cpp:48:55:48:55 | x | expression | -| test.cpp:264:12:264:14 | definition of c11 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'C9'. | test.cpp:52:15:52:15 | y | expression | -| test.cpp:269:13:269:15 | definition of c12 | Implicit conversion of plain char $@ to signed char from instantiating template 'C10'. | test.cpp:60:16:60:16 | y | expression | -| test.cpp:284:13:284:15 | definition of c15 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'C13'. | test.cpp:69:16:69:16 | y | expression | -| test.cpp:288:13:288:15 | definition of c16 | Implicit conversion of plain char $@ to int8_t from instantiating template 'C14'. | test.cpp:77:16:77:16 | y | expression | +| test.cpp:93:7:93:9 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:93:7:93:9 | 118 | expression | +| test.cpp:94:21:94:23 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:94:21:94:23 | 118 | expression | +| test.cpp:102:7:102:9 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:102:7:102:9 | 118 | expression | +| test.cpp:103:21:103:23 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:103:21:103:23 | 118 | expression | +| test.cpp:121:7:121:8 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:121:7:121:8 | x3 | expression | +| test.cpp:124:20:124:21 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:124:20:124:21 | x4 | expression | +| test.cpp:134:21:134:22 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:134:21:134:22 | x7 | expression | +| test.cpp:137:20:137:21 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:137:20:137:21 | x8 | expression | +| test.cpp:147:17:147:18 | definition of c3 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'C1'. | test.cpp:5:12:5:12 | 120 | expression | +| test.cpp:150:17:150:18 | definition of c4 | Implicit conversion of plain char $@ to signed char from instantiating template 'C2'. | test.cpp:13:12:13:12 | 120 | expression | +| test.cpp:160:15:160:16 | definition of c7 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'C5'. | test.cpp:22:12:22:12 | 1 | expression | +| test.cpp:163:15:163:16 | definition of c8 | Implicit conversion of plain char $@ to int8_t from instantiating template 'C6'. | test.cpp:30:12:30:12 | 1 | expression | +| test.cpp:180:7:180:10 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:180:7:180:10 | * ... | expression | +| test.cpp:185:7:185:10 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:185:7:185:10 | * ... | expression | +| test.cpp:200:7:200:10 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:200:7:200:10 | * ... | expression | +| test.cpp:205:7:205:10 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:205:7:205:10 | * ... | expression | +| test.cpp:219:6:219:7 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:219:6:219:7 | a3 | expression | +| test.cpp:222:6:222:7 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:222:6:222:7 | a4 | expression | +| test.cpp:232:6:232:7 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:232:6:232:7 | a7 | expression | +| test.cpp:235:7:235:8 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:235:7:235:8 | a8 | expression | +| test.cpp:249:3:249:4 | call to f5 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'f5'. | test.cpp:43:56:43:56 | x | expression | +| test.cpp:253:3:253:4 | call to f6 | Implicit conversion of plain char $@ to signed char from instantiating template 'f6'. | test.cpp:44:54:44:54 | x | expression | +| test.cpp:266:3:266:5 | call to f13 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'f13'. | test.cpp:47:56:47:56 | x | expression | +| test.cpp:270:3:270:5 | call to f14 | Implicit conversion of plain char $@ to int8_t from instantiating template 'f14'. | test.cpp:48:55:48:55 | x | expression | +| test.cpp:287:12:287:14 | definition of c11 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'C9'. | test.cpp:52:15:52:15 | y | expression | +| test.cpp:292:13:292:15 | definition of c12 | Implicit conversion of plain char $@ to signed char from instantiating template 'C10'. | test.cpp:60:16:60:16 | y | expression | +| test.cpp:307:13:307:15 | definition of c15 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'C13'. | test.cpp:69:16:69:16 | y | expression | +| test.cpp:311:13:311:15 | definition of c16 | Implicit conversion of plain char $@ to int8_t from instantiating template 'C14'. | test.cpp:77:16:77:16 | y | expression | diff --git a/cpp/autosar/test/rules/M5-0-12/test.cpp b/cpp/autosar/test/rules/M5-0-12/test.cpp index 0fe008436c..037c57da13 100644 --- a/cpp/autosar/test/rules/M5-0-12/test.cpp +++ b/cpp/autosar/test/rules/M5-0-12/test.cpp @@ -80,6 +80,29 @@ template class C14 { std::int8_t x; }; +template T v1; +template T v2; + +void instantiateTemplateVariables() { + v1 = + 1; // COMPLIANT: unsigned char assigned to an unsigned char + v2 = 1; // COMPLIANT: signed char assigned to a signed char + v2 = 'v'; // COMPLIANT: signed char assigned to a signed char + + v1 = + 'v'; // NON-COMPLIANT: plain char assigned to an unsigned char + v2 = 'v'; // NON-COMPLIANT: plain char assigned to a signed char + + /* Twin cases with std::uint8_t and std::int8_t */ + v1 = 1; // COMPLIANT: std::uint8_t assigned to a std::uint8_t + v2 = 1; // COMPLIANT: std::int8_t assigned to a std::int8_t + v2 = 'v'; // COMPLIANT: signed char assigned to a signed char + + v1 = + 'v'; // NON-COMPLIANT: plain char assigned to a std::uint8_t + v2 = 'v'; // NON-COMPLIANT: plain char assigned to a std::int8_t +} + int main() { /* ========== 1. Assigning a char to another char ========== */ From bb2ad888ad067ff3b75dad57a5516d92ca04830b Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Mon, 14 Jul 2025 11:18:29 -0400 Subject: [PATCH 10/11] Surround type name with single quotes in alert message --- ...eUsedForTheStorageAndUseOfNumericValues.ql | 6 +- ...orTheStorageAndUseOfNumericValues.expected | 56 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/cpp/autosar/src/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.ql b/cpp/autosar/src/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.ql index b81cf2dc64..e6852d7d39 100644 --- a/cpp/autosar/src/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.ql +++ b/cpp/autosar/src/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.ql @@ -228,12 +228,12 @@ string getMessageTemplate(ImplicitConversionLocation implicitConversionLocation) | implicitConversionLocation.isImplicitConversionOutsideTemplate() and result = - "Implicit conversion of plain char $@ to " + implicitConversion.getType().getName() + "." + "Implicit conversion of plain char $@ to '" + implicitConversion.getType().getName() + "'." or implicitConversionLocation.isInstantiationOfImplicitConversionTemplate() and result = - "Implicit conversion of plain char $@ to " + implicitConversion.getType().getName() + - " from instantiating template '" + + "Implicit conversion of plain char $@ to '" + implicitConversion.getType().getName() + + "' from instantiating template '" + implicitConversionLocation .asInstantiationOfImplicitConversionTemplate(implicitConversion) .getTemplate() diff --git a/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected b/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected index d0aeaebd41..ad1f57935e 100644 --- a/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected +++ b/cpp/autosar/test/rules/M5-0-12/SignedCharAndUnsignedCharTypeShallOnlyBeUsedForTheStorageAndUseOfNumericValues.expected @@ -1,28 +1,28 @@ -| test.cpp:93:7:93:9 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:93:7:93:9 | 118 | expression | -| test.cpp:94:21:94:23 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:94:21:94:23 | 118 | expression | -| test.cpp:102:7:102:9 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:102:7:102:9 | 118 | expression | -| test.cpp:103:21:103:23 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:103:21:103:23 | 118 | expression | -| test.cpp:121:7:121:8 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:121:7:121:8 | x3 | expression | -| test.cpp:124:20:124:21 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:124:20:124:21 | x4 | expression | -| test.cpp:134:21:134:22 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:134:21:134:22 | x7 | expression | -| test.cpp:137:20:137:21 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:137:20:137:21 | x8 | expression | -| test.cpp:147:17:147:18 | definition of c3 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'C1'. | test.cpp:5:12:5:12 | 120 | expression | -| test.cpp:150:17:150:18 | definition of c4 | Implicit conversion of plain char $@ to signed char from instantiating template 'C2'. | test.cpp:13:12:13:12 | 120 | expression | -| test.cpp:160:15:160:16 | definition of c7 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'C5'. | test.cpp:22:12:22:12 | 1 | expression | -| test.cpp:163:15:163:16 | definition of c8 | Implicit conversion of plain char $@ to int8_t from instantiating template 'C6'. | test.cpp:30:12:30:12 | 1 | expression | -| test.cpp:180:7:180:10 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:180:7:180:10 | * ... | expression | -| test.cpp:185:7:185:10 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:185:7:185:10 | * ... | expression | -| test.cpp:200:7:200:10 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:200:7:200:10 | * ... | expression | -| test.cpp:205:7:205:10 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:205:7:205:10 | * ... | expression | -| test.cpp:219:6:219:7 | (unsigned char)... | Implicit conversion of plain char $@ to unsigned char. | test.cpp:219:6:219:7 | a3 | expression | -| test.cpp:222:6:222:7 | (signed char)... | Implicit conversion of plain char $@ to signed char. | test.cpp:222:6:222:7 | a4 | expression | -| test.cpp:232:6:232:7 | (uint8_t)... | Implicit conversion of plain char $@ to uint8_t. | test.cpp:232:6:232:7 | a7 | expression | -| test.cpp:235:7:235:8 | (int8_t)... | Implicit conversion of plain char $@ to int8_t. | test.cpp:235:7:235:8 | a8 | expression | -| test.cpp:249:3:249:4 | call to f5 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'f5'. | test.cpp:43:56:43:56 | x | expression | -| test.cpp:253:3:253:4 | call to f6 | Implicit conversion of plain char $@ to signed char from instantiating template 'f6'. | test.cpp:44:54:44:54 | x | expression | -| test.cpp:266:3:266:5 | call to f13 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'f13'. | test.cpp:47:56:47:56 | x | expression | -| test.cpp:270:3:270:5 | call to f14 | Implicit conversion of plain char $@ to int8_t from instantiating template 'f14'. | test.cpp:48:55:48:55 | x | expression | -| test.cpp:287:12:287:14 | definition of c11 | Implicit conversion of plain char $@ to unsigned char from instantiating template 'C9'. | test.cpp:52:15:52:15 | y | expression | -| test.cpp:292:13:292:15 | definition of c12 | Implicit conversion of plain char $@ to signed char from instantiating template 'C10'. | test.cpp:60:16:60:16 | y | expression | -| test.cpp:307:13:307:15 | definition of c15 | Implicit conversion of plain char $@ to uint8_t from instantiating template 'C13'. | test.cpp:69:16:69:16 | y | expression | -| test.cpp:311:13:311:15 | definition of c16 | Implicit conversion of plain char $@ to int8_t from instantiating template 'C14'. | test.cpp:77:16:77:16 | y | expression | +| test.cpp:93:7:93:9 | (unsigned char)... | Implicit conversion of plain char $@ to 'unsigned char'. | test.cpp:93:7:93:9 | 118 | expression | +| test.cpp:94:21:94:23 | (signed char)... | Implicit conversion of plain char $@ to 'signed char'. | test.cpp:94:21:94:23 | 118 | expression | +| test.cpp:102:7:102:9 | (unsigned char)... | Implicit conversion of plain char $@ to 'unsigned char'. | test.cpp:102:7:102:9 | 118 | expression | +| test.cpp:103:21:103:23 | (signed char)... | Implicit conversion of plain char $@ to 'signed char'. | test.cpp:103:21:103:23 | 118 | expression | +| test.cpp:121:7:121:8 | (unsigned char)... | Implicit conversion of plain char $@ to 'unsigned char'. | test.cpp:121:7:121:8 | x3 | expression | +| test.cpp:124:20:124:21 | (signed char)... | Implicit conversion of plain char $@ to 'signed char'. | test.cpp:124:20:124:21 | x4 | expression | +| test.cpp:134:21:134:22 | (uint8_t)... | Implicit conversion of plain char $@ to 'uint8_t'. | test.cpp:134:21:134:22 | x7 | expression | +| test.cpp:137:20:137:21 | (int8_t)... | Implicit conversion of plain char $@ to 'int8_t'. | test.cpp:137:20:137:21 | x8 | expression | +| test.cpp:147:17:147:18 | definition of c3 | Implicit conversion of plain char $@ to 'unsigned char' from instantiating template 'C1'. | test.cpp:5:12:5:12 | 120 | expression | +| test.cpp:150:17:150:18 | definition of c4 | Implicit conversion of plain char $@ to 'signed char' from instantiating template 'C2'. | test.cpp:13:12:13:12 | 120 | expression | +| test.cpp:160:15:160:16 | definition of c7 | Implicit conversion of plain char $@ to 'uint8_t' from instantiating template 'C5'. | test.cpp:22:12:22:12 | 1 | expression | +| test.cpp:163:15:163:16 | definition of c8 | Implicit conversion of plain char $@ to 'int8_t' from instantiating template 'C6'. | test.cpp:30:12:30:12 | 1 | expression | +| test.cpp:180:7:180:10 | (unsigned char)... | Implicit conversion of plain char $@ to 'unsigned char'. | test.cpp:180:7:180:10 | * ... | expression | +| test.cpp:185:7:185:10 | (signed char)... | Implicit conversion of plain char $@ to 'signed char'. | test.cpp:185:7:185:10 | * ... | expression | +| test.cpp:200:7:200:10 | (uint8_t)... | Implicit conversion of plain char $@ to 'uint8_t'. | test.cpp:200:7:200:10 | * ... | expression | +| test.cpp:205:7:205:10 | (int8_t)... | Implicit conversion of plain char $@ to 'int8_t'. | test.cpp:205:7:205:10 | * ... | expression | +| test.cpp:219:6:219:7 | (unsigned char)... | Implicit conversion of plain char $@ to 'unsigned char'. | test.cpp:219:6:219:7 | a3 | expression | +| test.cpp:222:6:222:7 | (signed char)... | Implicit conversion of plain char $@ to 'signed char'. | test.cpp:222:6:222:7 | a4 | expression | +| test.cpp:232:6:232:7 | (uint8_t)... | Implicit conversion of plain char $@ to 'uint8_t'. | test.cpp:232:6:232:7 | a7 | expression | +| test.cpp:235:7:235:8 | (int8_t)... | Implicit conversion of plain char $@ to 'int8_t'. | test.cpp:235:7:235:8 | a8 | expression | +| test.cpp:249:3:249:4 | call to f5 | Implicit conversion of plain char $@ to 'unsigned char' from instantiating template 'f5'. | test.cpp:43:56:43:56 | x | expression | +| test.cpp:253:3:253:4 | call to f6 | Implicit conversion of plain char $@ to 'signed char' from instantiating template 'f6'. | test.cpp:44:54:44:54 | x | expression | +| test.cpp:266:3:266:5 | call to f13 | Implicit conversion of plain char $@ to 'uint8_t' from instantiating template 'f13'. | test.cpp:47:56:47:56 | x | expression | +| test.cpp:270:3:270:5 | call to f14 | Implicit conversion of plain char $@ to 'int8_t' from instantiating template 'f14'. | test.cpp:48:55:48:55 | x | expression | +| test.cpp:287:12:287:14 | definition of c11 | Implicit conversion of plain char $@ to 'unsigned char' from instantiating template 'C9'. | test.cpp:52:15:52:15 | y | expression | +| test.cpp:292:13:292:15 | definition of c12 | Implicit conversion of plain char $@ to 'signed char' from instantiating template 'C10'. | test.cpp:60:16:60:16 | y | expression | +| test.cpp:307:13:307:15 | definition of c15 | Implicit conversion of plain char $@ to 'uint8_t' from instantiating template 'C13'. | test.cpp:69:16:69:16 | y | expression | +| test.cpp:311:13:311:15 | definition of c16 | Implicit conversion of plain char $@ to 'int8_t' from instantiating template 'C14'. | test.cpp:77:16:77:16 | y | expression | From a474ded139a11efb51548d2fd45ef8310f7f050e Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Mon, 14 Jul 2025 12:12:13 -0400 Subject: [PATCH 11/11] Minor editing of label --- cpp/autosar/test/rules/M5-0-12/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/autosar/test/rules/M5-0-12/test.cpp b/cpp/autosar/test/rules/M5-0-12/test.cpp index 037c57da13..3e9a21ae17 100644 --- a/cpp/autosar/test/rules/M5-0-12/test.cpp +++ b/cpp/autosar/test/rules/M5-0-12/test.cpp @@ -87,7 +87,7 @@ void instantiateTemplateVariables() { v1 = 1; // COMPLIANT: unsigned char assigned to an unsigned char v2 = 1; // COMPLIANT: signed char assigned to a signed char - v2 = 'v'; // COMPLIANT: signed char assigned to a signed char + v2 = 'v'; // COMPLIANT: plain char assigned to a plain char v1 = 'v'; // NON-COMPLIANT: plain char assigned to an unsigned char @@ -96,7 +96,7 @@ void instantiateTemplateVariables() { /* Twin cases with std::uint8_t and std::int8_t */ v1 = 1; // COMPLIANT: std::uint8_t assigned to a std::uint8_t v2 = 1; // COMPLIANT: std::int8_t assigned to a std::int8_t - v2 = 'v'; // COMPLIANT: signed char assigned to a signed char + v2 = 'v'; // COMPLIANT: plain char assigned to a plain char v1 = 'v'; // NON-COMPLIANT: plain char assigned to a std::uint8_t