diff --git a/change_notes/2022-09-18-m3-2-1-templates.md b/change_notes/2022-09-18-m3-2-1-templates.md new file mode 100644 index 0000000000..b96cb35dca --- /dev/null +++ b/change_notes/2022-09-18-m3-2-1-templates.md @@ -0,0 +1,4 @@ + - `M3-2-1` - `DeclarationsOfAnObjectShallHaveCompatibleTypes.ql` + - Reduced false positives by excluding non-object variables (for example, member variables). + - Reduced false positives by excluding variable templates and template instantiations. + - Improved the reported error message by including the conflicting type names. \ No newline at end of file diff --git a/cpp/autosar/src/rules/M3-2-1/DeclarationsOfAnObjectShallHaveCompatibleTypes.ql b/cpp/autosar/src/rules/M3-2-1/DeclarationsOfAnObjectShallHaveCompatibleTypes.ql index cc6a921a6b..cb970a41f9 100644 --- a/cpp/autosar/src/rules/M3-2-1/DeclarationsOfAnObjectShallHaveCompatibleTypes.ql +++ b/cpp/autosar/src/rules/M3-2-1/DeclarationsOfAnObjectShallHaveCompatibleTypes.ql @@ -20,6 +20,11 @@ import cpp import codingstandards.cpp.autosar import codingstandards.cpp.Typehelpers +predicate isNonTemplateObjectVariable(GlobalOrNamespaceVariable gv) { + not gv.isFromTemplateInstantiation(_) and + not gv.isFromUninstantiatedTemplate(_) +} + from VariableDeclarationEntry decl1, VariableDeclarationEntry decl2 where not isExcluded(decl1, DeclarationsPackage::declarationsOfAnObjectShallHaveCompatibleTypesQuery()) and @@ -27,6 +32,11 @@ where not areCompatible(decl1.getType(), decl2.getType()) and // Note that normally `VariableDeclarationEntry` includes parameters, which are not covered // by this query. We implicitly exclude them with the `getQualifiedName()` predicate. - decl1.getVariable().getQualifiedName() = decl2.getVariable().getQualifiedName() -select decl1, "The object $@ is not compatible with re-declaration $@", decl1, decl1.getName(), - decl2, decl2.getName() + decl1.getVariable().getQualifiedName() = decl2.getVariable().getQualifiedName() and + // Only consider global/namespace variables which aren't templated + isNonTemplateObjectVariable(decl1.getVariable()) and + isNonTemplateObjectVariable(decl2.getVariable()) +select decl1, + "The object $@ of type " + decl1.getType().toString() + + " is not compatible with re-declaration $@ of type " + decl2.getType().toString(), decl1, + decl1.getName(), decl2, decl2.getName() diff --git a/cpp/autosar/test/rules/M3-2-1/DeclarationsOfAnObjectShallHaveCompatibleTypes.expected b/cpp/autosar/test/rules/M3-2-1/DeclarationsOfAnObjectShallHaveCompatibleTypes.expected index 8aed8c0473..33f6dec68f 100644 --- a/cpp/autosar/test/rules/M3-2-1/DeclarationsOfAnObjectShallHaveCompatibleTypes.expected +++ b/cpp/autosar/test/rules/M3-2-1/DeclarationsOfAnObjectShallHaveCompatibleTypes.expected @@ -1,12 +1,12 @@ -| test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:4:6:4:7 | definition of a4 | The object $@ is not compatible with re-declaration $@ | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:4:6:4:7 | definition of a4 | a4 | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:11:12:11:13 | declaration of a4 | a4 | -| test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:5:5:5:6 | definition of a5 | The object $@ is not compatible with re-declaration $@ | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:5:5:5:6 | definition of a5 | a5 | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:13:13:13:14 | declaration of a5 | a5 | -| test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:6:6:6:7 | definition of a6 | The object $@ is not compatible with re-declaration $@ | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:6:6:6:7 | definition of a6 | a6 | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:17:1:17:3 | declaration of a6 | a6 | -| test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:7:5:7:6 | definition of a7 | The object $@ is not compatible with re-declaration $@ | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:7:5:7:6 | definition of a7 | a7 | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:19:11:19:12 | declaration of a7 | a7 | -| test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:14:5:14:6 | definition of a2 | The object $@ is not compatible with re-declaration $@ | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:14:5:14:6 | definition of a2 | a2 | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:23:13:23:14 | declaration of a2 | a2 | -| test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:19:5:19:7 | definition of a11 | The object $@ is not compatible with re-declaration $@ | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:19:5:19:7 | definition of a11 | a11 | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:28:12:28:14 | declaration of a11 | a11 | -| test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:11:12:11:13 | declaration of a4 | The object $@ is not compatible with re-declaration $@ | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:11:12:11:13 | declaration of a4 | a4 | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:4:6:4:7 | definition of a4 | a4 | -| test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:13:13:13:14 | declaration of a5 | The object $@ is not compatible with re-declaration $@ | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:13:13:13:14 | declaration of a5 | a5 | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:5:5:5:6 | definition of a5 | a5 | -| test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:17:1:17:3 | declaration of a6 | The object $@ is not compatible with re-declaration $@ | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:17:1:17:3 | declaration of a6 | a6 | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:6:6:6:7 | definition of a6 | a6 | -| test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:19:11:19:12 | declaration of a7 | The object $@ is not compatible with re-declaration $@ | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:19:11:19:12 | declaration of a7 | a7 | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:7:5:7:6 | definition of a7 | a7 | -| test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:23:13:23:14 | declaration of a2 | The object $@ is not compatible with re-declaration $@ | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:23:13:23:14 | declaration of a2 | a2 | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:14:5:14:6 | definition of a2 | a2 | -| test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:28:12:28:14 | declaration of a11 | The object $@ is not compatible with re-declaration $@ | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:28:12:28:14 | declaration of a11 | a11 | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:19:5:19:7 | definition of a11 | a11 | +| test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:4:6:4:7 | definition of a4 | The object $@ of type long is not compatible with re-declaration $@ of type int | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:4:6:4:7 | definition of a4 | a4 | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:11:12:11:13 | declaration of a4 | a4 | +| test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:5:5:5:6 | definition of a5 | The object $@ of type int is not compatible with re-declaration $@ of type long | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:5:5:5:6 | definition of a5 | a5 | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:13:13:13:14 | declaration of a5 | a5 | +| test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:6:6:6:7 | definition of a6 | The object $@ of type long is not compatible with re-declaration $@ of type int | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:6:6:6:7 | definition of a6 | a6 | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:17:1:17:3 | declaration of a6 | a6 | +| test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:7:5:7:6 | definition of a7 | The object $@ of type int is not compatible with re-declaration $@ of type LL | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:7:5:7:6 | definition of a7 | a7 | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:19:11:19:12 | declaration of a7 | a7 | +| test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:14:5:14:6 | definition of a2 | The object $@ of type int is not compatible with re-declaration $@ of type long | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:14:5:14:6 | definition of a2 | a2 | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:23:13:23:14 | declaration of a2 | a2 | +| test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:19:5:19:7 | definition of a11 | The object $@ of type int[100] is not compatible with re-declaration $@ of type int[101] | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:19:5:19:7 | definition of a11 | a11 | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:28:12:28:14 | declaration of a11 | a11 | +| test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:11:12:11:13 | declaration of a4 | The object $@ of type int is not compatible with re-declaration $@ of type long | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:11:12:11:13 | declaration of a4 | a4 | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:4:6:4:7 | definition of a4 | a4 | +| test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:13:13:13:14 | declaration of a5 | The object $@ of type long is not compatible with re-declaration $@ of type int | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:13:13:13:14 | declaration of a5 | a5 | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:5:5:5:6 | definition of a5 | a5 | +| test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:17:1:17:3 | declaration of a6 | The object $@ of type int is not compatible with re-declaration $@ of type long | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:17:1:17:3 | declaration of a6 | a6 | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:6:6:6:7 | definition of a6 | a6 | +| test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:19:11:19:12 | declaration of a7 | The object $@ of type LL is not compatible with re-declaration $@ of type int | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:19:11:19:12 | declaration of a7 | a7 | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:7:5:7:6 | definition of a7 | a7 | +| test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:23:13:23:14 | declaration of a2 | The object $@ of type long is not compatible with re-declaration $@ of type int | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:23:13:23:14 | declaration of a2 | a2 | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:14:5:14:6 | definition of a2 | a2 | +| test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:28:12:28:14 | declaration of a11 | The object $@ of type int[101] is not compatible with re-declaration $@ of type int[100] | test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp:28:12:28:14 | declaration of a11 | a11 | test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp:19:5:19:7 | definition of a11 | a11 | diff --git a/cpp/autosar/test/rules/M3-2-1/test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp b/cpp/autosar/test/rules/M3-2-1/test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp index 33482c62a2..ad774c5995 100644 --- a/cpp/autosar/test/rules/M3-2-1/test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp +++ b/cpp/autosar/test/rules/M3-2-1/test_declarations_of_an_object_shall_have_compatible_types_unit1.cpp @@ -17,3 +17,19 @@ int a2; // NON_COMPLIANT int a9[100]; // COMPLIANT int a10[100]; // COMPLIANT int a11[100]; // NON_COMPLIANT - different sizes + +// Variable templates can cause false positives +template constexpr T number_one = T(1); // COMPLIANT + +int test() { return number_one; } + +long test2() { return number_one; } + +template class ClassB { +private: + T mA; // Should be ignored, as not an object + double mB; // Should be ignored, as not an object +}; + +void test3() { ClassB b; } +void test4() { ClassB b; } \ No newline at end of file diff --git a/cpp/autosar/test/rules/M3-2-1/test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp b/cpp/autosar/test/rules/M3-2-1/test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp index 0a2fe7a472..58aefe0281 100644 --- a/cpp/autosar/test/rules/M3-2-1/test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp +++ b/cpp/autosar/test/rules/M3-2-1/test_declarations_of_an_object_shall_have_compatible_types_unit2.cpp @@ -26,3 +26,12 @@ extern long a2; // NON_COMPLIANT extern int a9[100]; // COMPLIANT LI a10[100]; // COMPLIANT extern int a11[101]; // NON_COMPLIANT - different sizes + +template class ClassB { +private: + T mA; // Should be ignored, as not an object + int mB; // Should be ignored, as not an object +}; + +void testb_1() { ClassB b; } +void testb_2() { ClassB b; } \ No newline at end of file