@@ -31,17 +31,19 @@ class EssentialTypeCategory extends TEssentialTypeCategory {
3131 }
3232}
3333
34+ class EssentiallySignedOrUnsignedType extends EssentialTypeCategory {
35+ EssentiallySignedOrUnsignedType ( ) {
36+ this = EssentiallySignedType ( ) or this = EssentiallyUnsignedType ( )
37+ }
38+ }
39+
3440/**
3541 * An expression in the program that evaluates to a compile time constant signed or unsigned integer.
3642 */
3743private class ConstantIntegerExpr extends Expr {
3844 pragma [ noinline]
3945 ConstantIntegerExpr ( ) {
40- getEssentialTypeCategory ( this .getType ( ) ) =
41- [
42- EssentiallyUnsignedType ( ) .( EssentialTypeCategory ) ,
43- EssentiallySignedType ( ) .( EssentialTypeCategory )
44- ] and
46+ getEssentialTypeCategory ( this .getType ( ) ) instanceof EssentiallySignedOrUnsignedType and
4547 exists ( this .getValue ( ) .toFloat ( ) ) and
4648 not this instanceof Conversion
4749 }
@@ -192,8 +194,8 @@ class EssentialEqualityOperationExpr extends EssentialExpr, EqualityOperation {
192194 override Type getEssentialType ( ) { result instanceof BoolType }
193195}
194196
195- class EssentialBinaryBitwiseOperationExpr extends EssentialExpr , BinaryBitwiseOperation {
196- EssentialBinaryBitwiseOperationExpr ( ) {
197+ class EssentialShiftOperationExpr extends EssentialExpr , BinaryBitwiseOperation {
198+ EssentialShiftOperationExpr ( ) {
197199 this instanceof LShiftExpr or
198200 this instanceof RShiftExpr
199201 }
@@ -235,9 +237,7 @@ class EssentialUnaryPlusExpr extends EssentialExpr, UnaryPlusExpr {
235237 operandEssentialType = getEssentialType ( getOperand ( ) ) and
236238 operandEssentialTypeCategory = getEssentialTypeCategory ( operandEssentialType )
237239 |
238- if
239- operandEssentialTypeCategory =
240- [ EssentiallyUnsignedType ( ) .( TEssentialTypeCategory ) , EssentiallySignedType ( ) ]
240+ if operandEssentialTypeCategory instanceof EssentiallySignedOrUnsignedType
241241 then result = operandEssentialType
242242 else result = getStandardType ( )
243243 )
@@ -257,6 +257,13 @@ class EssentialUnaryMinusExpr extends EssentialExpr, UnaryMinusExpr {
257257 }
258258}
259259
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+
260267class EssentialConditionalExpr extends EssentialExpr , ConditionalExpr {
261268 override Type getEssentialType ( ) {
262269 exists ( Type thenEssentialType , Type elseEssentialType |
@@ -267,30 +274,34 @@ class EssentialConditionalExpr extends EssentialExpr, ConditionalExpr {
267274 then result = thenEssentialType
268275 else
269276 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 ( )
285281 )
286282 }
287283}
288284
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
294305 }
295306
296307 override Type getEssentialType ( ) {
@@ -305,50 +316,57 @@ class EssentialBinaryArithmeticExpr extends EssentialExpr, BinaryArithmeticOpera
305316 rightEssentialTypeCategory = getEssentialTypeCategory ( rightEssentialType )
306317 |
307318 if
308- leftEssentialTypeCategory = EssentiallySignedType ( ) and
309- rightEssentialTypeCategory = EssentiallySignedType ( )
319+ leftEssentialTypeCategory = rightEssentialTypeCategory and
320+ leftEssentialTypeCategory instanceof EssentiallySignedOrUnsignedType
310321 then
311322 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 ( )
322323 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 ( )
352370 )
353371 }
354372}
0 commit comments