Skip to content

Commit 8973820

Browse files
committed
Preprocessor6: improve DIR-4-9
1 parent 055e83f commit 8973820

File tree

3 files changed

+32
-21
lines changed

3 files changed

+32
-21
lines changed

c/misra/src/rules/DIR-4-9/FunctionOverFunctionLikeMacro.ql

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@
1515

1616
import cpp
1717
import codingstandards.c.misra
18-
import codingstandards.cpp.FunctionLikeMacro
1918
import codingstandards.cpp.Naming
19+
import codingstandards.cpp.Macro
2020

2121
abstract class IrreplaceableFunctionLikeMacro extends FunctionLikeMacro { }
2222

2323
/** A standard library function like macro that contains the use of a stringize or tokenize operator should not be replaced by a function. */
2424
private class StringizeOrTokenizeMacro extends IrreplaceableFunctionLikeMacro {
25-
StringizeOrTokenizeMacro() { this.getBody().regexpMatch(".*\\#{1,2}?.*") }
25+
StringizeOrTokenizeMacro() {
26+
exists(TokenPastingOperator t | t.getMacro() = this) or
27+
exists(StringizingOperator s | s.getMacro() = this)
28+
}
2629
}
2730

2831
/** A standard library function like macro that should not be replaced by a function. */
@@ -38,14 +41,14 @@ private class AsmArgumentInvoked extends IrreplaceableFunctionLikeMacro {
3841
}
3942

4043
/** A macro that is only invoked with constant arguments is more likely to be compile-time evaluated than a function call so do not suggest replacement. */
41-
private class OnlyConstantNumericInvoked extends IrreplaceableFunctionLikeMacro {
42-
OnlyConstantNumericInvoked() {
44+
private class OnlyConstantArgsInvoked extends IrreplaceableFunctionLikeMacro {
45+
OnlyConstantArgsInvoked() {
4346
forex(MacroInvocation mi | mi = this.getAnInvocation() |
4447
//int/float literals
4548
mi.getUnexpandedArgument(_).regexpMatch("\\d+")
4649
or
47-
//char/string literal
48-
mi.getUnexpandedArgument(_).regexpMatch("(\\'|\")+.*")
50+
//char literal or string literal, which is a literal surrounded by single quotes or double quotes
51+
mi.getUnexpandedArgument(_).regexpMatch("('[^']*'|\"[^\"]*\")")
4952
)
5053
}
5154
}
@@ -79,6 +82,8 @@ from FunctionLikeMacro m
7982
where
8083
not isExcluded(m, Preprocessor6Package::functionOverFunctionLikeMacroQuery()) and
8184
not m instanceof IrreplaceableFunctionLikeMacro and
85+
//macros can have empty body
86+
not m.getBody().length() = 0 and
8287
//function call not allowed in a constant expression (where constant expr is parent)
8388
forall(MacroInvocation i | i = m.getAnInvocation() | not partOfConstantExpr(i))
84-
select m, "Macro used when function call would be preferred."
89+
select m, "Macro used when function call would be preferred.", m.getBody().length()
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
| test.c:4:1:6:12 | #define MACRO4(L) (L" " "suffix") | Macro used when function call would be preferred. |
1+
| test.c:4:1:4:25 | #define MACRO4(x) (x + 1) | Macro used when function call would be preferred. | 7 |
2+
| test.c:9:1:9:48 | #define MACRO9() printf_custom("output = %d", 7) | Macro used when function call would be preferred. | 31 |

c/misra/test/rules/DIR-4-9/test.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
#define MACRO(OP, L, R) ((L)OP(R)) // COMPLIANT
2-
#define MACRO2(L, R) (L + R) // COMPLIANT
3-
#define MACRO3(L, R) (L " " R " " L) // COMPLIANT
4-
#define MACRO4(L) \
5-
(L" " \
6-
"suffix") // NON_COMPLIANT
7-
#define MACRO5(L, LR) (LR + 1) // COMPLIANT
8-
#define MACRO6(X, LR) (LR + 1) // COMPLIANT
9-
#define MACRO7(x, y) x##y // COMPLIANT
1+
#define MACRO(OP, L, R) ((L)OP(R)) // COMPLIANT
2+
#define MACRO2(L, R) (L + R) // COMPLIANT
3+
#define MACRO3(L, R) (L " " R " " L) // COMPLIANT
4+
#define MACRO4(x) (x + 1) // NON_COMPLIANT
5+
#define MACRO5(L, LR) (LR + 1) // COMPLIANT
6+
#define MACRO6(x) printf_custom("output = %d", test##x) // COMPLIANT
7+
#define MACRO7(x) #x // COMPLIANT
8+
#define MACRO8(x) "NOP" // COMPLIANT
9+
#define MACRO9() printf_custom("output = %d", 7) // NON_COMPLIANT
10+
#define MACRO10(x) // COMPLIANT
1011

1112
const char a1[MACRO2(1, 1) + 6];
13+
extern printf_custom();
14+
int test1;
1215

1316
void f() {
1417
int i = MACRO(+, 1, 1);
@@ -18,13 +21,15 @@ void f() {
1821

1922
char *i4 = MACRO3("prefix", "suffix");
2023

21-
char *i5 = MACRO4("prefix");
24+
int i5 = MACRO4(1);
2225

23-
char *i6 = MACRO4(MACRO2(1, 1));
26+
int i6 = MACRO4(MACRO2(1, 1));
2427

2528
int i7 = MACRO5(1, 1);
2629

27-
int i8 = MACRO6(1, 1);
30+
MACRO6(1);
2831

29-
char *i9 = MACRO7("prefix", "suffix");
32+
char *i10 = MACRO7("prefix");
33+
34+
asm(MACRO8(1));
3035
}

0 commit comments

Comments
 (0)