Skip to content

Commit ecf5e8b

Browse files
committed
Rule 1.2: Support aggregation of results at macro locations
Add a new module/library for identifying the macro that generated an element as the primary location, and use it for Rule 1.2 to avoid overreporting.
1 parent 9139b8e commit ecf5e8b

File tree

4 files changed

+51
-2
lines changed

4 files changed

+51
-2
lines changed

c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313

1414
import cpp
1515
import codingstandards.c.misra
16+
import codingstandards.cpp.AlertReporting
1617
import codingstandards.c.Extensions
1718

1819
from CCompilerExtension e
1920
where not isExcluded(e, Language3Package::languageExtensionsShouldNotBeUsedQuery())
20-
select e, e.getMessage()
21+
select MacroUnwrapper<CCompilerExtension>::unwrapElement(e), e.getMessage()

c/misra/test/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@
4848
| test.c:376:3:376:26 | call to __sync_lock_test_and_set_4 | Call to builtin function '__sync_lock_test_and_set_4' is a compiler extension and is not portable to other compilers. |
4949
| test.c:377:3:377:21 | call to __sync_lock_release_4 | Call to builtin function '__sync_lock_release_4' is a compiler extension and is not portable to other compilers. |
5050
| test.c:405:3:405:18 | call to __builtin_alloca | Call to builtin function '__builtin_alloca' is a compiler extension and is not portable to other compilers. |
51+
| test.c:409:1:411:8 | #define BUILTIN __builtin_alloca( 0) | Call to builtin function '__builtin_alloca' is a compiler extension and is not portable to other compilers. |

c/misra/test/rules/RULE-1-2/test.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,4 +404,10 @@ void gf47() { // NON_COMPLIANT in versions < C11.
404404
void gf48() {
405405
__builtin_alloca(
406406
0); // NON_COMPLIANT (all __builtin functions are non-compliant.)
407-
}
407+
}
408+
409+
#define BUILTIN \
410+
__builtin_alloca( \
411+
0) // NON_COMPLIANT (all __builtin functions are non-compliant.)
412+
413+
void gf49() { BUILTIN; }
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* Provides a library for managing how alerts are reported.
3+
*/
4+
5+
import cpp
6+
7+
signature class ResultType extends Element;
8+
9+
/**
10+
* A module for unwrapping results that occur in macro expansions.
11+
*/
12+
module MacroUnwrapper<ResultType ResultElement> {
13+
/**
14+
* Gets a macro invocation that applies to the result element.
15+
*/
16+
private MacroInvocation getAMacroInvocation(ResultElement re) {
17+
result.getAnExpandedElement() = re
18+
}
19+
20+
/**
21+
* Gets the primary macro that generated the result element.
22+
*/
23+
Macro getPrimaryMacro(ResultElement re) {
24+
exists(MacroInvocation mi |
25+
mi = getAMacroInvocation(re) and
26+
// No other more specific macro that expands to element
27+
not exists(MacroInvocation otherMi |
28+
otherMi = getAMacroInvocation(re) and otherMi.getParentInvocation() = mi
29+
) and
30+
result = mi.getMacro()
31+
)
32+
}
33+
34+
/**
35+
* If a result element is expanded from a macro invocation, then return the "primary" macro that
36+
* generated the element, otherwise return the element itself.
37+
*/
38+
Element unwrapElement(ResultElement re) {
39+
if exists(getPrimaryMacro(re)) then result = getPrimaryMacro(re) else result = re
40+
}
41+
}

0 commit comments

Comments
 (0)