Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion amendments.csv
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language,standard,amendment,rule_id,supportable,implementation_category,implemented,difficulty
c,MISRA-C-2012,Amendment3,DIR-4-6,Yes,Expand,Yes,Easy
c,MISRA-C-2012,Amendment3,DIR-4-9,Yes,Refine,No,Easy
c,MISRA-C-2012,Amendment3,DIR-4-11,Yes,Refine,No,Import
c,MISRA-C-2012,Amendment3,DIR-4-11,Yes,Refine,Yes,Import
c,MISRA-C-2012,Amendment3,RULE-1-4,Yes,Replace,No,Easy
c,MISRA-C-2012,Amendment3,RULE-10-1,Yes,Replace,Yes,Easy
c,MISRA-C-2012,Amendment3,RULE-10-3,Yes,Refine,Yes,Easy
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @id c/misra/low-precision-periodic-trigonometric-function-call
* @name DIR-4-11: The validity of values passed to trigonometric functions shall be checked
* @description Trigonometric periodic functions have significantly less precision when called with
* large floating-point values.
* @kind problem
* @precision high
* @problem.severity warning
* @tags external/misra/id/dir-4-11
* correctness
* external/misra/c/2012/third-edition-first-revision
* external/misra/c/2012/amendment3
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis

float getMaxAllowedAbsoluteValue(FloatingPointType t, string description) {
if t.getSize() <= 4
then (
// Per MISRA, assume k=1 for float types.
result = 3.15 and description = "pi"
) else (
// Allow k=10 for doubles, as the standard allows for a larger range depending on the
// implementation, application, and precision goals.
result = 10 * 3.15 and description = "10 * pi"
)
}

from FunctionCall fc, Expr argument, float maxValue, float maxAllowedValue, string maxAllowedStr
where
not isExcluded(fc, ContractsPackage::lowPrecisionPeriodicTrigonometricFunctionCallQuery()) and
fc.getTarget().getName() = ["sin", "cos", "tan"] and
argument = fc.getArgument(0) and
maxValue = rank[1](float bound | bound = [lowerBound(argument), upperBound(argument)].abs()) and
maxAllowedValue = getMaxAllowedAbsoluteValue(argument.getType(), maxAllowedStr) and
maxValue > maxAllowedValue
select fc,
"Call to periodic trigonometric function " + fc.getTarget().getName() +
" with maximum argument absolute value of " + maxValue.toString() +
", which exceeds the recommended " + "maximum of " + maxAllowedStr + "."
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
| test.c:32:5:32:7 | call to sin | Call to periodic trigonometric function sin with maximum argument absolute value of 31.4, which exceeds the recommended maximum of pi. |
| test.c:33:5:33:7 | call to cos | Call to periodic trigonometric function cos with maximum argument absolute value of 31.4, which exceeds the recommended maximum of pi. |
| test.c:34:5:34:7 | call to tan | Call to periodic trigonometric function tan with maximum argument absolute value of 31.4, which exceeds the recommended maximum of pi. |
| test.c:38:5:38:7 | call to sin | Call to periodic trigonometric function sin with maximum argument absolute value of 31.4, which exceeds the recommended maximum of pi. |
| test.c:39:5:39:7 | call to cos | Call to periodic trigonometric function cos with maximum argument absolute value of 31.4, which exceeds the recommended maximum of pi. |
| test.c:40:5:40:7 | call to tan | Call to periodic trigonometric function tan with maximum argument absolute value of 31.4, which exceeds the recommended maximum of pi. |
| test.c:49:5:49:7 | call to sin | Call to periodic trigonometric function sin with maximum argument absolute value of 314, which exceeds the recommended maximum of pi. |
| test.c:50:5:50:7 | call to cos | Call to periodic trigonometric function cos with maximum argument absolute value of 314, which exceeds the recommended maximum of pi. |
| test.c:51:5:51:7 | call to tan | Call to periodic trigonometric function tan with maximum argument absolute value of 314, which exceeds the recommended maximum of pi. |
| test.c:52:5:52:7 | call to sin | Call to periodic trigonometric function sin with maximum argument absolute value of 314, which exceeds the recommended maximum of 10 * pi. |
| test.c:53:5:53:7 | call to cos | Call to periodic trigonometric function cos with maximum argument absolute value of 314, which exceeds the recommended maximum of 10 * pi. |
| test.c:54:5:54:7 | call to tan | Call to periodic trigonometric function tan with maximum argument absolute value of 314, which exceeds the recommended maximum of 10 * pi. |
| test.c:55:5:55:7 | call to sin | Call to periodic trigonometric function sin with maximum argument absolute value of 314, which exceeds the recommended maximum of pi. |
| test.c:56:5:56:7 | call to cos | Call to periodic trigonometric function cos with maximum argument absolute value of 314, which exceeds the recommended maximum of pi. |
| test.c:57:5:57:7 | call to tan | Call to periodic trigonometric function tan with maximum argument absolute value of 314, which exceeds the recommended maximum of pi. |
| test.c:58:5:58:7 | call to sin | Call to periodic trigonometric function sin with maximum argument absolute value of 314, which exceeds the recommended maximum of 10 * pi. |
| test.c:59:5:59:7 | call to cos | Call to periodic trigonometric function cos with maximum argument absolute value of 314, which exceeds the recommended maximum of 10 * pi. |
| test.c:60:5:60:7 | call to tan | Call to periodic trigonometric function tan with maximum argument absolute value of 314, which exceeds the recommended maximum of 10 * pi. |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rules/DIR-4-11/LowPrecisionPeriodicTrigonometricFunctionCall.ql
62 changes: 62 additions & 0 deletions c/misra/test/rules/DIR-4-11/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#include <math.h>
void f(int x) {
float f1 = 0.0f;
double d1 = 0.0f;
sin(f1); // COMPLIANT
cos(f1); // COMPLIANT
tan(f1); // COMPLIANT
sin(d1); // COMPLIANT
cos(d1); // COMPLIANT
tan(d1); // COMPLIANT

if (x < 10) {
f1 += 3.14;
d1 += 3.14;
sin(f1); // COMPLIANT
cos(f1); // COMPLIANT
tan(f1); // COMPLIANT
sin(d1); // COMPLIANT
cos(d1); // COMPLIANT
tan(d1); // COMPLIANT
sin(-f1); // COMPLIANT
cos(-f1); // COMPLIANT
tan(-f1); // COMPLIANT
sin(-d1); // COMPLIANT
cos(-d1); // COMPLIANT
tan(-d1); // COMPLIANT
}

if (x < 20) {
f1 = 3.14 * 10;
d1 = 3.14 * 10;
sin(f1); // NON-COMPLIANT
cos(f1); // NON-COMPLIANT
tan(f1); // NON-COMPLIANT
sin(d1); // COMPLIANT
cos(d1); // COMPLIANT
tan(d1); // COMPLIANT
sin(-f1); // NON-COMPLIANT
cos(-f1); // NON-COMPLIANT
tan(-f1); // NON-COMPLIANT
sin(-d1); // COMPLIANT
cos(-d1); // COMPLIANT
tan(-d1); // COMPLIANT
}

if (x < 30) {
f1 = 3.14 * 100;
d1 = 3.14 * 100;
sin(f1); // NON-COMPLIANT
cos(f1); // NON-COMPLIANT
tan(f1); // NON-COMPLIANT
sin(d1); // NON-COMPLIANT
cos(d1); // NON-COMPLIANT
tan(d1); // NON-COMPLIANT
sin(-f1); // NON-COMPLIANT
cos(-f1); // NON-COMPLIANT
tan(-f1); // NON-COMPLIANT
sin(-d1); // NON-COMPLIANT
cos(-d1); // NON-COMPLIANT
tan(-d1); // NON-COMPLIANT
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- `DIR-4-11` - `LowPrecisionPeriodicTrigonometricFunctionCall.ql`:
- New query within rule added to detect calls to periodic trigonometric functions with values outside of pi*k for k that depends on implementation and application precision goals, assuming k=1 for 32 bit floating types and k=10 for 64 bit floating types.
17 changes: 17 additions & 0 deletions cpp/common/src/codingstandards/cpp/exclusions/c/Contracts.qll
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import codingstandards.cpp.exclusions.RuleMetadata
newtype ContractsQuery =
TDoNotViolateInLineLinkageConstraintsQuery() or
TCheckMathLibraryFunctionParametersQuery() or
TLowPrecisionPeriodicTrigonometricFunctionCallQuery() or
TFunctionErrorInformationUntestedQuery()

predicate isContractsQueryMetadata(Query query, string queryId, string ruleId, string category) {
Expand All @@ -27,6 +28,15 @@ predicate isContractsQueryMetadata(Query query, string queryId, string ruleId, s
ruleId = "DIR-4-11" and
category = "required"
or
query =
// `Query` instance for the `lowPrecisionPeriodicTrigonometricFunctionCall` query
ContractsPackage::lowPrecisionPeriodicTrigonometricFunctionCallQuery() and
queryId =
// `@id` for the `lowPrecisionPeriodicTrigonometricFunctionCall` query
"c/misra/low-precision-periodic-trigonometric-function-call" and
ruleId = "DIR-4-11" and
category = "required"
or
query =
// `Query` instance for the `functionErrorInformationUntested` query
ContractsPackage::functionErrorInformationUntestedQuery() and
Expand All @@ -52,6 +62,13 @@ module ContractsPackage {
TQueryC(TContractsPackageQuery(TCheckMathLibraryFunctionParametersQuery()))
}

Query lowPrecisionPeriodicTrigonometricFunctionCallQuery() {
//autogenerate `Query` type
result =
// `Query` type for `lowPrecisionPeriodicTrigonometricFunctionCall` query
TQueryC(TContractsPackageQuery(TLowPrecisionPeriodicTrigonometricFunctionCallQuery()))
}

Query functionErrorInformationUntestedQuery() {
//autogenerate `Query` type
result =
Expand Down
13 changes: 13 additions & 0 deletions rule_packages/c/Contracts.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@
"implementation_scope": {
"description": "This query identifies possible domain, pole and range errors on a selection of C standard library fuctions from math.h."
}
},
{
"description": "Trigonometric periodic functions have significantly less precision when called with large floating-point values.",
"kind": "problem",
"name": "The validity of values passed to trigonometric functions shall be checked",
"precision": "high",
"severity": "warning",
"short_name": "LowPrecisionPeriodicTrigonometricFunctionCall",
"tags": [
"correctness",
"external/misra/c/2012/third-edition-first-revision",
"external/misra/c/2012/amendment3"
]
}
],
"title": "The validity of values passed to library functions shall be checked"
Expand Down
Loading