|
| 1 | +/** |
| 2 | + * @id c/misra/low-precision-periodic-trigonometric-function-call |
| 3 | + * @name DIR-4-11: The validity of values passed to trigonometric functions shall be checked |
| 4 | + * @description Trigonometric periodic functions have significantly less precision when called with |
| 5 | + * large floating-point values. |
| 6 | + * @kind problem |
| 7 | + * @precision high |
| 8 | + * @problem.severity warning |
| 9 | + * @tags external/misra/id/dir-4-11 |
| 10 | + * correctness |
| 11 | + * external/misra/c/2012/third-edition-first-revision |
| 12 | + * external/misra/c/2012/amendment3 |
| 13 | + * external/misra/obligation/required |
| 14 | + */ |
| 15 | + |
| 16 | +import cpp |
| 17 | +import codingstandards.c.misra |
| 18 | +import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis |
| 19 | + |
| 20 | +float getMaxAllowedAbsoluteValue(FloatingPointType t, string description) { |
| 21 | + if t.getSize() <= 4 |
| 22 | + then ( |
| 23 | + // Per MISRA, assume k=1 for float types. |
| 24 | + result = 3.15 and description = "pi" |
| 25 | + ) else ( |
| 26 | + // Allow k=10 for doubles, as the standard allows for a larger range depending on the |
| 27 | + // implementation, application, and precision goals. |
| 28 | + result = 10 * 3.15 and description = "10 * pi" |
| 29 | + ) |
| 30 | +} |
| 31 | + |
| 32 | +from FunctionCall fc, Expr argument, float maxValue, float maxAllowedValue, string maxAllowedStr |
| 33 | +where |
| 34 | + not isExcluded(fc, ContractsPackage::lowPrecisionPeriodicTrigonometricFunctionCallQuery()) and |
| 35 | + fc.getTarget().getName() = ["sin", "cos", "tan"] and |
| 36 | + argument = fc.getArgument(0) and |
| 37 | + maxValue = rank[1](float bound | bound = [lowerBound(argument), upperBound(argument)].abs()) and |
| 38 | + maxAllowedValue = getMaxAllowedAbsoluteValue(argument.getType(), maxAllowedStr) and |
| 39 | + maxValue > maxAllowedValue |
| 40 | +select fc, |
| 41 | + "Call to periodic trigonometric function " + fc.getTarget().getName() + |
| 42 | + " with maximum argument absolute value of " + maxValue.toString() + |
| 43 | + ", which exceeds the recommended " + "maximum of " + maxAllowedStr + "." |
0 commit comments