Skip to content

Commit

Permalink
Merge branch 'main' into chr_Fix12214
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github authored Nov 22, 2023
2 parents 2ead60d + 83b5cb5 commit dbb28fa
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 42 deletions.
5 changes: 4 additions & 1 deletion addons/cppcheckdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ class Token:
isCast
externLang
isExpandedMacro Is this token a expanded macro token
macroName Macro name that this token is expanded from
isRemovedVoidParameter Has void parameter been removed?
isSplittedVarDeclComma Is this a comma changed to semicolon in a split variable declaration ('int a,b;' => 'int a; int b;')
isSplittedVarDeclEq Is this a '=' changed to semicolon in a split variable declaration ('int a=5;' => 'int a; a=5;')
Expand Down Expand Up @@ -313,6 +314,7 @@ class Token:
isCast = False
isUnsigned = False
isSigned = False
macroName = None
isExpandedMacro = False
isRemovedVoidParameter = False
isSplittedVarDeclComma = False
Expand Down Expand Up @@ -386,7 +388,8 @@ def __init__(self, element):
if element.get('isCast'):
self.isCast = True
self.externLang = element.get('externLang')
if element.get('isExpandedMacro'):
self.macroName = element.get('macroName')
if self.macroName or element.get('isExpandedMacro'):
self.isExpandedMacro = True
if element.get('isRemovedVoidParameter'):
self.isRemovedVoidParameter = True
Expand Down
25 changes: 25 additions & 0 deletions addons/misra.py
Original file line number Diff line number Diff line change
Expand Up @@ -2520,6 +2520,20 @@ def misra_11_3(self, data):
self.reportError(token, 11, 3)

def misra_11_4(self, data):
# Get list of macro definitions
macros = {}
for directive in data.directives:
#define X ((peripheral_t *)0x40000U)
res = re.match(r'#define ([A-Za-z0-9_]+).*', directive.str)
if res:
if res.group(1) in macros:
macros[res.group(1)].append(directive)
else:
macros[res.group(1)] = [directive]

# If macro definition is non-compliant then warn about the macro definition instead of
# the macro usages. To reduce diagnostics for a non-compliant macro.
bad_macros = []
for token in data.tokenlist:
if not isCast(token):
continue
Expand All @@ -2530,6 +2544,17 @@ def misra_11_4(self, data):
if vt2.pointer > 0 and vt1.pointer == 0 and (vt1.isIntegral() or vt1.isEnum()) and vt2.type != 'void':
self.reportError(token, 11, 4)
elif vt1.pointer > 0 and vt2.pointer == 0 and (vt2.isIntegral() or vt2.isEnum()) and vt1.type != 'void':
if token.macroName is not None and \
token.macroName == token.astOperand1.macroName and \
token.astOperand1.isInt and \
token.link.previous.str == '*' and \
token.macroName == token.link.previous.macroName and \
token.macroName in macros and \
len(macros[token.macroName]) == 1:
if token.macroName not in bad_macros:
bad_macros.append(token.macroName)
self.reportError(macros[token.macroName][0], 11, 4)
continue
self.reportError(token, 11, 4)

def misra_11_5(self, data):
Expand Down
5 changes: 4 additions & 1 deletion addons/test/misra/misra-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -798,12 +798,15 @@ static void misra_11_3(u8* p, struct Fred *fred) {
struct Wilma *wilma = (struct Wilma *)fred; // 11.3
}

typedef struct { uint32_t something; } struct_11_4;
#define A_11_4 ((struct_11_4 *)0x40000U) // 11.4

static void misra_11_4(u8*p) {
u64 y = (u64)p; // 11.4
u8 *misra_11_4_A = ( u8 * ) 0x0005;// 11.4
s32 misra_11_4_B;
u8 *q = ( u8 * ) misra_11_4_B; // 11.4

dummy = A_11_4->something; // no-warning
}

static void misra_11_5(void *p) {
Expand Down
2 changes: 1 addition & 1 deletion cmake/compilerDefinitions.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
if (MSVC)
# Visual Studio only sets _DEBUG
add_compile_definitions($<$<CONFIG:Debug>:-DDEBUG>)
add_compile_definitions($<$<CONFIG:Debug>:DEBUG>)

add_definitions(-DWIN32)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
Expand Down
20 changes: 1 addition & 19 deletions lib/checkother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1431,25 +1431,7 @@ void CheckOther::checkConstVariable()
}
}
if (tok->isUnaryOp("&") && Token::Match(tok, "& %varid%", var->declarationId())) {
const Token* opTok = tok->astParent();
int argn = -1;
if (opTok && opTok->isUnaryOp("!"))
continue;
if (opTok && (opTok->isComparisonOp() || opTok->isAssignmentOp() || opTok->isCalculation())) {
if (opTok->isComparisonOp() || opTok->isCalculation()) {
if (opTok->astOperand1() != tok)
opTok = opTok->astOperand1();
else
opTok = opTok->astOperand2();
}
if (opTok && opTok->valueType() && var->valueType() && opTok->valueType()->isConst(var->valueType()->pointer))
continue;
} else if (const Token* ftok = getTokenArgumentFunction(tok, argn)) {
bool inconclusive{};
if (var->valueType() && !isVariableChangedByFunctionCall(ftok, var->valueType()->pointer, var->declarationId(), mSettings, &inconclusive) && !inconclusive)
continue;
}
usedInAssignment = true;
usedInAssignment = isExpressionChangedAt(tok->next(), tok, 0, false, mSettings, true);
break;
}
if (astIsRangeBasedForDecl(tok) && Token::Match(tok->astParent()->astOperand2(), "%varid%", var->declarationId())) {
Expand Down
4 changes: 2 additions & 2 deletions lib/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2109,10 +2109,10 @@ static void mergeAdjacent(std::list<ValueFlow::Value>& values)

static void removeOverlaps(std::list<ValueFlow::Value>& values)
{
for (ValueFlow::Value& x : values) {
for (const ValueFlow::Value& x : values) {
if (x.isNonValue())
continue;
values.remove_if([&](ValueFlow::Value& y) {
values.remove_if([&](const ValueFlow::Value& y) {
if (y.isNonValue())
return false;
if (&x == &y)
Expand Down
2 changes: 1 addition & 1 deletion lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5943,7 +5943,7 @@ void Tokenizer::dump(std::ostream &out) const
if (tok->isExternC())
outs += " externLang=\"C\"";
if (tok->isExpandedMacro())
outs += " isExpandedMacro=\"true\"";
outs += " macroName=\"" + tok->getMacroName() + "\"";
if (tok->isTemplateArg())
outs += " isTemplateArg=\"true\"";
if (tok->isRemovedVoidParameter())
Expand Down
31 changes: 14 additions & 17 deletions test/testother.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2794,16 +2794,14 @@ class TestOther : public TestFixture {
"void a(T& x) {\n"
" x.dostuff();\n"
" const U * y = dynamic_cast<const U *>(&x);\n"
" y->mutate();\n" // to avoid warnings that y can be const
"}");
TODO_ASSERT_EQUALS("can be const", errout.str(), ""); //Currently taking the address is treated as a non-const operation when it should depend on what we do with it
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
check("struct T : public U { void dostuff() const {}};\n"
"void a(T& x) {\n"
" x.dostuff();\n"
" U const * y = dynamic_cast<U const *>(&x);\n"
" y->mutate();\n" // to avoid warnings that y can be const
"}");
TODO_ASSERT_EQUALS("can be const", errout.str(), ""); //Currently taking the address is treated as a non-const operation when it should depend on what we do with it
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
check("struct T : public U { void dostuff() const {}};\n"
"void a(T& x) {\n"
" x.dostuff();\n"
Expand All @@ -2814,17 +2812,9 @@ class TestOther : public TestFixture {
check("struct T : public U { void dostuff() const {}};\n"
"void a(T& x) {\n"
" x.dostuff();\n"
" const U const * const * const * const y = dynamic_cast<const U const * const * const * const>(&x);\n"
" y->mutate();\n" // to avoid warnings that y can be const
"}");
TODO_ASSERT_EQUALS("can be const", errout.str(), ""); //Currently taking the address is treated as a non-const operation when it should depend on what we do with it
check("struct T : public U { void dostuff() const {}};\n"
"void a(T& x) {\n"
" x.dostuff();\n"
" const U const * const * * const y = dynamic_cast<const U const * const * * const>(&x);\n"
" y->mutate();\n" // to avoid warnings that y can be const
" U const * const * * const y = dynamic_cast<U const * const * * const>(&x);\n"
"}");
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:2]: (style) Parameter 'x' can be declared as reference to const\n", errout.str());
check("struct T : public U { void dostuff() const {}};\n"
"void a(T& x) {\n"
" x.dostuff();\n"
Expand Down Expand Up @@ -3375,13 +3365,20 @@ class TestOther : public TestFixture {
"}\n");
ASSERT_EQUALS("", errout.str());

check("void f(int& r) {\n"
check("bool f(std::string& s1, std::string& s2) {\n" // #12203
" return &s1 == &s2;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 's1' can be declared as reference to const\n"
"[test.cpp:1]: (style) Parameter 's2' can be declared as reference to const\n",
errout.str());

check("void f(int& r) {\n" // #12214
" (void)(true);\n"
" if (r) {}\n"
"}\n");
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'r' can be declared as reference to const\n", errout.str());

check("struct S { void f(int&); };\n"
check("struct S { void f(int&); };\n" // #12216
"void g(S& s, int& r, void (S::* p2m)(int&)) {\n"
" (s.*p2m)(r);\n"
"}\n");
Expand Down Expand Up @@ -3775,7 +3772,7 @@ class TestOther : public TestFixture {
check("void f(int& i) {\n"
" new (&i) int();\n"
"}\n");
ASSERT_EQUALS("", errout.str()); // don't crash
TODO_ASSERT_EQUALS("", "[test.cpp:1]: (style) Parameter 'i' can be declared as reference to const\n", errout.str()); // don't crash

check("void f(int& i) {\n"
" int& r = i;\n"
Expand Down

0 comments on commit dbb28fa

Please sign in to comment.