@@ -18,37 +18,47 @@ import codingstandards.c.misra
18
18
import codingstandards.cpp.FunctionLikeMacro
19
19
import codingstandards.cpp.Naming
20
20
21
- predicate omission ( Macro i ) { Naming:: Cpp14:: hasStandardLibraryMacroName ( i .getName ( ) ) }
22
-
23
21
abstract class IrreplaceableFunctionLikeMacro extends FunctionLikeMacro { }
24
22
23
+ /** A standard library function like macro that contains the use of a stringize or tokenize operator should not be replaced by a function. */
24
+ private class StringizeOrTokenizeMacro extends IrreplaceableFunctionLikeMacro {
25
+ StringizeOrTokenizeMacro ( ) { this .getBody ( ) .regexpMatch ( ".*\\#{1,2}?.*" ) }
26
+ }
27
+
28
+ /** A standard library function like macro that should not be replaced by a function. */
29
+ private class StandardLibraryFunctionLikeMacro extends IrreplaceableFunctionLikeMacro {
30
+ StandardLibraryFunctionLikeMacro ( ) { Naming:: Cpp14:: hasStandardLibraryMacroName ( this .getName ( ) ) }
31
+ }
32
+
33
+ /** A function like macro invocation as an `asm` argument cannot be replaced by a function. */
25
34
private class AsmArgumentInvoked extends IrreplaceableFunctionLikeMacro {
26
35
AsmArgumentInvoked ( ) {
27
36
any ( AsmStmt s ) .getLocation ( ) .subsumes ( this .getAnInvocation ( ) .getLocation ( ) )
28
37
}
29
38
}
30
39
40
+ /** 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. */
31
41
private class OnlyConstantNumericInvoked extends IrreplaceableFunctionLikeMacro {
32
42
OnlyConstantNumericInvoked ( ) {
33
43
forex ( MacroInvocation mi | mi = this .getAnInvocation ( ) |
44
+ //int/float literals
34
45
mi .getUnexpandedArgument ( _) .regexpMatch ( "\\d+" )
46
+ or
47
+ //char/string literal
48
+ mi .getUnexpandedArgument ( _) .regexpMatch ( "(\\'|\")+.*" )
35
49
)
36
50
}
37
51
}
38
52
39
- private class KnownIrreplaceableFunctionLikeMacro extends IrreplaceableFunctionLikeMacro {
40
- KnownIrreplaceableFunctionLikeMacro ( ) {
41
- this .getName ( ) in [ "UNUSED" , "__has_builtin" , "MIN" , "MAX" ]
42
- }
43
- }
44
-
53
+ /** A function like macro invoked to initialize an object with static storage that cannot be replaced with a function call. */
45
54
private class UsedToStaticInitialize extends IrreplaceableFunctionLikeMacro {
46
55
UsedToStaticInitialize ( ) {
47
56
any ( StaticStorageDurationVariable v ) .getInitializer ( ) .getExpr ( ) =
48
57
this .getAnInvocation ( ) .getExpr ( )
49
58
}
50
59
}
51
60
61
+ /** A function like macro that is called with an argument that is an operator that cannot be replaced with a function call. */
52
62
private class FunctionLikeMacroWithOperatorArgument extends IrreplaceableFunctionLikeMacro {
53
63
FunctionLikeMacroWithOperatorArgument ( ) {
54
64
exists ( MacroInvocation mi | mi .getMacro ( ) = this |
@@ -57,32 +67,6 @@ private class FunctionLikeMacroWithOperatorArgument extends IrreplaceableFunctio
57
67
}
58
68
}
59
69
60
- abstract class UnsafeMacro extends FunctionLikeMacro { }
61
-
62
- class ParameterNotUsedMacro extends UnsafeMacro {
63
- ParameterNotUsedMacro ( ) {
64
- //parameter not used - has false positives on args that are not used but are substrings of other args
65
- exists ( string p |
66
- p = this .getAParameter ( ) and
67
- not this .getBody ( ) .regexpMatch ( ".*(\\s*|\\(|\\)|\\##)" + p + "(\\s*||\\)|\\(|\\##).*" )
68
- )
69
- }
70
- }
71
-
72
- class ParameterMoreThanOnceMacro extends UnsafeMacro {
73
- ParameterMoreThanOnceMacro ( ) {
74
- //parameter used more than once
75
- exists ( string p |
76
- p = this .getAParameter ( ) and
77
- exists ( int i , string newstr |
78
- newstr = this .getBody ( ) .replaceAll ( p , "" ) and
79
- i = ( ( this .getBody ( ) .length ( ) - newstr .length ( ) ) / p .length ( ) ) and
80
- i > 1
81
- )
82
- )
83
- }
84
- }
85
-
86
70
predicate partOfConstantExpr ( MacroInvocation i ) {
87
71
exists ( Expr e |
88
72
e .isConstant ( ) and
@@ -94,8 +78,6 @@ predicate partOfConstantExpr(MacroInvocation i) {
94
78
from FunctionLikeMacro m
95
79
where
96
80
not isExcluded ( m , Preprocessor6Package:: functionOverFunctionLikeMacroQuery ( ) ) and
97
- not omission ( m ) and
98
- m instanceof UnsafeMacro and
99
81
not m instanceof IrreplaceableFunctionLikeMacro and
100
82
//function call not allowed in a constant expression (where constant expr is parent)
101
83
forall ( MacroInvocation i | i = m .getAnInvocation ( ) | not partOfConstantExpr ( i ) )
0 commit comments