@@ -31,17 +31,19 @@ class EssentialTypeCategory extends TEssentialTypeCategory {
31
31
}
32
32
}
33
33
34
+ class EssentiallySignedOrUnsignedType extends EssentialTypeCategory {
35
+ EssentiallySignedOrUnsignedType ( ) {
36
+ this = EssentiallySignedType ( ) or this = EssentiallyUnsignedType ( )
37
+ }
38
+ }
39
+
34
40
/**
35
41
* An expression in the program that evaluates to a compile time constant signed or unsigned integer.
36
42
*/
37
43
private class ConstantIntegerExpr extends Expr {
38
44
pragma [ noinline]
39
45
ConstantIntegerExpr ( ) {
40
- getEssentialTypeCategory ( this .getType ( ) ) =
41
- [
42
- EssentiallyUnsignedType ( ) .( EssentialTypeCategory ) ,
43
- EssentiallySignedType ( ) .( EssentialTypeCategory )
44
- ] and
46
+ getEssentialTypeCategory ( this .getType ( ) ) instanceof EssentiallySignedOrUnsignedType and
45
47
exists ( this .getValue ( ) .toFloat ( ) ) and
46
48
not this instanceof Conversion
47
49
}
@@ -192,8 +194,8 @@ class EssentialEqualityOperationExpr extends EssentialExpr, EqualityOperation {
192
194
override Type getEssentialType ( ) { result instanceof BoolType }
193
195
}
194
196
195
- class EssentialBinaryBitwiseOperationExpr extends EssentialExpr , BinaryBitwiseOperation {
196
- EssentialBinaryBitwiseOperationExpr ( ) {
197
+ class EssentialShiftOperationExpr extends EssentialExpr , BinaryBitwiseOperation {
198
+ EssentialShiftOperationExpr ( ) {
197
199
this instanceof LShiftExpr or
198
200
this instanceof RShiftExpr
199
201
}
@@ -235,9 +237,7 @@ class EssentialUnaryPlusExpr extends EssentialExpr, UnaryPlusExpr {
235
237
operandEssentialType = getEssentialType ( getOperand ( ) ) and
236
238
operandEssentialTypeCategory = getEssentialTypeCategory ( operandEssentialType )
237
239
|
238
- if
239
- operandEssentialTypeCategory =
240
- [ EssentiallyUnsignedType ( ) .( TEssentialTypeCategory ) , EssentiallySignedType ( ) ]
240
+ if operandEssentialTypeCategory instanceof EssentiallySignedOrUnsignedType
241
241
then result = operandEssentialType
242
242
else result = getStandardType ( )
243
243
)
@@ -257,6 +257,13 @@ class EssentialUnaryMinusExpr extends EssentialExpr, UnaryMinusExpr {
257
257
}
258
258
}
259
259
260
+ bindingset [ essentialTypeA, essentialTypeB]
261
+ private Type maxRankType ( Type essentialTypeA , Type essentialTypeB ) {
262
+ if essentialTypeA .getSize ( ) > essentialTypeB .getSize ( )
263
+ then result = essentialTypeA
264
+ else result = essentialTypeB
265
+ }
266
+
260
267
class EssentialConditionalExpr extends EssentialExpr , ConditionalExpr {
261
268
override Type getEssentialType ( ) {
262
269
exists ( Type thenEssentialType , Type elseEssentialType |
@@ -267,30 +274,34 @@ class EssentialConditionalExpr extends EssentialExpr, ConditionalExpr {
267
274
then result = thenEssentialType
268
275
else
269
276
if
270
- getEssentialTypeCategory ( thenEssentialType ) = EssentiallySignedType ( ) and
271
- getEssentialTypeCategory ( elseEssentialType ) = EssentiallySignedType ( )
272
- then
273
- if thenEssentialType .getSize ( ) > elseEssentialType .getSize ( )
274
- then result = thenEssentialType
275
- else result = elseEssentialType
276
- else
277
- if
278
- getEssentialTypeCategory ( thenEssentialType ) = EssentiallyUnsignedType ( ) and
279
- getEssentialTypeCategory ( elseEssentialType ) = EssentiallyUnsignedType ( )
280
- then
281
- if thenEssentialType .getSize ( ) > elseEssentialType .getSize ( )
282
- then result = thenEssentialType
283
- else result = elseEssentialType
284
- else result = this .getStandardType ( )
277
+ getEssentialTypeCategory ( thenEssentialType ) = getEssentialTypeCategory ( elseEssentialType ) and
278
+ getEssentialTypeCategory ( thenEssentialType ) instanceof EssentiallySignedOrUnsignedType
279
+ then result = maxRankType ( thenEssentialType , elseEssentialType )
280
+ else result = this .getStandardType ( )
285
281
)
286
282
}
287
283
}
288
284
289
- class EssentialBinaryArithmeticExpr extends EssentialExpr , BinaryArithmeticOperation {
290
- EssentialBinaryArithmeticExpr ( ) {
291
- // GNU C extension has min/max which we can ignore
292
- not this instanceof MinExpr and
293
- not this instanceof MaxExpr
285
+ /**
286
+ * A binary operation subject to usual conversions, with essential type behaviour as specified by D.7.9.
287
+ */
288
+ class EssentialBinaryOperationSubjectToUsualConversions extends EssentialExpr , BinaryOperation {
289
+ EssentialBinaryOperationSubjectToUsualConversions ( ) {
290
+ this instanceof MulExpr
291
+ or
292
+ this instanceof DivExpr
293
+ or
294
+ this instanceof RemExpr
295
+ or
296
+ this instanceof AddExpr
297
+ or
298
+ this instanceof SubExpr
299
+ or
300
+ this instanceof BitwiseAndExpr
301
+ or
302
+ this instanceof BitwiseOrExpr
303
+ or
304
+ this instanceof BitwiseXorExpr
294
305
}
295
306
296
307
override Type getEssentialType ( ) {
@@ -305,50 +316,57 @@ class EssentialBinaryArithmeticExpr extends EssentialExpr, BinaryArithmeticOpera
305
316
rightEssentialTypeCategory = getEssentialTypeCategory ( rightEssentialType )
306
317
|
307
318
if
308
- leftEssentialTypeCategory = EssentiallySignedType ( ) and
309
- rightEssentialTypeCategory = EssentiallySignedType ( )
319
+ leftEssentialTypeCategory = rightEssentialTypeCategory and
320
+ leftEssentialTypeCategory instanceof EssentiallySignedOrUnsignedType
310
321
then
311
322
if exists ( getValue ( ) )
312
- then result = stlr ( this )
313
- else (
314
- if leftEssentialType .getSize ( ) > rightEssentialType .getSize ( )
315
- then result = leftEssentialType
316
- else result = rightEssentialType
317
- )
318
- else
319
- if
320
- leftEssentialTypeCategory = EssentiallyUnsignedType ( ) and
321
- rightEssentialTypeCategory = EssentiallyUnsignedType ( )
322
323
then
323
- if exists ( getValue ( ) )
324
- then result = utlr ( this )
325
- else (
326
- if leftEssentialType .getSize ( ) > rightEssentialType .getSize ( )
327
- then result = leftEssentialType
328
- else result = rightEssentialType
329
- )
330
- else
331
- if
332
- this instanceof AddExpr and
333
- (
334
- leftEssentialTypeCategory = EssentiallyCharacterType ( )
335
- or
336
- rightEssentialTypeCategory = EssentiallyCharacterType ( )
337
- ) and
338
- (
339
- leftEssentialTypeCategory =
340
- [ EssentiallySignedType ( ) , EssentiallyUnsignedType ( ) .( TEssentialTypeCategory ) ]
341
- or
342
- rightEssentialTypeCategory =
343
- [ EssentiallySignedType ( ) , EssentiallyUnsignedType ( ) .( TEssentialTypeCategory ) ]
344
- )
345
- or
346
- this instanceof SubExpr and
347
- leftEssentialTypeCategory = EssentiallyCharacterType ( ) and
348
- rightEssentialTypeCategory =
349
- [ EssentiallySignedType ( ) , EssentiallyUnsignedType ( ) .( TEssentialTypeCategory ) ]
350
- then result instanceof PlainCharType
351
- else result = this .getStandardType ( )
324
+ leftEssentialTypeCategory = EssentiallySignedType ( ) and result = stlr ( this )
325
+ or
326
+ leftEssentialTypeCategory = EssentiallyUnsignedType ( ) and result = utlr ( this )
327
+ else result = maxRankType ( leftEssentialType , rightEssentialType )
328
+ else result = this .getStandardType ( )
329
+ )
330
+ }
331
+ }
332
+
333
+ /**
334
+ * An add expression, with essential type behaviour as specified by D.7.9.
335
+ */
336
+ class EssentialAddExpr extends EssentialBinaryOperationSubjectToUsualConversions , AddExpr {
337
+ override Type getEssentialType ( ) {
338
+ exists (
339
+ EssentialTypeCategory operandTypeCategory , EssentialTypeCategory otherOperandTypeCategory
340
+ |
341
+ operandTypeCategory = getEssentialTypeCategory ( getEssentialType ( getAnOperand ( ) ) ) and
342
+ otherOperandTypeCategory = getEssentialTypeCategory ( getEssentialType ( getAnOperand ( ) ) )
343
+ |
344
+ if
345
+ operandTypeCategory = EssentiallyCharacterType ( ) and
346
+ otherOperandTypeCategory instanceof EssentiallySignedOrUnsignedType
347
+ then result instanceof PlainCharType
348
+ else result = super .getEssentialType ( )
349
+ )
350
+ }
351
+ }
352
+
353
+ /**
354
+ * A sub expression, with essential type behaviour as specified by D.7.9.
355
+ */
356
+ class EssentialSubExpr extends EssentialBinaryOperationSubjectToUsualConversions , SubExpr {
357
+ override Type getEssentialType ( ) {
358
+ exists (
359
+ EssentialTypeCategory leftEssentialTypeCategory ,
360
+ EssentialTypeCategory rightEssentialTypeCategory
361
+ |
362
+ leftEssentialTypeCategory = getEssentialTypeCategory ( getEssentialType ( getLeftOperand ( ) ) ) and
363
+ rightEssentialTypeCategory = getEssentialTypeCategory ( getEssentialType ( getRightOperand ( ) ) )
364
+ |
365
+ if
366
+ leftEssentialTypeCategory = EssentiallyCharacterType ( ) and
367
+ rightEssentialTypeCategory instanceof EssentiallySignedOrUnsignedType
368
+ then result instanceof PlainCharType
369
+ else result = super .getEssentialType ( )
352
370
)
353
371
}
354
372
}
0 commit comments