Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

M5-0-*: Ignore explicit casts when identifying cvalues by parent #778

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
| test.cpp:11:8:11:14 | (int16_t)... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:11:8:11:14 | ... + ... | expression |
| test.cpp:11:8:11:14 | ... + ... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:11:8:11:14 | ... + ... | expression |
| test.cpp:13:8:13:13 | ... + ... | Implicit conversion converts cvalue $@ from signed short to signed int. | test.cpp:13:8:13:13 | ... + ... | expression |
| test.cpp:12:8:12:14 | (int16_t)... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:12:8:12:14 | ... + ... | expression |
| test.cpp:12:8:12:14 | ... + ... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:12:8:12:14 | ... + ... | expression |
| test.cpp:14:8:14:13 | ... + ... | Implicit conversion converts cvalue $@ from signed short to signed int. | test.cpp:14:8:14:13 | ... + ... | expression |
| test.cpp:23:13:23:19 | (int16_t)... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:23:13:23:19 | ... + ... | expression |
| test.cpp:30:12:30:18 | (int16_t)... | Implicit conversion converts cvalue $@ from signed char to signed short. | test.cpp:30:12:30:18 | ... + ... | expression |
18 changes: 18 additions & 0 deletions cpp/autosar/test/rules/M5-0-3/test.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <cstdint>

void f1() {
using std::int16_t;
using std::int32_t;
Expand All @@ -13,4 +14,21 @@ void f1() {
l3 = l2 + 1; // NON_COMPLIANT
l3 = static_cast<int32_t>(l2) + 1; // COMPLIANT
l3 = l2 + 0x01ffff; // COMPLIANT
}

void int16_arg(std::int16_t t);

void test_func_call() {
std::int8_t l1;
int16_arg(l1 + l1); // NON_COMPLIANT
int16_arg(static_cast<std::int16_t>(l1 + l1)); // COMPLIANT
}

std::int16_t test_return(int test) {
std::int8_t l1;
if (test > 0) {
return l1 + l1; // NON_COMPLIANT
} else {
return static_cast<std::int16_t>(l1 + l1); // COMPLIANT
}
}
9 changes: 9 additions & 0 deletions cpp/autosar/test/rules/M5-0-7/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,13 @@ void f1() {
s16a = static_cast<int16_t>(f32a / f32b); // NON_COMPLIANT
s16a = static_cast<int16_t>(f32a); // COMPLIANT
s16a = static_cast<int16_t>(f32a) / f32b; // COMPLIANT
}

void int_arg(std::int32_t i);

std::int16_t test_args() {
float f32a;
float f32b;
int_arg(static_cast<std::int16_t>(f32a)); // COMPLIANT - f32a is not a cvalue
return static_cast<std::int16_t>(f32a); // COMPLIANT - f32a is not a cvalue
}
18 changes: 18 additions & 0 deletions cpp/autosar/test/rules/M5-0-8/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,22 @@ void f() {
f64 = static_cast<double>(1.0f + 1.0f); // NON_COMPLIANT
f32 = static_cast<float>(1.0f + 1); // COMPLIANT
f64 = static_cast<double>(1.0 + 1); // COMPLIANT; no suffix defines a double
}

#include <vector>

void function_args() {
std::vector<std::uint8_t> v{0};

std::uint32_t u32{0};
v.at(static_cast<std::size_t>(u32)); // COMPLIANT - cast is not a cvalue
std::size_t st =
static_cast<std::size_t>(u32); // COMPLIANT - cast is not a cvalue
v.at(st);
}

std::size_t return_args() {
std::uint32_t u32{0};

return static_cast<std::size_t>(u32); // COMPLIANT
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
| test.cpp:16:8:16:35 | static_cast<int8_t>... | Explicit integral conversion converts the signedness of the $@ from unsigned to signed. | test.cpp:16:28:16:34 | ... + ... | cvalue |
| test.cpp:18:8:18:40 | static_cast<int8_t>... | Explicit integral conversion converts the signedness of the $@ from unsigned to signed. | test.cpp:18:28:18:39 | ... + ... | cvalue |
| test.cpp:20:8:20:35 | static_cast<int8_t>... | Explicit integral conversion converts the signedness of the $@ from unsigned to signed. | test.cpp:20:28:20:34 | ... * ... | cvalue |
| test.cpp:20:8:20:35 | static_cast<int8_t>... | Explicit integral conversion converts the signedness of the $@ from unsigned to signed. | test.cpp:20:28:20:34 | ... + ... | cvalue |
| test.cpp:22:8:22:40 | static_cast<int8_t>... | Explicit integral conversion converts the signedness of the $@ from unsigned to signed. | test.cpp:22:28:22:39 | ... + ... | cvalue |
| test.cpp:24:8:24:35 | static_cast<int8_t>... | Explicit integral conversion converts the signedness of the $@ from unsigned to signed. | test.cpp:24:28:24:34 | ... * ... | cvalue |
7 changes: 7 additions & 0 deletions cpp/autosar/test/rules/M5-0-9/test.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#include <cstdint>

void signed_arg(std::uint32_t s);
void unsigned_arg(std::uint32_t u);

void f() {
using std::int16_t;
using std::int32_t;
Expand All @@ -22,4 +26,7 @@ void f() {
i16 = static_cast<int16_t>(i16 / i8); // NON_COMPLIANT

i8 = static_cast<int8_t>(u8) + static_cast<int8_t>(u8); // COMPLIANT

unsigned(static_cast<uint32_t>(i32)); // COMPLIANT - i32 is not a cvalue
signed(static_cast<int32_t>(u32)); // COMPLIANT - u32 is not a cvalue
}
12 changes: 10 additions & 2 deletions cpp/common/src/codingstandards/cpp/Expr.qll
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,17 @@ module MisraExpr {
private predicate isCValue(Expr e) {
not e.isConstant() and
(
exists(ReturnStmt return | e = return.getExpr())
exists(ReturnStmt return |
e = return.getExpr() and
// Only return statements which are not explicitly casted are considered
not exists(Cast c | not c.isImplicit() and c.getExpr() = e)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See topline comment.

Perhaps this should be something like,e.getExplicitlyConverted() = return.getExpr() ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that's a good spot, I will make that change!

)
or
exists(Call call | e = call.getAnArgument())
exists(FunctionCall call |
e = call.getAnArgument() and
// // Only function arguments which are not explicitly casted are considered
not exists(Cast c | not c.isImplicit() and c.getExpr() = e)
)
)
or
isCValue(e.(ParenthesisExpr).getExpr())
Expand Down
Loading