Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fde0df0

Browse filesBrowse files
authored
Merge pull request #29 from knewbury01/knewbury01/Preprocessor5
Package Preprocessor 5
2 parents 6135896 + fb74797 commit fde0df0
Copy full SHA for fde0df0

File tree

33 files changed

+652
-60
lines changed
Filter options

33 files changed

+652
-60
lines changed

‎.vscode/tasks.json

Copy file name to clipboardExpand all lines: .vscode/tasks.json
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@
224224
"Preprocessor2",
225225
"Preprocessor3",
226226
"Preprocessor4",
227+
"Preprocessor5",
227228
"IntegerConversion",
228229
"Expressions",
229230
"DeadCode",
+112Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# MSC38-C: Do not treat a predefined identifier as an object if it might only be implemented as a macro
2+
3+
This query implements the CERT-C rule MSC38-C:
4+
5+
> Do not treat a predefined identifier as an object if it might only be implemented as a macro
6+
7+
8+
## Description
9+
10+
The C Standard, 7.1.4 paragraph 1, \[[ISO/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO%2FIEC9899-2011)\] states
11+
12+
> Any function declared in a header may be additionally implemented as a function-like macro defined in the header, so if a library function is declared explicitly when its header is included, one of the techniques shown below can be used to ensure the declaration is not affected by such a macro. Any macro definition of a function can be suppressed locally by enclosing the name of the function in parentheses, because the name is then not followed by the left parenthesis that indicates expansion of a macro function name. For the same syntactic reason, it is permitted to take the address of a library function even if it is also defined as a macro.<sup>185</sup>
13+
14+
15+
185. This means that an implementation shall provide an actual function for each library function, even if it also provides a macro for that function.
16+
17+
However, the C Standard enumerates specific exceptions in which the behavior of accessing an object or function expanded to be a standard library macro definition is [undefined](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior). The macros are `assert`, `errno`, `math_errhandling`, `setjmp`, `va_arg`, `va_copy`, `va_end`, and `va_start`. These cases are described by [undefined behaviors](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior) [110](https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior#CC.UndefinedBehavior-ub_110), [114](https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior#CC.UndefinedBehavior-ub_114), [122](https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior#CC.UndefinedBehavior-ub_122), [124](https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior#CC.UndefinedBehavior-ub_124), and [138](https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior#CC.UndefinedBehavior-ub_138). Programmers must not suppress these macros to access the underlying object or function.
18+
19+
## Noncompliant Code Example (assert)
20+
21+
In this noncompliant code example, the standard `assert()` macro is suppressed in an attempt to pass it as a function pointer to the `execute_handler()` function. Attempting to suppress the `assert()` macro is [undefined behavior](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior).
22+
23+
```cpp
24+
#include <assert.h>
25+
26+
typedef void (*handler_type)(int);
27+
28+
void execute_handler(handler_type handler, int value) {
29+
handler(value);
30+
}
31+
32+
void func(int e) {
33+
execute_handler(&(assert), e < 0);
34+
}
35+
```
36+
37+
## Compliant Solution (assert)
38+
39+
In this compliant solution, the `assert()` macro is wrapped in a helper function, removing the [undefined behavior](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior):
40+
41+
```cpp
42+
#include <assert.h>
43+
44+
typedef void (*handler_type)(int);
45+
46+
void execute_handler(handler_type handler, int value) {
47+
handler(value);
48+
}
49+
50+
static void assert_handler(int value) {
51+
assert(value);
52+
}
53+
54+
void func(int e) {
55+
execute_handler(&assert_handler, e < 0);
56+
}
57+
```
58+
59+
## Noncompliant Code Example (Redefining errno)
60+
61+
Legacy code is apt to include an incorrect declaration, such as the following in this noncompliant code example:
62+
63+
```cpp
64+
extern int errno;
65+
66+
```
67+
68+
## Compliant Solution (Declaring errno)
69+
70+
This compliant solution demonstrates the correct way to declare `errno` by including the header `<errno.h>`:
71+
72+
```cpp
73+
#include <errno.h>
74+
75+
```
76+
[C-conforming](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-conformingprogram) [implementations](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-implementation) are required to declare `errno` in `<errno.h>`, although some historic implementations failed to do so.
77+
78+
## Risk Assessment
79+
80+
Accessing objects or functions underlying the specific macros enumerated in this rule is [undefined behavior](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior).
81+
82+
<table> <tbody> <tr> <th> Rule </th> <th> Severity </th> <th> Likelihood </th> <th> Remediation Cost </th> <th> Priority </th> <th> Level </th> </tr> <tr> <td> MSC38-C </td> <td> Low </td> <td> Unlikely </td> <td> Medium </td> <td> <strong>P2</strong> </td> <td> <strong>L3</strong> </td> </tr> </tbody> </table>
83+
84+
85+
## Automated Detection
86+
87+
<table> <tbody> <tr> <th> Tool </th> <th> Version </th> <th> Checker </th> <th> Description </th> </tr> <tr> <td> <a> Astrée </a> </td> <td> 22.04 </td> <td> </td> <td> Supported, but no explicit checker </td> </tr> <tr> <td> <a> CodeSonar </a> </td> <td> 7.0p0 </td> <td> <strong>BADMACRO.STDARG_H</strong> </td> <td> Use of &lt;stdarg.h&gt; Feature </td> </tr> <tr> <td> <a> Helix QAC </a> </td> <td> 2022.2 </td> <td> <strong>C3437, C3475</strong> <strong>C++3127, C++5039</strong> </td> <td> </td> </tr> <tr> <td> <a> Parasoft C/C++test </a> </td> <td> 2022.1 </td> <td> <strong>CERT_C-MSC38-a</strong> </td> <td> A function-like macro shall not be invoked without all of its arguments </td> </tr> <tr> <td> <a> Polyspace Bug Finder </a> </td> <td> R2022a </td> <td> <a> CERT C: Rule MSC38-C </a> </td> <td> Checks for predefined macro used as an object (rule fully covered) </td> </tr> <tr> <td> <a> PRQA QA-C </a> </td> <td> 9.7 </td> <td> <strong>3437, 3475</strong> </td> <td> </td> </tr> <tr> <td> <a> RuleChecker </a> </td> <td> 22.04 </td> <td> </td> <td> Supported, but no explicit checker </td> </tr> </tbody> </table>
88+
89+
90+
## Related Vulnerabilities
91+
92+
Search for [vulnerabilities](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-vulnerability) resulting from the violation of this rule on the [CERT website](https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+MSC38-C).
93+
94+
## Related Guidelines
95+
96+
[Key here](https://wiki.sei.cmu.edu/confluence/display/c/How+this+Coding+Standard+is+Organized#HowthisCodingStandardisOrganized-RelatedGuidelines) (explains table format and definitions)
97+
98+
<table> <tbody> <tr> <th> Taxonomy </th> <th> Taxonomy item </th> <th> Relationship </th> </tr> <tr> <td> <a> CERT C </a> </td> <td> <a> DCL37-C. Do not declare or define a reserved identifier </a> </td> <td> Prior to 2018-01-12: CERT: Unspecified Relationship </td> </tr> </tbody> </table>
99+
100+
101+
## Bibliography
102+
103+
<table> <tbody> <tr> <td> <a> ISO/IEC 9899:2011 </a> </td> <td> 7.1.4, "Use of Library Functions" </td> </tr> </tbody> </table>
104+
105+
106+
## Implementation notes
107+
108+
This query reports locations corresponding to both redefinitions of those standard library macros as well as locations where the identifiers used for accesses.
109+
110+
## References
111+
112+
* CERT-C: [MSC38-C: Do not treat a predefined identifier as an object if it might only be implemented as a macro](https://wiki.sei.cmu.edu/confluence/display/c)
+45Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* @id c/cert/do-not-treat-a-predefined-identifier-as-object
3+
* @name MSC38-C: Do not treat a predefined identifier as an object if it might only be implemented as a macro
4+
* @description Accessing an object or function that expands to one of a few specific standard
5+
* library macros is undefined behaviour.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity warning
9+
* @tags external/cert/id/msc38-c
10+
* correctness
11+
* readability
12+
* external/cert/obligation/rule
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.cert
17+
18+
predicate hasRestrictedMacroName(string s) {
19+
s = "assert"
20+
or
21+
s = "errno"
22+
or
23+
s = "math_errhandling"
24+
or
25+
s = "setjmp"
26+
or
27+
s = "va_arg"
28+
or
29+
s = "va_copy"
30+
or
31+
s = "va_end"
32+
or
33+
s = "va_start"
34+
}
35+
36+
from Element m, string name
37+
where
38+
not isExcluded(m, Preprocessor5Package::doNotTreatAPredefinedIdentifierAsObjectQuery()) and
39+
(
40+
m.(Access).getTarget().hasName(name)
41+
or
42+
m.(Declaration).hasGlobalName(name)
43+
) and
44+
hasRestrictedMacroName(name)
45+
select m, "Supression of standard library macro " + name + "."
+89Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# PRE32-C: Do not use preprocessor directives in invocations of function-like macros
2+
3+
This query implements the CERT-C rule PRE32-C:
4+
5+
> Do not use preprocessor directives in invocations of function-like macros
6+
7+
8+
## Description
9+
10+
The arguments to a macro must not include preprocessor directives, such as `#define`, `#ifdef`, and `#include`. Doing so results in [undefined behavior](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-undefinedbehavior), according to the C Standard, 6.10.3, paragraph 11 \[[ISO/IEC 9899:2011](https://wiki.sei.cmu.edu/confluence/display/c/AA.+Bibliography#AA.Bibliography-ISO-IEC9899-2011)\]:
11+
12+
> The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments. **If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives, the behavior is undefined.**
13+
14+
15+
See also [undefined behavior 93](https://wiki.sei.cmu.edu/confluence/display/c/CC.+Undefined+Behavior#CC.UndefinedBehavior-ub_93).
16+
17+
This rule also applies to the use of preprocessor directives in arguments to any function where it is unknown whether or not the function is implemented using a macro. This includes all standard library functions, such as `memcpy()`, `printf()`, and `assert()`, because any standard library function may be implemented as a macro. (C11, 7.1.4, paragraph 1).
18+
19+
## Noncompliant Code Example
20+
21+
In this noncompliant code example \[[GCC Bugs](http://gcc.gnu.org/bugs.html#nonbugs_c)\], the programmer uses preprocessor directives to specify platform-specific arguments to `memcpy()`. However, if `memcpy()` is implemented using a macro, the code results in undefined behavior.
22+
23+
```cpp
24+
#include <string.h>
25+
26+
void func(const char *src) {
27+
/* Validate the source string; calculate size */
28+
char *dest;
29+
/* malloc() destination string */
30+
memcpy(dest, src,
31+
#ifdef PLATFORM1
32+
12
33+
#else
34+
24
35+
#endif
36+
);
37+
/* ... */
38+
}
39+
40+
```
41+
42+
## Compliant Solution
43+
44+
In this compliant solution \[[GCC Bugs](http://gcc.gnu.org/bugs.html#nonbugs_c)\], the appropriate call to `memcpy()` is determined outside the function call:
45+
46+
```cpp
47+
#include <string.h>
48+
49+
void func(const char *src) {
50+
/* Validate the source string; calculate size */
51+
char *dest;
52+
/* malloc() destination string */
53+
#ifdef PLATFORM1
54+
memcpy(dest, src, 12);
55+
#else
56+
memcpy(dest, src, 24);
57+
#endif
58+
/* ... */
59+
}
60+
```
61+
62+
## Risk Assessment
63+
64+
Including preprocessor directives in macro arguments is undefined behavior.
65+
66+
<table> <tbody> <tr> <th> Rule </th> <th> Severity </th> <th> Likelihood </th> <th> Remediation Cost </th> <th> Priority </th> <th> Level </th> </tr> <tr> <td> PRE32-C </td> <td> Low </td> <td> Unlikely </td> <td> Medium </td> <td> <strong>P2</strong> </td> <td> <strong>L3</strong> </td> </tr> </tbody> </table>
67+
68+
69+
## Automated Detection
70+
71+
<table> <tbody> <tr> <th> Tool </th> <th> Version </th> <th> Checker </th> <th> Description </th> </tr> <tr> <td> <a> Astrée </a> </td> <td> 22.04 </td> <td> <strong>macro-argument-hash</strong> </td> <td> Fully checked </td> </tr> <tr> <td> <a> Axivion Bauhaus Suite </a> </td> <td> 7.2.0 </td> <td> <strong>CertC-PRE32</strong> </td> <td> Fully implemented </td> </tr> <tr> <td> <a> CodeSonar </a> </td> <td> 7.0p0 </td> <td> <strong>LANG.PREPROC.MACROARG</strong> </td> <td> Preprocessing directives in macro argument </td> </tr> <tr> <td> <a> ECLAIR </a> </td> <td> 1.2 </td> <td> <strong>CC2.PRE32</strong> </td> <td> Fully implemented </td> </tr> <tr> <td> <a> Helix QAC </a> </td> <td> 2022.2 </td> <td> <strong>C0853</strong> <strong>C++1072</strong> </td> <td> </td> </tr> <tr> <td> <a> Klocwork </a> </td> <td> 2022.2 </td> <td> <strong>MISRA.EXPANSION.DIRECTIVE</strong> </td> <td> </td> </tr> <tr> <td> <a> LDRA tool suite </a> </td> <td> 9.7.1 </td> <td> <strong>341 S</strong> </td> <td> Fully implemented </td> </tr> <tr> <td> <a> Parasoft C/C++test </a> </td> <td> 2022.1 </td> <td> <strong>CERT_C-PRE32-a</strong> </td> <td> Arguments to a function-like macro shall not contain tokens that look like preprocessing directives </td> </tr> <tr> <td> <a> PC-lint Plus </a> </td> <td> 1.4 </td> <td> <strong>436, 9501</strong> </td> <td> Fully supported </td> </tr> <tr> <td> <a> Polyspace Bug Finder </a> </td> <td> R2022a </td> <td> <a> CERT C: Rule PRE32-C </a> </td> <td> Checks for preprocessor directive in macro argument (rule fully covered) </td> </tr> <tr> <td> <a> PRQA QA-C </a> </td> <td> 9.7 </td> <td> <strong>0853</strong> </td> <td> </td> </tr> <tr> <td> <a> PRQA QA-C++ </a> </td> <td> 4.4 </td> <td> <strong>1072 </strong> </td> <td> </td> </tr> <tr> <td> <a> RuleChecker </a> </td> <td> 22.04 </td> <td> <strong>macro-argument-hash</strong> </td> <td> Fully checked </td> </tr> </tbody> </table>
72+
73+
74+
## Related Vulnerabilities
75+
76+
Search for [vulnerabilities](https://wiki.sei.cmu.edu/confluence/display/c/BB.+Definitions#BB.Definitions-vulnerability) resulting from the violation of this rule on the [CERT website](https://www.kb.cert.org/vulnotes/bymetric?searchview&query=FIELD+KEYWORDS+contains+PRE32-C).
77+
78+
## Bibliography
79+
80+
<table> <tbody> <tr> <td> \[ <a> GCC Bugs </a> \] </td> <td> "Non-bugs" </td> </tr> <tr> <td> \[ <a> ISO/IEC 9899:2011 </a> \] </td> <td> 6.10.3, "Macro Replacement" </td> </tr> </tbody> </table>
81+
82+
83+
## Implementation notes
84+
85+
This query defines end of function call as the next node in the control flow graph.
86+
87+
## References
88+
89+
* CERT-C: [PRE32-C: Do not use preprocessor directives in invocations of function-like macros](https://wiki.sei.cmu.edu/confluence/display/c)
+63Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* @id c/cert/macro-or-function-args-contain-hash-token
3+
* @name PRE32-C: Do not use preprocessor directives in invocations of function-like macros
4+
* @description Arguments to a function-like macros shall not contain tokens that look like
5+
* pre-processing directives or else behaviour after macro expansion is unpredictable.
6+
* This rule applies to functions as well in case they are implemented using macros.
7+
* @kind problem
8+
* @precision high
9+
* @problem.severity warning
10+
* @tags external/cert/id/pre32-c
11+
* correctness
12+
* readability
13+
* external/cert/obligation/rule
14+
*/
15+
16+
import cpp
17+
import codingstandards.c.cert
18+
import codingstandards.cpp.PreprocessorDirective
19+
20+
pragma[noinline]
21+
predicate isFunctionInvocationLocation(FunctionCall call, File f, int startline, int endline) {
22+
call.getLocation().hasLocationInfo(f.getAbsolutePath(), startline, _, _, _) and
23+
isFunctionSuccessorLocation(call.getASuccessor(), f, endline)
24+
}
25+
26+
pragma[noinline]
27+
predicate isFunctionSuccessorLocation(ControlFlowNode node, File f, int endline) {
28+
//for all function calls the closest location heurisitc we have for end line is the next node in cfg
29+
node.getLocation().hasLocationInfo(f.getAbsolutePath(), endline, _, _, _)
30+
}
31+
32+
PreprocessorDirective isLocatedInAFunctionInvocation(FunctionCall c) {
33+
exists(PreprocessorDirective p, File f, int startCall, int endCall |
34+
isFunctionInvocationLocation(c, f, startCall, endCall) and
35+
exists(int startLine, int endLine | isPreprocDirectiveLine(p, f, startLine, endLine) |
36+
startCall < startLine and
37+
startCall < endLine and
38+
endLine <= endCall and
39+
endLine <= endCall
40+
) and
41+
result = p
42+
)
43+
}
44+
45+
from PreprocessorDirective p, string msg
46+
where
47+
not isExcluded(p, Preprocessor5Package::macroOrFunctionArgsContainHashTokenQuery()) and
48+
exists(FunctionCall c |
49+
p = isLocatedInAFunctionInvocation(c) and
50+
//if this is actually a function in a macro ignore it because it will still be seen in the macro condition
51+
not c.isInMacroExpansion() and
52+
msg =
53+
"Invocation of function " + c.getTarget().getName() + " includes a token \"" + p +
54+
"\" that could be confused for an argument preprocessor directive."
55+
)
56+
or
57+
exists(MacroInvocation m |
58+
p = isLocatedInAMacroInvocation(m) and
59+
msg =
60+
"Invocation of macro " + m.getMacroName() + " includes a token \"" + p +
61+
"\" that could be confused for an argument preprocessor directive."
62+
)
63+
select p, msg
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| assert.h:2:6:2:11 | assert | Supression of standard library macro assert. |
2+
| test.c:3:12:3:16 | errno | Supression of standard library macro errno. |
3+
| test.c:10:21:10:26 | assert | Supression of standard library macro assert. |
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/MSC38-C/DoNotTreatAPredefinedIdentifierAsObject.ql

‎c/cert/test/rules/MSC38-C/assert.h

Copy file name to clipboard
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#undef assert
2+
void assert(int i); // NON_COMPLIANT
3+
4+
#define assert(x) (void)0

‎c/cert/test/rules/MSC38-C/test.c

Copy file name to clipboard
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include "assert.h"
2+
3+
extern int errno; // NON_COMPLIANT
4+
5+
typedef void (*handler_type)(int);
6+
7+
void execute_handler(handler_type handler, int value) { handler(value); }
8+
9+
void f(int e) {
10+
execute_handler(&(assert), e < 0); // NON_COMPLIANT
11+
}
12+
13+
static void assert_handler(int value) { assert(value); }
14+
15+
void f2(int e) {
16+
execute_handler(&assert_handler, e < 0); // COMPLIANT
17+
}
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
| test.c:9:1:9:19 | #if NOTDEFINEDMACRO | Invocation of macro MACROFUNCTION includes a token "#if NOTDEFINEDMACRO" that could be confused for an argument preprocessor directive. |
2+
| test.c:11:1:11:5 | #else | Invocation of macro MACROFUNCTION includes a token "#else" that could be confused for an argument preprocessor directive. |
3+
| test.c:13:1:13:6 | #endif | Invocation of macro MACROFUNCTION includes a token "#endif" that could be confused for an argument preprocessor directive. |
4+
| test.c:20:1:20:16 | #ifdef SOMEMACRO | Invocation of function memcpy includes a token "#ifdef SOMEMACRO" that could be confused for an argument preprocessor directive. |
5+
| test.c:22:1:22:5 | #else | Invocation of function memcpy includes a token "#else" that could be confused for an argument preprocessor directive. |
6+
| test.c:24:1:24:6 | #endif | Invocation of function memcpy includes a token "#endif" that could be confused for an argument preprocessor directive. |
7+
| test.c:27:1:27:8 | #if TEST | Invocation of function memcpy includes a token "#if TEST" that could be confused for an argument preprocessor directive. |
8+
| test.c:28:1:28:6 | #endif | Invocation of function memcpy includes a token "#endif" that could be confused for an argument preprocessor directive. |
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/PRE32-C/MacroOrFunctionArgsContainHashToken.ql

‎c/cert/test/rules/PRE32-C/test.c

Copy file name to clipboard
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
#include <string.h>
3+
#define MACROFUNCTION(X) strlen(X)
4+
5+
void func(const char *src) {
6+
char *dest;
7+
8+
MACROFUNCTION(
9+
#if NOTDEFINEDMACRO // NON_COMPLIANT
10+
"longstringtest!test!"
11+
#else // NON_COMPLIANT
12+
"shortstring"
13+
#endif // NON_COMPLIANT
14+
);
15+
16+
MACROFUNCTION("alright"); // COMPLIANT
17+
memcpy(dest, src, 12); // COMPLIANT
18+
19+
memcpy(dest, src,
20+
#ifdef SOMEMACRO // NON_COMPLIANT
21+
12
22+
#else // NON_COMPLIANT
23+
24
24+
#endif // NON_COMPLIANT
25+
);
26+
27+
#if TEST // COMPLIANT[FALSE_POSITIVE]
28+
#endif // COMPLIANT[FALSE_POSITIVE]
29+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.