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 3c1615d

Browse filesBrowse files
authored
Merge pull request #703 from github/lcartey/language-extensions-improvements
Rule 1.2: Address false positives for variable length arrays, improve reporting
2 parents 76de855 + 55c9f23 commit 3c1615d
Copy full SHA for 3c1615d

File tree

Expand file treeCollapse file tree

6 files changed

+196
-75
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+196
-75
lines changed

‎c/common/src/codingstandards/c/Extensions.qll

Copy file name to clipboardExpand all lines: c/common/src/codingstandards/c/Extensions.qll
+85-14Lines changed: 85 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,28 @@ import codingstandards.cpp.Extensions
44
/**
55
* Common base class for modeling compiler extensions.
66
*/
7-
abstract class CCompilerExtension extends CompilerExtension { }
7+
abstract class CCompilerExtension extends CompilerExtension {
8+
abstract string getMessage();
9+
}
810

911
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins
1012
abstract class CConditionalDefineExtension extends CCompilerExtension, PreprocessorIfdef {
13+
string feature;
14+
1115
CConditionalDefineExtension() {
12-
exists(toString().indexOf("__has_builtin")) or
13-
exists(toString().indexOf("__has_constexpr_builtin")) or
14-
exists(toString().indexOf("__has_feature")) or
15-
exists(toString().indexOf("__has_extension")) or
16-
exists(toString().indexOf("__has_attribute")) or
17-
exists(toString().indexOf("__has_declspec_attribute")) or
18-
exists(toString().indexOf("__is_identifier")) or
19-
exists(toString().indexOf("__has_include")) or
20-
exists(toString().indexOf("__has_include_next")) or
21-
exists(toString().indexOf("__has_warning"))
16+
feature =
17+
[
18+
"__has_builtin", "__has_constexpr_builtin", "__has_feature", "__has_extension",
19+
"__has_attribute", "__has_declspec_attribute", "__is_identifier", "__has_include",
20+
"__has_include_next", "__has_warning"
21+
] and
22+
exists(toString().indexOf(feature))
23+
}
24+
25+
override string getMessage() {
26+
result =
27+
"Call to builtin function '" + feature +
28+
"' is a compiler extension and is not portable to other compilers."
2229
}
2330
}
2431

@@ -31,6 +38,12 @@ class CMacroBasedExtension extends CCompilerExtension, Macro {
3138
"__clang_version__", "__clang_literal_encoding__", "__clang_wide_literal_encoding__"
3239
]
3340
}
41+
42+
override string getMessage() {
43+
result =
44+
"Use of builtin macro '" + getBody() +
45+
"' is a compiler extension and is not portable to other compilers."
46+
}
3447
}
3548

3649
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes
@@ -41,6 +54,12 @@ class CAttributeExtension extends CCompilerExtension, Attribute {
4154
"fallthrough", "read_only", "alias"
4255
]
4356
}
57+
58+
override string getMessage() {
59+
result =
60+
"Use of attribute '" + getName() +
61+
"' is a compiler extension and is not portable to other compilers."
62+
}
4463
}
4564

4665
// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html#g_t_005f_005fsync-Builtins
@@ -61,21 +80,41 @@ class CFunctionExtension extends CCompilerExtension, FunctionCall {
6180
// the built-in extensions
6281
getTarget().getName().indexOf("__builtin_") = 0
6382
}
83+
84+
override string getMessage() {
85+
result =
86+
"Call to builtin function '" + getTarget().getName() +
87+
"' is a compiler extension and is not portable to other compilers."
88+
}
6489
}
6590

6691
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Alignment.html#Alignment
6792
class CFunctionLikeExtension extends CCompilerExtension, AlignofExprOperator {
6893
CFunctionLikeExtension() { exists(getValueText().indexOf("__alignof__")) }
94+
95+
override string getMessage() {
96+
result = "'__alignof__' is a compiler extension and is not portable to other compilers."
97+
}
6998
}
7099

71100
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs
72-
class CStmtExprExtension extends CCompilerExtension, StmtExpr { }
101+
class CStmtExprExtension extends CCompilerExtension, StmtExpr {
102+
override string getMessage() {
103+
result =
104+
"Statement expressions are a compiler extension and are not portable to other compilers."
105+
}
106+
}
73107

74108
// Use of ternary like the following: `int a = 0 ?: 0;` where the
75109
// one of the branches is omitted
76110
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals
77111
class CTerseTernaryExtension extends CCompilerExtension, ConditionalExpr {
78112
CTerseTernaryExtension() { getCondition() = getElse() or getCondition() = getThen() }
113+
114+
override string getMessage() {
115+
result =
116+
"Ternaries with omitted middle operands are a compiler extension and is not portable to other compilers."
117+
}
79118
}
80119

81120
// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128
@@ -87,31 +126,63 @@ class CRealTypeExtensionExtension extends CCompilerExtension, DeclarationEntry {
87126
getType() instanceof Decimal64Type or
88127
getType() instanceof Float128Type
89128
}
129+
130+
override string getMessage() {
131+
result = "Decimal floats are a compiler extension and are not portable to other compilers."
132+
}
90133
}
91134

92135
// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128
93136
class CIntegerTypeExtension extends CCompilerExtension, DeclarationEntry {
94137
CIntegerTypeExtension() { getType() instanceof Int128Type }
138+
139+
override string getMessage() {
140+
result = "128-bit integers are a compiler extension and are not portable to other compilers."
141+
}
95142
}
96143

97144
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Long-Long.html#Long-Long
98145
class CLongLongType extends CCompilerExtension, DeclarationEntry {
99146
CLongLongType() { getType() instanceof LongLongType }
147+
148+
override string getMessage() {
149+
result =
150+
"Double-Word integers are a compiler extension and are not portable to other compilers."
151+
}
100152
}
101153

102154
class CZeroLengthArraysExtension extends CCompilerExtension, DeclarationEntry {
103155
CZeroLengthArraysExtension() { getType().(ArrayType).getArraySize() = 0 }
156+
157+
override string getMessage() {
158+
result = "Zero length arrays are a compiler extension and are not portable to other compilers."
159+
}
104160
}
105161

106162
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html#Empty-Structures
107163
class CEmptyStructExtension extends CCompilerExtension, Struct {
108164
CEmptyStructExtension() { not exists(getAMember(_)) }
165+
166+
override string getMessage() {
167+
result = "Empty structures are a compiler extension and are not portable to other compilers."
168+
}
109169
}
110170

111171
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length
112-
class CVariableLengthArraysExtension extends CCompilerExtension, DeclarationEntry {
172+
class CVariableLengthArraysExtension extends CCompilerExtension, Field {
113173
CVariableLengthArraysExtension() {
114174
getType() instanceof ArrayType and
115-
not getType().(ArrayType).hasArraySize()
175+
not getType().(ArrayType).hasArraySize() and
176+
// Not the final member of the struct, which is allowed to be variably sized
177+
not exists(int lastIndex, Class declaringStruct |
178+
declaringStruct = getDeclaringType() and
179+
lastIndex = count(declaringStruct.getACanonicalMember()) - 1 and
180+
this = declaringStruct.getCanonicalMember(lastIndex)
181+
)
182+
}
183+
184+
override string getMessage() {
185+
result =
186+
"Variable length arrays are a compiler extension and are not portable to other compilers."
116187
}
117188
}

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

Copy file name to clipboardExpand all lines: c/misra/src/rules/RULE-1-2/LanguageExtensionsShouldNotBeUsed.ql
+2-1Lines 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, "Is a compiler extension and is not portable to other compilers."
21+
select MacroUnwrapper<CCompilerExtension>::unwrapElement(e), e.getMessage()

0 commit comments

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