@@ -4,21 +4,28 @@ import codingstandards.cpp.Extensions
4
4
/**
5
5
* Common base class for modeling compiler extensions.
6
6
*/
7
- abstract class CCompilerExtension extends CompilerExtension { }
7
+ abstract class CCompilerExtension extends CompilerExtension {
8
+ abstract string getMessage ( ) ;
9
+ }
8
10
9
11
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins
10
12
abstract class CConditionalDefineExtension extends CCompilerExtension , PreprocessorIfdef {
13
+ string feature ;
14
+
11
15
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."
22
29
}
23
30
}
24
31
@@ -31,6 +38,12 @@ class CMacroBasedExtension extends CCompilerExtension, Macro {
31
38
"__clang_version__" , "__clang_literal_encoding__" , "__clang_wide_literal_encoding__"
32
39
]
33
40
}
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
+ }
34
47
}
35
48
36
49
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes
@@ -41,6 +54,12 @@ class CAttributeExtension extends CCompilerExtension, Attribute {
41
54
"fallthrough" , "read_only" , "alias"
42
55
]
43
56
}
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
+ }
44
63
}
45
64
46
65
// 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 {
61
80
// the built-in extensions
62
81
getTarget ( ) .getName ( ) .indexOf ( "__builtin_" ) = 0
63
82
}
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
+ }
64
89
}
65
90
66
91
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Alignment.html#Alignment
67
92
class CFunctionLikeExtension extends CCompilerExtension , AlignofExprOperator {
68
93
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
+ }
69
98
}
70
99
71
100
// 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
+ }
73
107
74
108
// Use of ternary like the following: `int a = 0 ?: 0;` where the
75
109
// one of the branches is omitted
76
110
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html#Conditionals
77
111
class CTerseTernaryExtension extends CCompilerExtension , ConditionalExpr {
78
112
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
+ }
79
118
}
80
119
81
120
// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128
@@ -87,31 +126,63 @@ class CRealTypeExtensionExtension extends CCompilerExtension, DeclarationEntry {
87
126
getType ( ) instanceof Decimal64Type or
88
127
getType ( ) instanceof Float128Type
89
128
}
129
+
130
+ override string getMessage ( ) {
131
+ result = "Decimal floats are a compiler extension and are not portable to other compilers."
132
+ }
90
133
}
91
134
92
135
// Reference: https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html#g_t_005f_005fint128
93
136
class CIntegerTypeExtension extends CCompilerExtension , DeclarationEntry {
94
137
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
+ }
95
142
}
96
143
97
144
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Long-Long.html#Long-Long
98
145
class CLongLongType extends CCompilerExtension , DeclarationEntry {
99
146
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
+ }
100
152
}
101
153
102
154
class CZeroLengthArraysExtension extends CCompilerExtension , DeclarationEntry {
103
155
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
+ }
104
160
}
105
161
106
162
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html#Empty-Structures
107
163
class CEmptyStructExtension extends CCompilerExtension , Struct {
108
164
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
+ }
109
169
}
110
170
111
171
// Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length
112
- class CVariableLengthArraysExtension extends CCompilerExtension , DeclarationEntry {
172
+ class CVariableLengthArraysExtension extends CCompilerExtension , Field {
113
173
CVariableLengthArraysExtension ( ) {
114
174
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."
116
187
}
117
188
}
0 commit comments