Skip to content

Commit

Permalink
Fix #12217 (misra 11.4: report conversion in macro) (danmar#5692)
Browse files Browse the repository at this point in the history
  • Loading branch information
danmar authored Nov 22, 2023
1 parent 693702d commit 727d086
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 3 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 lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5946,7 +5946,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

0 comments on commit 727d086

Please sign in to comment.