Skip to content

Commit d3e1704

Browse files
Merge remote-tracking branch 'origin/main' into michaelrfairhurst/implement-missing-sin-precision-amendment
2 parents 0a64609 + 0fd4496 commit d3e1704

File tree

70 files changed

+3177
-1135
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+3177
-1135
lines changed

amendments.csv

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
language,standard,amendment,rule_id,supportable,implementation_category,implemented,difficulty
22
c,MISRA-C-2012,Amendment3,DIR-4-6,Yes,Expand,Yes,Easy
3-
c,MISRA-C-2012,Amendment3,DIR-4-9,Yes,Refine,No,Easy
3+
c,MISRA-C-2012,Amendment3,DIR-4-9,Yes,Refine,Yes,Easy
44
c,MISRA-C-2012,Amendment3,DIR-4-11,Yes,Refine,Yes,Import
5-
c,MISRA-C-2012,Amendment3,RULE-1-4,Yes,Replace,No,Easy
5+
c,MISRA-C-2012,Amendment3,RULE-1-4,Yes,Replace,Yes,Easy
66
c,MISRA-C-2012,Amendment3,RULE-10-1,Yes,Replace,Yes,Easy
77
c,MISRA-C-2012,Amendment3,RULE-10-3,Yes,Refine,Yes,Easy
88
c,MISRA-C-2012,Amendment3,RULE-10-4,Yes,Refine,Yes,Import
99
c,MISRA-C-2012,Amendment3,RULE-10-5,Yes,Expand,Yes,Easy
1010
c,MISRA-C-2012,Amendment3,RULE-10-7,Yes,Refine,Yes,Import
1111
c,MISRA-C-2012,Amendment3,RULE-10-8,Yes,Refine,Yes,Import
1212
c,MISRA-C-2012,Amendment3,RULE-21-11,Yes,Clarification,Yes,Import
13-
c,MISRA-C-2012,Amendment3,RULE-21-12,Yes,Replace,No,Easy
13+
c,MISRA-C-2012,Amendment3,RULE-21-12,Yes,Replace,Yes,Easy
1414
c,MISRA-C-2012,Amendment4,RULE-11-3,Yes,Expand,Yes,Easy
1515
c,MISRA-C-2012,Amendment4,RULE-11-8,Yes,Expand,Yes,Easy
1616
c,MISRA-C-2012,Amendment4,RULE-13-2,Yes,Expand,Yes,Very Hard
17-
c,MISRA-C-2012,Amendment4,RULE-18-6,Yes,Expand,No,Medium
17+
c,MISRA-C-2012,Amendment4,RULE-18-6,Yes,Expand,Yes,Medium
1818
c,MISRA-C-2012,Amendment4,RULE-18-8,Yes,Split,Yes,Easy
1919
c,MISRA-C-2012,Amendment4,RULE-2-2,Yes,Clarification,Yes,Import
2020
c,MISRA-C-2012,Amendment4,RULE-2-7,Yes,Clarification,Yes,Import
@@ -26,7 +26,6 @@ c,MISRA-C-2012,Amendment4,RULE-10-1,Yes,Clarification,Yes,Import
2626
c,MISRA-C-2012,Amendment4,RULE-18-3,Yes,Clarification,Yes,Import
2727
c,MISRA-C-2012,Amendment4,RULE-1-4,Yes,Replace,No,Easy
2828
c,MISRA-C-2012,Amendment4,RULE-9-1,Yes,Refine,Yes,Easy
29-
c,MISRA-C-2012,Amendment4,RULE-9-2,Yes,Refine,No,Import
3029
c,MISRA-C-2012,Corrigendum2,DIR-4-10,Yes,Clarification,Yes,Import
3130
c,MISRA-C-2012,Corrigendum2,RULE-7-4,Yes,Refine,Yes,Easy
3231
c,MISRA-C-2012,Corrigendum2,RULE-8-2,Yes,Clarification,Yes,Import
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/**
2+
* A library that expands upon the `Objects.qll` library, to support nested "Objects" such as
3+
* `x.y.z` or `x[i][j]` within an object `x`.
4+
*
5+
* Objects in C are values in memory, that have a type and a storage duration. In the case of
6+
* array objects and struct objects, the object will contain other objects. The these subobjects
7+
* will share properties of the root object such as storage duration. This library can be used to,
8+
* for instance, find all usages of a struct member to ensure that member is initialized before it
9+
* is used.
10+
*
11+
* To use this library, select `SubObject` and find its usages in the AST via `getAnAccess()` (to
12+
* find usages of the subobject by value) or `getAnAddressOfExpr()` (to find usages of the object
13+
* by address).
14+
*
15+
* Note that a struct or array object may contain a pointer. In this case, the pointer itself is
16+
* a subobject of the struct or array object, but the object that the pointer points to is not.
17+
* This is because the pointed-to object does not necessarily have the same storage duration,
18+
* lifetime, or linkage as the pointer and the object containing the pointer.
19+
*
20+
* Note as well that `getAnAccess()` on an array subobject will return all accesses to the array,
21+
* not just accesses to a particular index. For this reason, `SubObject` exposes the predicate
22+
* `isPrecise()`. If a subobject is precise, that means all results of `getAnAccess()` will
23+
* definitely refer to the same object in memory. If it is not precise, the different accesses
24+
* may refer to the same or different objects in memory. For instance, `x[i].y` and `x[j].y` are
25+
* the same object if `i` and `j` are the same, but they are different objects if `i` and `j` are
26+
* different.
27+
*/
28+
29+
import codingstandards.c.Objects
30+
31+
newtype TSubObject =
32+
TObjectRoot(ObjectIdentity i) or
33+
TObjectMember(SubObject struct, MemberVariable m) {
34+
m = struct.getType().(Struct).getAMemberVariable()
35+
} or
36+
TObjectIndex(SubObject array) { array.getType() instanceof ArrayType }
37+
38+
class SubObject extends TSubObject {
39+
string toString() {
40+
exists(ObjectIdentity i |
41+
this = TObjectRoot(i) and
42+
result = i.toString()
43+
)
44+
or
45+
exists(SubObject struct, Variable m |
46+
this = TObjectMember(struct, m) and
47+
result = struct.toString() + "." + m.getName()
48+
)
49+
or
50+
exists(SubObject array |
51+
this = TObjectIndex(array) and
52+
result = array.toString()
53+
)
54+
}
55+
56+
Type getType() {
57+
exists(ObjectIdentity i |
58+
this = TObjectRoot(i) and
59+
result = i.getType()
60+
)
61+
or
62+
exists(Variable m |
63+
this = TObjectMember(_, m) and
64+
result = m.getType()
65+
)
66+
or
67+
exists(SubObject array |
68+
this = TObjectIndex(array) and
69+
result = array.getType().(ArrayType).getBaseType()
70+
)
71+
}
72+
73+
/**
74+
* Holds for object roots and for member accesses on that root, not for array accesses.
75+
*
76+
* This is useful for cases where we do not wish to treat `x[y]` and `x[z]` as the same object.
77+
*/
78+
predicate isPrecise() { not getParent*() = TObjectIndex(_) }
79+
80+
SubObject getParent() {
81+
exists(SubObject struct, MemberVariable m |
82+
this = TObjectMember(struct, m) and
83+
result = struct
84+
)
85+
or
86+
exists(SubObject array |
87+
this = TObjectIndex(array) and
88+
result = array
89+
)
90+
}
91+
92+
Expr getAnAccess() {
93+
exists(ObjectIdentity i |
94+
this = TObjectRoot(i) and
95+
result = i.getAnAccess()
96+
)
97+
or
98+
exists(MemberVariable m |
99+
this = TObjectMember(_, m) and
100+
result = m.getAnAccess() and
101+
// Only consider `DotFieldAccess`es, not `PointerFieldAccess`es, as the latter
102+
// are not subobjects of the root object:
103+
result.(DotFieldAccess).getQualifier() = getParent().getAnAccess()
104+
)
105+
or
106+
this = TObjectIndex(_) and
107+
result.(ArrayExpr).getArrayBase() = getParent().getAnAccess()
108+
}
109+
110+
AddressOfExpr getAnAddressOfExpr() { result.getOperand() = this.getAnAccess() }
111+
112+
/**
113+
* Get the "root" object identity to which this subobject belongs. For instance, in the
114+
* expression `x.y.z`, the root object is `x`. This subobject will share properties with the root
115+
* object such as storage duration, lifetime, and linkage.
116+
*/
117+
ObjectIdentity getRootIdentity() {
118+
exists(ObjectIdentity i |
119+
this = TObjectRoot(i) and
120+
result = i
121+
)
122+
or
123+
result = getParent().getRootIdentity()
124+
}
125+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import cpp
2+
import codingstandards.c.Objects
3+
import codingstandards.cpp.Concurrency
4+
import codingstandards.cpp.Type
5+
6+
signature module GlobalInitializationAnalysisConfigSig {
7+
/** A function which is not called or started as a thread */
8+
default predicate isRootFunction(Function f) {
9+
not exists(Function f2 | f2.calls(f)) and
10+
not f instanceof ThreadedFunction and
11+
// Exclude functions which are used as function pointers.
12+
not exists(FunctionAccess access | f = access.getTarget())
13+
}
14+
15+
ObjectIdentity getAnInitializedObject(Expr e);
16+
17+
ObjectIdentity getAUsedObject(Expr e);
18+
}
19+
20+
module GlobalInitalizationAnalysis<GlobalInitializationAnalysisConfigSig Config> {
21+
final class FinalFunction = Function;
22+
23+
final class FinalExpr = Expr;
24+
25+
class RootFunction extends FinalFunction {
26+
RootFunction() { Config::isRootFunction(this) }
27+
}
28+
29+
/** A function call which initializes a mutex or a condition */
30+
class ObjectInit extends FinalExpr {
31+
ObjectIdentity owningObject;
32+
33+
ObjectInit() { owningObject = Config::getAnInitializedObject(this) }
34+
35+
ObjectIdentity getOwningObject() { result = owningObject }
36+
}
37+
38+
/**
39+
* A function argument where that argument is used as a mutex or condition object.
40+
*/
41+
class ObjectUse extends FinalExpr {
42+
ObjectIdentity owningObject;
43+
44+
ObjectUse() { owningObject = Config::getAUsedObject(this) }
45+
46+
ObjectIdentity getOwningObject() { result = owningObject }
47+
}
48+
49+
predicate requiresInitializedMutexObject(
50+
Function func, ObjectUse mutexUse, ObjectIdentity owningObject
51+
) {
52+
mutexUse.getEnclosingFunction() = func and
53+
owningObject = mutexUse.getOwningObject() and
54+
not exists(ObjectInit init |
55+
init.getEnclosingFunction() = func and
56+
init.getOwningObject() = owningObject and
57+
mutexUse.getAPredecessor+() = init
58+
)
59+
or
60+
exists(FunctionCall call |
61+
func = call.getEnclosingFunction() and
62+
requiresInitializedMutexObject(call.getTarget(), mutexUse, owningObject) and
63+
not exists(ObjectInit init |
64+
call.getAPredecessor*() = init and
65+
init.getOwningObject() = owningObject
66+
)
67+
)
68+
or
69+
exists(C11ThreadCreateCall call |
70+
func = call.getEnclosingFunction() and
71+
not owningObject.getStorageDuration().isThread() and
72+
requiresInitializedMutexObject(call.getFunction(), mutexUse, owningObject) and
73+
not exists(ObjectInit init |
74+
call.getAPredecessor*() = init and
75+
init.getOwningObject() = owningObject
76+
)
77+
)
78+
}
79+
80+
predicate uninitializedFrom(Expr e, ObjectIdentity obj, Function callRoot) {
81+
exists(ObjectUse use | use = e |
82+
obj = use.getOwningObject() and
83+
requiresInitializedMutexObject(callRoot, use, obj) and
84+
(
85+
if obj.getStorageDuration().isAutomatic()
86+
then obj.getEnclosingElement+() = callRoot
87+
else (
88+
obj.getStorageDuration().isThread() and callRoot instanceof ThreadedFunction
89+
or
90+
callRoot instanceof RootFunction
91+
)
92+
)
93+
)
94+
}
95+
}

c/common/test/includes/standard-library/stdlib.h

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ int at_quick_exit (void (*) (void));
4949
_Noreturn void quick_exit (int);
5050

5151
char *getenv (const char *);
52+
char *getenv_s (size_t *restrict len, char *restrict value, size_t valuesz, const char *restrict name);
5253

5354
int system (const char *);
5455

0 commit comments

Comments
 (0)