@@ -18,37 +18,47 @@ import codingstandards.c.misra
1818import codingstandards.cpp.FunctionLikeMacro
1919import codingstandards.cpp.Naming
2020
21- predicate omission ( Macro i ) { Naming:: Cpp14:: hasStandardLibraryMacroName ( i .getName ( ) ) }
22-
2321abstract class IrreplaceableFunctionLikeMacro extends FunctionLikeMacro { }
2422
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. */
2534private class AsmArgumentInvoked extends IrreplaceableFunctionLikeMacro {
2635 AsmArgumentInvoked ( ) {
2736 any ( AsmStmt s ) .getLocation ( ) .subsumes ( this .getAnInvocation ( ) .getLocation ( ) )
2837 }
2938}
3039
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. */
3141private class OnlyConstantNumericInvoked extends IrreplaceableFunctionLikeMacro {
3242 OnlyConstantNumericInvoked ( ) {
3343 forex ( MacroInvocation mi | mi = this .getAnInvocation ( ) |
44+ //int/float literals
3445 mi .getUnexpandedArgument ( _) .regexpMatch ( "\\d+" )
46+ or
47+ //char/string literal
48+ mi .getUnexpandedArgument ( _) .regexpMatch ( "(\\'|\")+.*" )
3549 )
3650 }
3751}
3852
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. */
4554private class UsedToStaticInitialize extends IrreplaceableFunctionLikeMacro {
4655 UsedToStaticInitialize ( ) {
4756 any ( StaticStorageDurationVariable v ) .getInitializer ( ) .getExpr ( ) =
4857 this .getAnInvocation ( ) .getExpr ( )
4958 }
5059}
5160
61+ /** A function like macro that is called with an argument that is an operator that cannot be replaced with a function call. */
5262private class FunctionLikeMacroWithOperatorArgument extends IrreplaceableFunctionLikeMacro {
5363 FunctionLikeMacroWithOperatorArgument ( ) {
5464 exists ( MacroInvocation mi | mi .getMacro ( ) = this |
@@ -57,32 +67,6 @@ private class FunctionLikeMacroWithOperatorArgument extends IrreplaceableFunctio
5767 }
5868}
5969
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-
8670predicate partOfConstantExpr ( MacroInvocation i ) {
8771 exists ( Expr e |
8872 e .isConstant ( ) and
@@ -94,8 +78,6 @@ predicate partOfConstantExpr(MacroInvocation i) {
9478from FunctionLikeMacro m
9579where
9680 not isExcluded ( m , Preprocessor6Package:: functionOverFunctionLikeMacroQuery ( ) ) and
97- not omission ( m ) and
98- m instanceof UnsafeMacro and
9981 not m instanceof IrreplaceableFunctionLikeMacro and
10082 //function call not allowed in a constant expression (where constant expr is parent)
10183 forall ( MacroInvocation i | i = m .getAnInvocation ( ) | not partOfConstantExpr ( i ) )
0 commit comments