diff --git a/addons/misra.py b/addons/misra.py index b9666e622..db13db1f4 100755 --- a/addons/misra.py +++ b/addons/misra.py @@ -3542,6 +3542,31 @@ class MisraChecker: continue self.reportError(token, 21, 16) + def misra_21_19(self, cfg): + for token in cfg.tokenlist: + if token.str in ('localeconv', 'getenv', 'setlocale', 'strerror') and simpleMatch(token.next, '('): + name, _ = cppcheckdata.get_function_call_name_args(token) + if name is None or name != token.str: + continue + parent = token.next + while simpleMatch(parent.astParent, '+'): + parent = parent.astParent + # x = f() + if simpleMatch(parent.astParent, '=') and parent == parent.astParent.astOperand2: + lhs = parent.astParent.astOperand1 + if lhs and lhs.valueType and lhs.valueType.pointer > 0 and lhs.valueType.constness == 0: + self.reportError(token, 21, 19) + if token.str == '=': + lhs = token.astOperand1 + while simpleMatch(lhs, '*') and lhs.astOperand2 is None: + lhs = lhs.astOperand1 + if not simpleMatch(lhs, '.'): + continue + while simpleMatch(lhs, '.'): + lhs = lhs.astOperand1 + if lhs and lhs.variable and simpleMatch(lhs.variable.typeStartToken, 'lconv'): + self.reportError(token, 21, 19) + def misra_21_21(self, cfg): for token in cfg.tokenlist: if token.str == 'system': @@ -4189,6 +4214,7 @@ class MisraChecker: self.executeCheck(2114, self.misra_21_14, cfg) self.executeCheck(2115, self.misra_21_15, cfg) self.executeCheck(2116, self.misra_21_16, cfg) + self.executeCheck(2121, self.misra_21_19, cfg) self.executeCheck(2121, self.misra_21_21, cfg) # 22.4 is already covered by Cppcheck writeReadOnlyFile self.executeCheck(2205, self.misra_22_5, cfg) diff --git a/addons/test/misra/misra-test.c b/addons/test/misra/misra-test.c index 696a4ee25..e06788a66 100644 --- a/addons/test/misra/misra-test.c +++ b/addons/test/misra/misra-test.c @@ -1803,6 +1803,12 @@ static void misra_21_16_f2(char *x, char *y) { (void)memcmp(x, y, 10); // 21.16 } +static void misra_21_19(void) { + char *s = setlocale(LC_ALL,0); // 21.19 + const struct lconv *conv = localeconv (); + conv->decimal_point = "^"; // 21.19 +} + static void misra_21_21(void) { (void)system("ls"); // 21.21 }