Skip to content

Commit 8ef8017

Browse files
Fix & improve tests
1 parent 9271829 commit 8ef8017

File tree

2 files changed

+67
-59
lines changed

2 files changed

+67
-59
lines changed

cpp/common/src/codingstandards/cpp/Extensions.qll

Lines changed: 64 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import cpp
22

33
/**
4-
* Common base class for modeling compiler extensions.
4+
* A usage of a compiler extension in C++ code, such as non-standard attributes or built-in function
5+
* calls.
56
*/
6-
abstract class CompilerExtension extends Locatable { }
7-
8-
/**
9-
* Common base class for modeling compiler extensions in CPP.
10-
*/
11-
abstract class CPPCompilerExtension extends CompilerExtension {
7+
abstract class CPPCompilerExtension extends Locatable {
128
abstract string getMessage();
139
}
1410

@@ -29,7 +25,7 @@ class CPPAttributeExtension extends CPPCompilerExtension, Attribute {
2925
}
3026

3127
/**
32-
* An `Attribute` within a compiler specific namespace such as `[[gnu::weak]]`.
28+
* A `StdAttribute` within a compiler specific namespace such as `[[gnu::weak]]`.
3329
*/
3430
class CppNamespacedStdAttributeExtension extends CPPCompilerExtension, StdAttribute {
3531
CppNamespacedStdAttributeExtension() { exists(this.getNamespace()) and not getNamespace() = "" }
@@ -41,6 +37,12 @@ class CppNamespacedStdAttributeExtension extends CPPCompilerExtension, StdAttrib
4137
}
4238
}
4339

40+
/**
41+
* A `StdAttribute` with a name not recognized as part of the C++17 standard.
42+
*
43+
* Only the listed names are valid C++17. Namespaced attributes are handled by
44+
* `CppNamespacedStdAttributeExtension` and not considered here.
45+
*/
4446
class CppUnrecognizedAttributeExtension extends CPPCompilerExtension, StdAttribute {
4547
CppUnrecognizedAttributeExtension() {
4648
not this instanceof CppNamespacedStdAttributeExtension and
@@ -55,7 +57,8 @@ class CppUnrecognizedAttributeExtension extends CPPCompilerExtension, StdAttribu
5557
}
5658

5759
/**
58-
* Compiler-specific builtin functions.
60+
* A `FunctionCall` of a compiler-specific builtin function.
61+
*
5962
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
6063
*/
6164
class CPPBuiltinFunctionExtension extends CPPCompilerExtension, FunctionCall {
@@ -73,7 +76,8 @@ class CPPBuiltinFunctionExtension extends CPPCompilerExtension, FunctionCall {
7376
}
7477

7578
/**
76-
* Statement expressions: ({ ... }) syntax.
79+
* A `StmtExpr`, which uses `({ <stmts> })` syntax, which is a GNU extension.
80+
*
7781
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
7882
*/
7983
class CPPStmtExprExtension extends CPPCompilerExtension, StmtExpr {
@@ -84,95 +88,93 @@ class CPPStmtExprExtension extends CPPCompilerExtension, StmtExpr {
8488
}
8589

8690
/**
87-
* Ternary expressions with omitted middle operand: x ?: y
91+
* A `ConditionalExpr` using GNU-style omitted middle operand such as `x ?: y`.
92+
*
8893
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html
8994
*/
9095
class CPPTerseTernaryExtension extends CPPCompilerExtension, ConditionalExpr {
9196
CPPTerseTernaryExtension() { getCondition() = getElse() or getCondition() = getThen() }
9297

9398
override string getMessage() {
9499
result =
95-
"Ternaries with omitted middle operands are a compiler extension and are not portable to other compilers."
100+
"Ternaries with omitted middle operands are a compiler extension and are not portable to " +
101+
"other compilers."
96102
}
97103
}
98104

99105
/**
100-
* Extended integer types: __int128, etc.
106+
* A non-standard `Type` that is only available as a compiler extension, such as `__int128`,
107+
* `_Decimal32`, `_Decimal64`, `_Decimal128`, or `__float128`.
108+
*
101109
* Reference: https://gcc.gnu.org/onlinedocs/gcc/__int128.html
110+
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html
102111
*/
103-
class CPPExtendedIntegerTypeExtension extends CPPCompilerExtension, DeclarationEntry {
104-
CPPExtendedIntegerTypeExtension() { getType() instanceof Int128Type }
105-
106-
override string getMessage() {
107-
result = "128-bit integers are a compiler extension and are not portable to other compilers."
112+
class CPPExtensionType extends Type {
113+
CPPExtensionType() {
114+
this instanceof Int128Type or
115+
this instanceof Decimal128Type or
116+
this instanceof Decimal32Type or
117+
this instanceof Decimal64Type or
118+
this instanceof Float128Type
108119
}
109120
}
110121

111122
/**
112-
* Extended floating-point types: __float128, _Decimal32, etc.
113-
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html
123+
* A `DeclarationEntry` using an extended type such as `__int128`, `_Decimal32`, `_Decimal64`,
124+
* `_Decimal128`, or `__float128`.
125+
*
126+
* Reference: https://gcc.gnu.org/onlinedocs/gcc/__int128.html
114127
*/
115-
class CPPExtendedFloatTypeExtension extends CPPCompilerExtension, DeclarationEntry {
116-
CPPExtendedFloatTypeExtension() {
117-
getType() instanceof Decimal128Type or
118-
getType() instanceof Decimal32Type or
119-
getType() instanceof Decimal64Type or
120-
getType() instanceof Float128Type
121-
}
128+
class CPPExtensionTypeUsage extends CPPCompilerExtension, DeclarationEntry {
129+
CPPExtensionType extendedType;
130+
131+
CPPExtensionTypeUsage() { extendedType = getType() }
122132

123133
override string getMessage() {
124134
result =
125-
"Extended floating-point types are a compiler extension and are not portable to other compilers."
135+
"Declaration '" + getName() + "' uses type '" + extendedType.getName() +
136+
"' which is a compiler extension and is not portable to other compilers."
126137
}
127138
}
128139

129140
/**
130-
* Zero-length arrays (flexible array members must be last).
141+
* A `DeclarationEntry` using a zero-length array, which is a non-standard way to declare a flexible
142+
* array member.
143+
*
131144
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
132145
*/
133146
class CPPZeroLengthArraysExtension extends CPPCompilerExtension, DeclarationEntry {
134-
CPPZeroLengthArraysExtension() { getType().(ArrayType).getArraySize() = 0 }
135-
136-
override string getMessage() {
137-
result = "Zero length arrays are a compiler extension and are not portable to other compilers."
138-
}
139-
}
147+
ArrayType array;
140148

141-
/**
142-
* Variable-length arrays in struct members (not C++17 compliant).
143-
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
144-
*/
145-
class CPPVariableLengthArraysExtension extends CPPCompilerExtension, Field {
146-
CPPVariableLengthArraysExtension() {
147-
getType() instanceof ArrayType and
148-
not getType().(ArrayType).hasArraySize() and
149-
// Not the final member of the struct, which is allowed in some contexts
150-
not exists(int lastIndex, Class declaringStruct |
151-
declaringStruct = getDeclaringType() and
152-
lastIndex = count(declaringStruct.getACanonicalMember()) - 1 and
153-
this = declaringStruct.getCanonicalMember(lastIndex)
154-
)
149+
CPPZeroLengthArraysExtension() {
150+
array = getType() and
151+
array.getArraySize() = 0
155152
}
156153

157154
override string getMessage() {
158155
result =
159-
"Variable length arrays are a compiler extension and are not portable to other compilers."
156+
"Variable '" + getName() + "' is declared with a zero-length array (of '" +
157+
array.getBaseType() + "') is a compiler extension and are not portable to other compilers."
160158
}
161159
}
162160

163161
/**
164-
* __alignof__ operator (use alignof from C++11 instead).
162+
* A `Field` with a variable-length array type in a struct member (not C++17 compliant).
163+
*
164+
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
165165
*/
166-
class CPPAlignofExtension extends CPPCompilerExtension, AlignofExprOperator {
167-
CPPAlignofExtension() { exists(getValueText().indexOf("__alignof__")) }
168-
166+
class CPPVariableLengthArraysExtension extends CPPCompilerExtension, VlaDeclStmt {
169167
override string getMessage() {
170-
result = "'__alignof__' is a compiler extension and is not portable to other compilers."
168+
result =
169+
"Variable length array (used in '" + this +
170+
"') are a compiler extension and are not portable to other compilers."
171171
}
172172
}
173173

174174
/**
175-
* Preprocessor extensions for feature detection.
175+
* A `PreprocessorIfdef` using a builtin preprocessor feature such as `__has_builtin`,
176+
* `__has_include`, etc., which are non-standard clang extensions.
177+
*
176178
* Reference: https://clang.llvm.org/docs/LanguageExtensions.html
177179
*/
178180
class CPPConditionalDefineExtension extends CPPCompilerExtension, PreprocessorIfdef {
@@ -195,6 +197,10 @@ class CPPConditionalDefineExtension extends CPPCompilerExtension, PreprocessorIf
195197
}
196198
}
197199

200+
/**
201+
* A `PreprocessorDirective` that is a non-standard compiler extension, such as `#pragma`, `#error`,
202+
* or `#warning`.
203+
*/
198204
class CPPPreprocessorDirectiveExtension extends CPPCompilerExtension, PreprocessorDirective {
199205
string kind;
200206

@@ -212,7 +218,8 @@ class CPPPreprocessorDirectiveExtension extends CPPCompilerExtension, Preprocess
212218
}
213219

214220
/**
215-
* Built-in type traits and operations such as `__is_abstract`, `__is_same`, etc.
221+
* A `BuiltInOperation` which describes certain non-standard syntax such as type trait operations,
222+
* for example GNU `__is_abstract(T)`, `__is_same(T, U)`, etc.
216223
*
217224
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
218225
*/

cpp/misra/test/rules/RULE-4-1-1/CompilerLanguageExtensionsUsed.expected

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111
| test.cpp:24:3:24:22 | __is_same | Use of built-in operation '__is_same' is a compiler extension. |
1212
| test.cpp:30:3:33:4 | (statement expression) | Statement expressions are a compiler extension and are not portable to other compilers. |
1313
| test.cpp:34:3:34:12 | ... ? ... : ... | Ternaries with omitted middle operands are a compiler extension and are not portable to other compilers. |
14-
| test.cpp:36:12:36:13 | definition of l0 | 128-bit integers are a compiler extension and are not portable to other compilers. |
14+
| test.cpp:36:12:36:13 | definition of l0 | Declaration 'l0' uses type '__int128' which is a compiler extension and is not portable to other compilers. |
1515
| test.cpp:45:20:45:30 | fallthrough | Use of attribute 'fallthrough' is a compiler extension and is not portable to other compilers. |
1616
| test.cpp:47:7:47:22 | fallthrough | Use of attribute 'fallthrough' in namespace 'gnu' is a compiler extension and is not portable to other compilers. |
1717
| test.cpp:55:3:55:29 | __builtin_va_start | Use of built-in operation '__builtin_va_start' is a compiler extension. |
18-
| test.cpp:60:7:60:8 | definition of m1 | Zero length arrays are a compiler extension and are not portable to other compilers. |
18+
| test.cpp:60:7:60:8 | definition of m1 | Variable 'm1' is declared with a zero-length array (of 'int') is a compiler extension and are not portable to other compilers. |
1919
| test.cpp:64:31:64:41 | vector_size | Use of attribute 'vector_size' is a compiler extension and is not portable to other compilers. |
2020
| test.cpp:66:1:66:20 | #ifdef __has_builtin | Call to builtin preprocessor feature '__has_builtin' is a compiler extension and is not portable to other compilers. |
2121
| test.cpp:72:1:72:12 | #pragma once | Use of non-standard preprocessor directive '#pragma once' is a compiler extension. |
2222
| test.cpp:73:1:73:27 | #pragma GCC diagnostic push | Use of non-standard preprocessor directive '#pragma GCC diagnostic push' is a compiler extension. |
2323
| test.cpp:74:1:74:28 | #warning "This is a warning" | Use of non-standard preprocessor directive '#warning' is a compiler extension. |
2424
| test.cpp:76:1:76:41 | #warning "preceeding spaces is common" | Use of non-standard preprocessor directive '#warning' is a compiler extension. |
25+
| test.cpp:81:7:81:7 | VLA declaration | Variable length array (used in 'VLA declaration') are a compiler extension and are not portable to other compilers. |

0 commit comments

Comments
 (0)