|
| 1 | +/** |
| 2 | + * A module for representing expressions and related types defined in the MISRA C 2012 standard. |
| 3 | + */ |
| 4 | + |
| 5 | +import codingstandards.c.misra |
| 6 | + |
| 7 | +/** |
| 8 | + * A `bool` type, either `stdbool.h` or a hand-coded bool type acceptable to MISRA C 2012. |
| 9 | + */ |
| 10 | +class MisraBoolType extends Type { |
| 11 | + MisraBoolType() { |
| 12 | + this instanceof BoolType |
| 13 | + or |
| 14 | + exists(Enum e | this = e | |
| 15 | + count(e.getAnEnumConstant()) = 2 and |
| 16 | + e.getEnumConstant(0).getName().toLowerCase() = ["false", "f"] and |
| 17 | + e.getEnumConstant(1).getName().toLowerCase() = ["true", "t"] |
| 18 | + ) |
| 19 | + or |
| 20 | + exists(TypedefType t | this = t | t.getName().toLowerCase() = ["bool", "boolean"]) |
| 21 | + } |
| 22 | +} |
| 23 | + |
| 24 | +/** |
| 25 | + * A boolean literal as defined by the C standard and acceptable to MISRA C 2012. |
| 26 | + */ |
| 27 | +class BooleanLiteral extends Literal { |
| 28 | + BooleanLiteral() { |
| 29 | + exists(MacroInvocation mi, int value, string macroName | |
| 30 | + macroName = mi.getMacroName() and mi.getExpr() = this and value = this.getValue().toInt() |
| 31 | + | |
| 32 | + macroName = "false" and value = 0 |
| 33 | + or |
| 34 | + macroName = "true" and value = 1 |
| 35 | + ) |
| 36 | + } |
| 37 | +} |
| 38 | + |
| 39 | +/** |
| 40 | + * A composite operator as defined in MISRA C:2012 8.10.3. |
| 41 | + */ |
| 42 | +class CompositeOperator extends Expr { |
| 43 | + CompositeOperator() { |
| 44 | + // + - * / % + - |
| 45 | + this instanceof BinaryArithmeticOperation and |
| 46 | + not this instanceof MaxExpr and |
| 47 | + not this instanceof MinExpr |
| 48 | + or |
| 49 | + // << >> & ^ | |
| 50 | + this instanceof BinaryBitwiseOperation |
| 51 | + or |
| 52 | + // ~ |
| 53 | + this instanceof ComplementExpr |
| 54 | + or |
| 55 | + exists(ConditionalExpr ce | ce = this | |
| 56 | + ce.getElse() instanceof CompositeExpression or ce.getThen() instanceof CompositeExpression |
| 57 | + ) |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 61 | +/** |
| 62 | + * A composite expression as defined in MISRA C:2012 8.10.3. |
| 63 | + */ |
| 64 | +class CompositeExpression extends Expr { |
| 65 | + CompositeExpression() { |
| 66 | + this instanceof CompositeOperator and |
| 67 | + // A non-constant expression that is the result of a composite operator |
| 68 | + not exists(this.getValue()) |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +/** |
| 73 | + * An operator on which the usual arithmetic conversions apply to the operands, as defined in MISRA |
| 74 | + * C:2012 6.3.1.8. |
| 75 | + */ |
| 76 | +class OperationWithUsualArithmeticConversions extends Expr { |
| 77 | + OperationWithUsualArithmeticConversions() { |
| 78 | + this instanceof BinaryOperation and |
| 79 | + not this instanceof LShiftExpr and |
| 80 | + not this instanceof RShiftExpr and |
| 81 | + not this instanceof LogicalAndExpr and |
| 82 | + not this instanceof LogicalOrExpr |
| 83 | + or |
| 84 | + this instanceof AssignArithmeticOperation |
| 85 | + } |
| 86 | + |
| 87 | + Expr getLeftOperand() { |
| 88 | + result = this.(BinaryOperation).getLeftOperand() |
| 89 | + or |
| 90 | + result = this.(AssignArithmeticOperation).getLValue() |
| 91 | + } |
| 92 | + |
| 93 | + Expr getRightOperand() { |
| 94 | + result = this.(BinaryOperation).getRightOperand() |
| 95 | + or |
| 96 | + result = this.(AssignArithmeticOperation).getRValue() |
| 97 | + } |
| 98 | + |
| 99 | + Expr getAnOperand() { result = this.getLeftOperand() or result = this.getRightOperand() } |
| 100 | + |
| 101 | + string getOperator() { |
| 102 | + result = this.(BinaryOperation).getOperator() |
| 103 | + or |
| 104 | + result = this.(AssignArithmeticOperation).getOperator() |
| 105 | + } |
| 106 | +} |
0 commit comments