@@ -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
1012abstract 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
6792class 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
77111class 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
93136class 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
98145class 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
102154class 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
107163class 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}
0 commit comments