From 15e501562684a1e4a2ad0b3bc0239e8c6dc5bd25 Mon Sep 17 00:00:00 2001 From: swasti16 Date: Wed, 5 Mar 2025 21:47:09 +0530 Subject: [PATCH] Fix #13647: Misra C 21.6: Location should point at function call instead of #include --- addons/misra.py | 29 +++++++++++++++-------------- addons/test/misra/misra-test.c | 18 +++++++++--------- test/cli/helloworld_test.py | 8 ++++---- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/addons/misra.py b/addons/misra.py index a80783d697e..7ea3c08e0a6 100755 --- a/addons/misra.py +++ b/addons/misra.py @@ -478,20 +478,20 @@ def rawlink(rawtoken): 'wctype.h': C99_STDLIB_IDENTIFIERS['wctype.h'], } -def isStdLibId(id_, standard='c99'): - id_lists = [] +def getStdLib(standard): if standard == 'c89': - id_lists = C90_STDLIB_IDENTIFIERS.values() - elif standard == 'c99': - id_lists = C99_STDLIB_IDENTIFIERS.values() - else: - id_lists = C11_STDLIB_IDENTIFIERS.values() + return C90_STDLIB_IDENTIFIERS + if standard == 'c99': + return C99_STDLIB_IDENTIFIERS + return C11_STDLIB_IDENTIFIERS + +def isStdLibId(id_, standard='c99'): + id_lists = getStdLib(standard).values() for l in id_lists: if id_ in l: return True return False - # Reserved keywords defined in ISO/IEC9899:1990 -- ch 6.1.1 C90_KEYWORDS = { 'auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do', @@ -3964,12 +3964,13 @@ def misra_21_5(self, data): self.reportError(directive, 21, 5) def misra_21_6(self, data): - dir_stdio = findInclude(data.directives, '') - dir_wchar = findInclude(data.directives, '') - if dir_stdio: - self.reportError(dir_stdio, 21, 6) - if dir_wchar: - self.reportError(dir_wchar, 21, 6) + for token in data.tokenlist: + if not isFunctionCall(token) or token.previous.function: + continue + standard_id = getStdLib(data.standards.c) + funcname = token.previous.str + if funcname in standard_id.get("stdio.h", []) or funcname in standard_id.get("wchar.h", []): + self.reportError(token, 21, 6) def misra_21_7(self, data): for token in data.tokenlist: diff --git a/addons/test/misra/misra-test.c b/addons/test/misra/misra-test.c index b289b5c48de..f6a4376bf91 100644 --- a/addons/test/misra/misra-test.c +++ b/addons/test/misra/misra-test.c @@ -37,8 +37,8 @@ #include // 21.4 #include // 21.5 -#include //21.6 -#include //21.6 +#include +#include #include // 21.10 #include // 21.11 #include @@ -134,7 +134,7 @@ static void misra_3_2(int enable) ++y; // This is hidden if trigraph replacement is active } - (void)printf("x=%i, y=%i\n", x, y); + (void)printf("x=%i, y=%i\n", x, y); //21.6 } extern int misra_5_1_extern_var_hides_var_x; @@ -209,9 +209,9 @@ int c41_15 = 'a'; // 10.3 8.4 static void misra_4_1(void) { - (void)printf("\x41g"); // 4.1 - (void)printf("\x41\x42"); - (void)printf("\x41" "g"); + (void)printf("\x41g"); // 4.1 21.6 + (void)printf("\x41\x42"); //21.6 + (void)printf("\x41" "g"); //21.6 } const char *s42_1 = "String containing trigraphs ??-??-??"; // 4.2 8.4 @@ -220,8 +220,8 @@ const char *s42_3 = "No trigraph?(?'?)"; // 8.4 static void misra_4_2(void) { - (void)printf("??=Trigraph\n"); // 4.2 - (void)printf("No?/Trigraph\n"); + (void)printf("??=Trigraph\n"); // 4.2 21.6 + (void)printf("No?/Trigraph\n"); //21.6 } #define misra_5_4_macro_hides_macro__31x 1 @@ -965,7 +965,7 @@ void misra_12_3(int a, int b, int c) { int a41 = MISRA_12_3_FN3_2(a34, a35), a42; // 12.3 int a43, a44 = MISRA_12_3_FN3_2(a34, a35); // 12.3 - MISRA_12_3_FN3_2_MSG(fprintf(stderr, "test\n")); // 12.3 + MISRA_12_3_FN3_2_MSG(fprintf(stderr, "test\n")); // 12.3 21.6 f((1,2),3); // TODO diff --git a/test/cli/helloworld_test.py b/test/cli/helloworld_test.py index 011d9175e4d..91546a496f9 100644 --- a/test/cli/helloworld_test.py +++ b/test/cli/helloworld_test.py @@ -68,7 +68,7 @@ def test_addon_local_path(): ret, stdout, stderr = cppcheck(args, cwd=__proj_dir) assert ret == 0, stdout assert stderr == ('[main.c:5]: (error) Division by zero.\n' - '[main.c:1]: (style) misra violation (use --rule-texts= to get proper output)\n') + '[main.c:4]: (style) misra violation (use --rule-texts= to get proper output)\n') def test_addon_local_path_not_enable(): args = [ @@ -91,7 +91,7 @@ def test_addon_absolute_path(): filename = os.path.join(__proj_dir, 'main.c') assert ret == 0, stdout assert stderr == ('[%s:5]: (error) Division by zero.\n' - '[%s:1]: (style) misra violation (use --rule-texts= to get proper output)\n' % (filename, filename)) + '[%s:4]: (style) misra violation (use --rule-texts= to get proper output)\n' % (filename, filename)) def test_addon_relative_path(): args = [ @@ -106,7 +106,7 @@ def test_addon_relative_path(): assert stdout == ('Checking %s ...\n' 'Checking %s: SOME_CONFIG...\n' % (filename, filename)) assert stderr == ('[%s:5]: (error) Division by zero.\n' - '[%s:1]: (style) misra violation (use --rule-texts= to get proper output)\n' % (filename, filename)) + '[%s:4]: (style) misra violation (use --rule-texts= to get proper output)\n' % (filename, filename)) def test_addon_with_gui_project(): project_file = os.path.join('helloworld', 'test.cppcheck') @@ -123,7 +123,7 @@ def test_addon_with_gui_project(): assert ret == 0, stdout assert stdout == 'Checking %s ...\n' % filename assert stderr == ('[%s:5]: (error) Division by zero.\n' - '[%s:1]: (style) misra violation (use --rule-texts= to get proper output)\n' % (filename, filename)) + '[%s:4]: (style) misra violation (use --rule-texts= to get proper output)\n' % (filename, filename)) def test_basepath_relative_path(): args = [