Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #12217 (misra 11.4: report conversion in macro) #5692

Merged
merged 1 commit into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading