Skip to content

Commit 221c0c1

Browse files
committed
Refine detection of reserved identifiers
* Update message * Require appropriate include in the non-external linkage case. * Add extra tests
1 parent 5f738b3 commit 221c0c1

File tree

3 files changed

+87
-9
lines changed

3 files changed

+87
-9
lines changed

c/common/test/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.expected

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
| test.c:6:1:6:28 | #define _also_reserved_MACRO | Macro '_also_reserved_MACRO' declares a name beginning with _ which is reserved in the ordinary and tag namespaces. |
33
| test.c:11:8:11:9 | _s | Type '_s' declares a name beginning with _ which is reserved in the tag name space. |
44
| test.c:15:6:15:7 | _f | Function '_f' declares a name beginning with _ which is reserved in the ordinary name space. |
5-
| test.c:19:7:19:12 | malloc | Function 'malloc' declares a reserved name from the C11 standard library header 'stdlib.h'. |
5+
| test.c:19:7:19:12 | malloc | Function 'malloc' declares a name which is reserved for external linkage from the C11 standard library header 'stdlib.h'. |
66
| test.c:25:5:25:9 | errno | Global variable 'errno' declares a name reserved for a macro from the C11 standard library header 'errno.h'. |
7-
| test.c:25:5:25:9 | errno | Global variable 'errno' declares a reserved name from the C11 standard library header 'errno.h'. |
7+
| test.c:25:5:25:9 | errno | Global variable 'errno' declares a name which is reserved for external linkage from the C11 standard library header 'errno.h'. |
88
| test.c:39:16:39:18 | log | Parameter 'log' declares a name reserved for a macro from the C11 standard library header 'tgmath.h'. |
99
| test.c:43:5:43:16 | _Test_global | Global variable '_Test_global' declares a reserved name beginning _ followed by an uppercase letter. |
1010
| test.c:44:6:44:15 | _Test_func | Function '_Test_func' declares a reserved name beginning _ followed by an uppercase letter. |
@@ -37,3 +37,7 @@
3737
| test.c:105:8:105:13 | NDEBUG | Type 'NDEBUG' declares a name reserved for a macro from the C11 standard library header 'assert.h'. |
3838
| test.c:106:7:106:12 | NDEBUG | Member variable 'NDEBUG' declares a name reserved for a macro from the C11 standard library header 'assert.h'. |
3939
| test.c:108:1:109:3 | #define NDEBUG x | Macro 'NDEBUG' declares a name reserved for a macro from the C11 standard library header 'assert.h'. |
40+
| test.c:114:5:114:8 | exit | Global variable 'exit' declares a name which is reserved for external linkage from the C11 standard library header 'stdlib.h'. |
41+
| test.c:116:6:116:9 | free | Function 'free' declares a name which is reserved for external linkage from the C11 standard library header 'stdlib.h'. |
42+
| test.c:126:1:126:16 | #define strlen 0 | Macro 'strlen' declares a reserved name from the C11 standard library header 'string.h' which is included directly or indirectly in this translation unit. |
43+
| test.c:136:1:136:16 | #define tm_sec 0 | Macro 'tm_sec' declares a reserved name from the C11 standard library header 'time.h' which is included directly or indirectly in this translation unit. |

c/common/test/rules/declaredareservedidentifier/test.c

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,65 @@ struct NDEBUG { // NON_COMPLIANT - NDEBUG is reserved as a macro name
107107
};
108108
#define NDEBUG \
109109
x // NON_COMPLIANT - NDEBUG is reserved as a macro name for the standard
110-
// library
110+
// library
111+
112+
/* Functions and objects with external linkage */
113+
114+
int exit; // NON_COMPLIANT - reserved for external linkage, even though header
115+
// was not included
116+
void free() { // NON_COMPLIANT - reserved for external linkage, even though
117+
// header was not included
118+
}
119+
static int rand; // COMPLIANT - only reserved for external linkage or if random
120+
// was included
121+
static int srand() { // COMPLIANT - only reserved for external linkage or if
122+
// random was included
123+
}
124+
125+
#include <string.h>
126+
#define strlen 0 // NON_COMPLIANT - reserved when string.h is included
127+
128+
// The examples below are non compliant, because those symbols are reserved in
129+
// file scope when string.h is included. However, the compiler/edg rejects the
130+
// declaration cases, so we cannot test them.
131+
132+
// static int strlen;
133+
// static void *memcpy(void *s1, const void *s2, size_t n) {}
134+
135+
#include <time.h>
136+
#define tm_sec 0 // NON_COMPLIANT - reserved when time.h is included
137+
138+
// The examples below are non compliant, because those symbols are reserved in
139+
// file scope when time.h is included. However, the compiler/edg rejects the
140+
// declaration cases, so we cannot test them.
141+
142+
// struct tm {
143+
// int tm_sec;
144+
// int tm_min;
145+
// int tm_hour;
146+
// int tm_mday;
147+
// int tm_mon;
148+
// int tm_year;
149+
// int tm_wday;
150+
// int tm_yday;
151+
// int tm_isdst;
152+
// long __tm_gmtoff;
153+
// const char *__tm_zone;
154+
// };
155+
156+
// Examples below are compliant because threads.h is not included
157+
158+
#define tss_set 0 // COMPLIANT - threads.h not included
159+
static int tss_get; // COMPLIANT - threads.h not included, not external linkage
160+
static void
161+
tss_delete( // COMPLIANT - threads.h not included, not external linkage
162+
int tss_create // COMPLIANT - threads.h not included
163+
) {
164+
int thrd_detach; // COMPLIANT - threads.h not included
165+
struct thrd_join { // COMPLIANT - threads.h not included
166+
int thrd_equal; // COMPLIANT - threads.h not included
167+
};
168+
}
169+
struct thrd_yield { // COMPLIANT - threads.h not included
170+
int thrd_exit; // COMPLIANT - threads.h not included
171+
};

cpp/common/src/codingstandards/cpp/rules/declaredareservedidentifier/DeclaredAReservedIdentifier.qll

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -202,14 +202,16 @@ query predicate problems(Element m, string message) {
202202
|
203203
hasExternalLinkage(m) and
204204
reason =
205-
"declares a reserved name from the " + TargetedCLibrary::getName() +
206-
" standard library header '" + header + "'"
205+
"declares a name which is reserved for external linkage from the " +
206+
TargetedCLibrary::getName() + " standard library header '" + header + "'"
207207
)
208208
or
209209
// > Each identifier with file scope listed in any of the following subclauses (including the
210210
// > future library directions) is reserved for use as a macro name and as an identifier with
211211
// > file scope in the same name space if any of its associated headers is included
212-
// Note: we do not consider the requirement of including the associated header
212+
//
213+
// Note: these cases are typically already rejected by the compiler, which prohibits redeclaration
214+
// of existing symbols. The macro cases are expected to work, though.
213215
exists(string header |
214216
TargetedCLibrary::hasObjectName(header, _, name, _, _) and
215217
(cNameSpace = OrdinaryNameSpace() or cNameSpace = MacroNameSpace())
@@ -220,17 +222,28 @@ query predicate problems(Element m, string message) {
220222
TargetedCLibrary::hasTypeName(header, _, name) and
221223
(cNameSpace = TagNameSpace() or cNameSpace = MacroNameSpace())
222224
or
223-
TargetedCLibrary::hasMemberVariableName(header, _, _, name, _) and
224-
(cNameSpace = OrdinaryNameSpace() or cNameSpace = MacroNameSpace())
225+
exists(string declaringType, Class c |
226+
TargetedCLibrary::hasMemberVariableName(header, _, declaringType, name, _)
227+
|
228+
// Each declaring type has its own namespace, so check that it's declared in the same
229+
cNameSpace = MemberNameSpace() and
230+
c.getAMember() = m and
231+
c.getSimpleName() = declaringType
232+
or
233+
cNameSpace = MacroNameSpace()
234+
)
225235
|
226236
(
227237
scope = FileScope()
228238
or
229239
scope = MacroScope()
230240
) and
241+
// The relevant header is included directly or transitively by the file
242+
m.getFile().getAnIncludedFile*().getBaseName() = header and
231243
reason =
232244
"declares a reserved name from the " + TargetedCLibrary::getName() +
233-
" standard library header '" + header + "'"
245+
" standard library header '" + header +
246+
"' which is included directly or indirectly in this translation unit"
234247
)
235248
or
236249
// C11 6.4.1/2

0 commit comments

Comments
 (0)