Skip to content

Commit

Permalink
Fix #12079: Misra: calling unknown function in condition => false pos…
Browse files Browse the repository at this point in the history
…itive 14.4, missing misra-config warning
  • Loading branch information
swasti16 committed Oct 19, 2023
1 parent dd76504 commit af151d7
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 36 deletions.
1 change: 1 addition & 0 deletions addons/cppcheckdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import os
import sys
import subprocess
import xml.etree.ElementTree as ET

try:
import pathlib
Expand Down
58 changes: 51 additions & 7 deletions addons/misra.py
Original file line number Diff line number Diff line change
Expand Up @@ -2805,7 +2805,9 @@ def misra_14_4(self, data):
continue
if not token.astOperand1 or not (token.astOperand1.str in ['if', 'while']):
continue
if not isBoolExpression(token.astOperand2):
if isBoolExpression(token.astOperand2):
continue
if token.astOperand2.valueType:
self.reportError(token, 14, 4)

def misra_15_1(self, data):
Expand Down Expand Up @@ -3185,6 +3187,38 @@ def misra_17_3(self, cfg):
for w in cfg.clang_warnings:
if w['message'].endswith('[-Wimplicit-function-declaration]'):
self.reportError(cppcheckdata.Location(w), 17, 3)
for token in cfg.tokenlist:
if token.str not in ["while", "if"]:
continue
if token.next.str != "(":
continue
tok = token.next
while (tok != token.next.link):
if tok.isName and not tok.function and not tok.valueType and tok.next.str == "(" and \
not tok.next.valueType and not isKeyword(tok.str) and not isStdLibId(tok.str):
self.reportError(tok, 17, 3)
break
tok = tok.next

def misra_config(self, data):
for token in data.tokenlist:
if token.str not in ["while", "if"]:
continue
if token.next.str != "(":
continue
tok = token.next
while tok != token.next.link:
if tok.str == "(" and tok.isCast:
tok = tok.link
continue
if not tok.isName or tok.function or tok.variable or tok.varId or tok.valueType \
or tok.next.str == "(" or tok.str in ["EOF"] \
or isKeyword(tok.str) or isStdLibId(tok.str):
tok = tok.next
continue
errmsg = tok.str + " Variable is unknown"
self.reportError(token, 0, 0, "config")
break

def misra_17_6(self, rawTokens):
for token in rawTokens:
Expand Down Expand Up @@ -4093,21 +4127,30 @@ def setSuppressionList(self, suppressionlist):

self.addSuppressedRule(ruleNum)

def reportError(self, location, num1, num2):
ruleNum = num1 * 100 + num2
def reportError(self, location, num1, num2, other_id = None):
if not other_id:
ruleNum = num1 * 100 + num2
else:
ruleNum = other_id

if self.isRuleGloballySuppressed(ruleNum):
return

if self.settings.verify:
self.verify_actual.append('%s:%d %d.%d' % (location.file, location.linenr, num1, num2))
if not other_id:
self.verify_actual.append('%s:%d %d.%d' % (location.file, location.linenr, num1, num2))
else:
self.verify_actual.append('%s:%d %s' % (location.file, location.linenr, other_id))
elif self.isRuleSuppressed(location.file, location.linenr, ruleNum):
# Error is suppressed. Ignore
self.suppressionStats.setdefault(ruleNum, 0)
self.suppressionStats[ruleNum] += 1
return
else:
errorId = 'c2012-' + str(num1) + '.' + str(num2)
if not other_id:
errorId = 'c2012-' + str(num1) + '.' + str(num2)
else:
errorId = 'c2012-' + other_id
misra_severity = 'Undefined'
cppcheck_severity = 'style'
if ruleNum in self.ruleTexts:
Expand Down Expand Up @@ -4293,7 +4336,7 @@ def fillVerifyExpected(verify_expected, tok):
rule_re = re.compile(r'[0-9]+\.[0-9]+')
if tok.str.startswith('//') and 'TODO' not in tok.str:
for word in tok.str[2:].split(' '):
if rule_re.match(word):
if rule_re.match(word) or word == "config":
verify_expected.append('%s:%d %s' % (tok.file, tok.linenr, word))

data = cppcheckdata.parsedump(dumpfile)
Expand Down Expand Up @@ -4431,6 +4474,7 @@ def fillVerifyExpected(verify_expected, tok):
self.executeCheck(1701, self.misra_17_1, cfg)
self.executeCheck(1702, self.misra_17_2, cfg)
self.executeCheck(1703, self.misra_17_3, cfg)
self.misra_config(cfg)
if cfgNumber == 0:
self.executeCheck(1706, self.misra_17_6, data.rawTokens)
self.executeCheck(1707, self.misra_17_7, cfg)
Expand Down Expand Up @@ -4751,7 +4795,7 @@ def main():
for misra_id in ids:
rules_violated[misra_id] = rules_violated.get(misra_id, 0) + 1
print("MISRA rules violated:")
convert = lambda text: int(text) if text.isdigit() else text
convert = lambda text: int(text) if text.isdigit() else 0
misra_sort = lambda key: [convert(c) for c in re.split(r'[\.-]([0-9]*)', key)]
for misra_id in sorted(rules_violated.keys(), key=misra_sort):
res = re.match(r'misra-c2012-([0-9]+)\\.([0-9]+)', misra_id)
Expand Down
4 changes: 2 additions & 2 deletions addons/test/misra/misra-suppressions1-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ static void foo(void)
{
for(i = 0; i < 10; i++)
{
if(misra_5_2_func3()) //14.4
if(misra_5_2_func3()) //17.3
{
int misra_5_2_var_hides_var_1____31x;
int misra_5_2_var_hides_var_1____31y;//5.2
}
}
} while(misra_5_2_func2()); //14.4
} while(misra_5_2_func2()); //17.3
}
}
}
67 changes: 40 additions & 27 deletions addons/test/misra/misra-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ typedef unsigned long long u64;
static void misra_1_2(void)
{
(void)(condition ? : 0); // 1.2
a = 1 + ({if (!expr) {code;} 1;}); // 1.2
a = 1 + ({if (!expr) {code;} 1;}); // 1.2 config
}

static _Atomic int misra_1_4_var; // 1.4
static _Noreturn void misra_1_4_func(void) // 1.4
{
if (0 != _Generic(misra_1_4_var)) {} // 1.4
if (0 != _Generic(misra_1_4_var)) {} // 1.4 17.3
printf_s("hello"); // 1.4
}

Expand Down Expand Up @@ -160,13 +160,13 @@ static void foo(void)
{
for(i = 0; i < 10; i++)
{
if(misra_5_2_func3()) //14.4
if(misra_5_2_func3()) //17.3
{
int misra_5_2_var_hides_var_1____31x;
int misra_5_2_var_hides_var_1____31y;//5.2
}
}
} while(misra_5_2_func2()); //14.4
} while(misra_5_2_func2()); //17.3
}
break;
}
Expand Down Expand Up @@ -252,11 +252,11 @@ static void misra_5_5_func1(void)
{
do
{
if(misra_5_5_func3()) //14.4
if(misra_5_5_func3()) //17.3
{
int misra_5_5_hides_macro________31y; //5.5
}
} while(misra_5_5_func2()); //14.4
} while(misra_5_5_func2()); //17.3
}
break;
}
Expand Down Expand Up @@ -1144,15 +1144,15 @@ static s13_4_t s13_4 =
};

static void misra_13_4(void) {
if (x != (y = z)) {} // 13.4
if (x != (y = z)) {} // 13.4 config
else {}
}

static void misra_13_5(void) {
if (x && (y++ < 123)){} // 13.5
if (x || ((y += 19) > 33)){} // 13.5
if (x || ((y = 25) > 33)){} // 13.5 13.4
if (x || ((--y) > 33)){} // 13.5
if (x && (y++ < 123)){} // 13.5 config
if (x || ((y += 19) > 33)){} // 13.5 config
if (x || ((y = 25) > 33)){} // 13.5 13.4 config
if (x || ((--y) > 33)){} // 13.5 config
else {}
}

Expand Down Expand Up @@ -1297,13 +1297,16 @@ struct {
unsigned int y:1;
} r14_4_struct; // 8.4
static void misra_14_4(bool b) {
if (x+4){} // 14.4
if (x+4){} //config
else {}

if (b) {}
else {}

if (r14_4_struct.x) {}

// #12079
if (z) {} //config
}

static void misra_15_1(void) {
Expand All @@ -1317,22 +1320,22 @@ static void misra_15_2(void) {
}

static void misra_15_3(void) {
if (x!=0) {
if (x!=0) { //config
goto L1; // 15.3 15.1
if (y!=0) {
if (y!=0) { //config
L1:
} else {}
} else {}

switch (x) {
case 0:
if (x == y) {
if (x == y) { //config
goto L2; // 15.3 15.1
}
goto L2; // 15.3 15.1
L3:
foo();
if (a == 0x42) {
if (a == 0x42) { //config
// Compliant:
goto L3; // 15.1 15.2
}
Expand Down Expand Up @@ -1432,14 +1435,14 @@ static void misra_15_4(void) {
}

static int misra_15_5(void) {
if (x!=0) {
if (x!=0) { // config
return 1; // 15.5
} else {}
return 2;
}

static void misra_15_6(void) {
if (x!=0); // 15.6
if (x!=0); // 15.6 config
else{}

#if A>1 // 20.9
Expand All @@ -1454,7 +1457,7 @@ static void misra_15_6(void) {
#endif
{ (void)0; } // no-warning

do {} while (x<0); // no-warning
do {} while (x<0); // config
}

static void misra_15_6_fp(void)
Expand All @@ -1474,11 +1477,11 @@ static void misra_15_7(void) {
uint32_t var = 0;
uint32_t var2 = 0;

if (x!=0){} // no-warning
if (x!=0){} else if(x==1){} // 15.7
if (x!=0){} else if(x==1){}else{;} // no-warning
if (x!=0){} // config
if (x!=0){} else if(x==1){} // 15.7 config
if (x!=0){} else if(x==1){}else{;} // config

if (x!=0)
if (x!=0) // config
{
}
else
Expand All @@ -1491,8 +1494,8 @@ static void misra_15_7(void) {
} // no-warning
}

if (a==2) {} else if (b==4) {} // 15.7
if (a==2) {} else { if (b==4) {} } // no-warning
if (a==2) {} else if (b==4) {} // 15.7 config
if (a==2) {} else { if (b==4) {} } // no-warning config
}

static void misra_16_1(int32_t i) {
Expand All @@ -1511,7 +1514,7 @@ static void misra_16_2(void) {
default:
break;
case 1:
while (y>4) {
while (y>4) { //config
case 2: break; // 16.2
}
break;
Expand All @@ -1535,7 +1538,7 @@ static void misra_16_3(void) {
a=4;
break;
case 9:
if (a==b) {
if (a==b) { //config
break;
}
case 10: // 16.3
Expand Down Expand Up @@ -1690,6 +1693,16 @@ static void misra_17_2_5(void) {
misra_17_2_1(); // no-warning
}

bool (*dostuff)(); //8.2 8.4
static void misra_17_3(void) {
if (dostuff()) {}
}

static void misra_config(char str) {
if (strlen(str) > 3){} //10.4
if (sizeof(int) > 1){} //10.4
}

static void misra_17_6(int x[static 20]) {(void)x;} // 17.6

static int calculation(int x) { return x + 1; }
Expand Down

0 comments on commit af151d7

Please sign in to comment.