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

iox-#1394 iox-#1196 Address Axivion and clang-tidy findings for cxx::function_ref #1456

Conversation

mossmaurice
Copy link
Contributor

@mossmaurice mossmaurice commented Jul 6, 2022

Signed-off-by: Simon Hoinkis [email protected]

Pre-Review Checklist for the PR Author

  1. Code follows the coding style of CONTRIBUTING.md
  2. Tests follow the best practice for testing
  3. Changelog updated in the unreleased section including API breaking changes
  4. Branch follows the naming format (iox-#123-this-is-a-branch)
  5. Commits messages are according to this guideline
    • Commit messages have the issue ID (iox-#123 commit text)
    • Commit messages are signed (git commit -s)
    • Commit author matches Eclipse Contributor Agreement (and ECA is signed)
  6. Update the PR title
    • Follow the same conventions as for commit messages
    • Link to the relevant issue
  7. Relevant issues are linked
  8. Add sensible notes for the reviewer
  9. All checks have passed (except task-list-completed)
  10. Assign PR to reviewer

Notes for Reviewer

Todo

  • Some suppressions not considered by Axivion -> Fixed
  • M7-1-2: Shall constness of 'target' be changed?
  • Discuss A2-7-3 and A14-5-2

Checklist for the PR Reviewer

  • Commits are properly organized and messages are according to the guideline
  • Code according to our coding style and naming conventions
  • Unit tests have been written for new behavior
    • Each unit test case has a unique UUID
  • Public API changes are documented via doxygen
  • Copyright owner are updated in the changed files
  • PR title describes the changes

Post-review Checklist for the PR Author

  1. All open points are addressed and tracked via issues

References

@mossmaurice mossmaurice added the AUTOSAR Warning of an Adpative Autosar C++14 rule label Jul 6, 2022
@mossmaurice mossmaurice self-assigned this Jul 6, 2022
@mossmaurice mossmaurice changed the title iox-#1394 Address Axivion findings for cxx::function_ref iox-#1394 Address Axivion findings for cxx::function_ref Jul 6, 2022
@mossmaurice mossmaurice added the CERT Warning of a SEI CERT C++ 2016 rule label Jul 6, 2022
@mossmaurice mossmaurice force-pushed the iox-#1394-fix-axivion-warning-in-function-ref branch from 5fcd3c6 to bbcf4c2 Compare July 6, 2022 13:47
@codecov
Copy link

codecov bot commented Jul 6, 2022

Codecov Report

Merging #1456 (16fd6c2) into master (ebc67df) will increase coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1456      +/-   ##
==========================================
+ Coverage   78.75%   78.76%   +0.01%     
==========================================
  Files         379      379              
  Lines       14477    14477              
  Branches     2012     2012              
==========================================
+ Hits        11401    11403       +2     
+ Misses       2436     2435       -1     
+ Partials      640      639       -1     
Flag Coverage Δ
unittests 78.42% <100.00%> (+0.01%) ⬆️
unittests_timing 14.87% <75.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...nclude/iceoryx_hoofs/internal/cxx/function_ref.inl 93.33% <100.00%> (ø)
iceoryx_posh/source/mepoo/memory_manager.cpp 97.08% <0.00%> (+1.94%) ⬆️

@mossmaurice mossmaurice marked this pull request as ready for review July 11, 2022 09:12
@mossmaurice mossmaurice added the clang-tidy Warning of a clang-tidy rule label Jul 11, 2022
@mossmaurice mossmaurice changed the title iox-#1394 Address Axivion findings for cxx::function_ref iox-#1394 iox-#1196 Address Axivion findings for cxx::function_ref Jul 11, 2022
@mossmaurice mossmaurice force-pushed the iox-#1394-fix-axivion-warning-in-function-ref branch from 757e67e to 1840354 Compare July 11, 2022 09:19
@mossmaurice mossmaurice changed the title iox-#1394 iox-#1196 Address Axivion findings for cxx::function_ref iox-#1394 iox-#1196 Address Axivion and clang-tidy findings for cxx::function_ref Jul 11, 2022
dkroenke
dkroenke previously approved these changes Jul 12, 2022
@@ -15,15 +15,15 @@
//
// SPDX-License-Identifier: Apache-2.0

// AXIVION DISABLE STYLE AutosarC++19_03-A16.2.3 : <type_traits> is included
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually I have no idea what this is suppressing and why a <type_traits> makes it safe again. Could you elaborate this a little bit more detailed. With other warnings it is most of the time more clear since they are directly above the line which has the "warning" and one sees the context but in this case it could be easily also a cut&paste failure.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it is about type_traits from STL being used but only included indirectly. I think the proper fix is to include it directly, as is customary in C++.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@elfenpiff @MatthiasKillat For <type_traits> we have our trampoline type_traits.hpp which adds some type traits missing in C++14. I re-phrased the justification.

public:
~function_ref() noexcept = default;

function_ref(const function_ref&) noexcept = default;

function_ref& operator=(const function_ref&) noexcept = default;
function_ref& operator=(const function_ref&) & noexcept = default;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did you add a reference here? Was it a warning? Should we do this for all copy assignments?

So this rule forbids code like:

std::move(a) = b;

Which is valid and well defined but on the first glimpse weird. But take a look at this here

template<typename T>
void initializeSomeArgs(T&& args) {
    std::forward<T>(args) = someT;
}

Here we take args as universal reference (so sometimes also as rvalue reference) and would like to assign a new value to it.
Why should we forbid that? What kind of error can possible originate from that?

Copy link
Contributor

@MatthiasKillat MatthiasKillat Jul 14, 2022

Choose a reason for hiding this comment

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

@elfenpiff In the example you provided it can have outside effect, depending on the type it is instantiated with so anything can go wrong but this is no reason not to allow since this holds for any references or pointers.

While it will not be useful often (or at all) for function_ref, I do not see it should be required to restrict the assignment operator to lvalues.

@mossmaurice Edit: I thought about this. For function_ref there is probably no good use case to assign to rvalues so it is fine to prohibit this explicitly. Same for all other places where I mentioned it.

It should not be done for all classes without considering their purpose, but it is rarely useful I think.

Copy link
Contributor Author

@mossmaurice mossmaurice Jul 15, 2022

Choose a reason for hiding this comment

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

@elfenpiff That's due to AUTOSAR rule A12-8-7. Indeed

std::move(a) = b;

is weird and does not make sense. You can find more examples in the AUTOSAR document.

For your 2nd example, I suppose if it is needed in some cases, we should explicitly define foo& operator=(const foo&) && and if desired call operator=() & from there explicitly.

Copy link
Contributor

@MatthiasKillat MatthiasKillat Jul 15, 2022

Choose a reason for hiding this comment

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

If both implementations (&& and &) exist and are identical it does not make sense to distinguish. Only if one should not exist (as here) or if they both exist but are different.

It is fine if we only have one like here.

namespace iox
{
namespace cxx
{
template <class ReturnType, class... ArgTypes>
template <typename CallableType, typename>
// AXIVION Next Line AutosarC++19_03-A12.1.2 : Members are initialized in the same manner, NSDMI with nullptr is
Copy link
Contributor

Choose a reason for hiding this comment

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

In what manner are the members initialized? What does NSDMI mean?

Copy link
Contributor

Choose a reason for hiding this comment

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

https://www.cppstories.com/2015/02/non-static-data-members-initialization/

But I think this Axivion suppression is probably not the right way, @saif-at-github may know more (should it suppress the next Construct instead?). I do see any members in the next line and am not sure what this rule is about or why there is an issue.

Ideally there is nothing to suppress here, I cannot the any problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@elfenpiff https://www.giybf.com 🙃

@MatthiasKillat Correct, I switchted it to Next Construct.

The rule just says either init via the : m_foo(foo) or inline via Type m_foo{defaultValue}, but don't mix things as you might forget it in another c'tor. However, doing it explicitly in both ways, is the best IMHO.

: m_pointerToCallable(const_cast<void*>(reinterpret_cast<const void*>(std::addressof(callable))))
// AXIVION Next Line AutosarC++19_03-A15.4.4 : Lambda not 'noexcept' as callable might throw
Copy link
Contributor

Choose a reason for hiding this comment

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

With this argument the call operator must be noexcept.

Copy link
Contributor

Choose a reason for hiding this comment

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

15-4-4 states that "A declaration of non-throwing function shall contain noexcept specification.". I have no problem with that. However, any function that might throw cannot have this specificier, which means any user-defined function cannot. Hence I do not see why Axivion should complain unless it is better analyzing whether a function can throw or not than the compiler.

And even modern compilers are in general not able to do this in general, non-trivial cases (like this one). Not sure the rule is useful to enforce with this tool for this reason. If the tool produces too many false positives/negatives it is useless for this rule (while the rule itself makes sense).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@elfenpiff I don't get this, the operator()() is already noexcept.

@MatthiasKillat Correct, we need to monitor that.

@elfenpiff elfenpiff removed the request for review from MatthiasKillat July 13, 2022 09:39
@@ -15,15 +15,15 @@
//
// SPDX-License-Identifier: Apache-2.0

// AXIVION DISABLE STYLE AutosarC++19_03-A16.2.3 : <type_traits> is included
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it is about type_traits from STL being used but only included indirectly. I think the proper fix is to include it directly, as is customary in C++.

#ifndef IOX_HOOFS_CXX_FUNCTION_REF_HPP
#define IOX_HOOFS_CXX_FUNCTION_REF_HPP

// AXIVION Next Line AutosarC++19_03-A16.2.2 : Needed for Expects and Ensures macros
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the problem here? Does it not recognize that something from this header is used? (maybe because it is a macro?) ...

Copy link
Contributor Author

@mossmaurice mossmaurice Jul 15, 2022

Choose a reason for hiding this comment

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

@MatthiasKillat AFAIU Axivion does not detect that the macro from requires.hpp is used.

Copy link
Contributor

@MatthiasKillat MatthiasKillat Jul 15, 2022

Choose a reason for hiding this comment

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

I dislike that tool failure results in these suppression comments.

-1 for the tool I guess

public:
~function_ref() noexcept = default;

function_ref(const function_ref&) noexcept = default;

function_ref& operator=(const function_ref&) noexcept = default;
function_ref& operator=(const function_ref&) & noexcept = default;
Copy link
Contributor

@MatthiasKillat MatthiasKillat Jul 14, 2022

Choose a reason for hiding this comment

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

@elfenpiff In the example you provided it can have outside effect, depending on the type it is instantiated with so anything can go wrong but this is no reason not to allow since this holds for any references or pointers.

While it will not be useful often (or at all) for function_ref, I do not see it should be required to restrict the assignment operator to lvalues.

@mossmaurice Edit: I thought about this. For function_ref there is probably no good use case to assign to rvalues so it is fine to prohibit this explicitly. Same for all other places where I mentioned it.

It should not be done for all classes without considering their purpose, but it is rarely useful I think.

iceoryx_hoofs/include/iceoryx_hoofs/cxx/function_ref.hpp Outdated Show resolved Hide resolved
auto f = reinterpret_cast<ReturnType (*)(ArgTypes...)>(target);
m_functionPointer([](void* target, ArgTypes... args) -> ReturnType {
using PointerType = ReturnType (*)(ArgTypes...);
// AXIVION Next Construct AutosarC++19_03-A5.2.4 : Type-safety ensured by casting from type
Copy link
Contributor

Choose a reason for hiding this comment

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

Type safety is ensured by the fact we only pass functions with this type as target, i.e. they are convertible.

This is entirely under the control of the class.

Copy link
Contributor

Choose a reason for hiding this comment

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

@mossmaurice I still find the justification lacking here, hence my comment about the reason.

Without extra knowledge of how it works, I could not infer it from the justification.

More precisely
the class design ensures a cast to the actual type of target

@mossmaurice mossmaurice force-pushed the iox-#1394-fix-axivion-warning-in-function-ref branch from 1840354 to c9c54dd Compare July 15, 2022 09:23
@mossmaurice
Copy link
Contributor Author

@elfenpiff @MatthiasKillat @elBoberido

The combination of clang-tidy and Axivion suppression has been confirmed to work in a call with Axivion yesterday:

// AXIVION Next Construct Ruleset-A1.2.3 : Because foo and bar
// NOLINTNEXTLINE (foobar)

Copy link
Contributor

@MatthiasKillat MatthiasKillat left a comment

Choose a reason for hiding this comment

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

Looks good. I think some justifications wrt. type erasure are not quite clear and need some detail/rewording.

public:
~function_ref() noexcept = default;

function_ref(const function_ref&) noexcept = default;

function_ref& operator=(const function_ref&) noexcept = default;
function_ref& operator=(const function_ref&) & noexcept = default;
Copy link
Contributor

@MatthiasKillat MatthiasKillat Jul 15, 2022

Choose a reason for hiding this comment

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

If both implementations (&& and &) exist and are identical it does not make sense to distinguish. Only if one should not exist (as here) or if they both exist but are different.

It is fine if we only have one like here.

, m_functionPointer([](void* target, ArgTypes... args) -> ReturnType {
// AXIVION Next Construct AutosarC++19_03-A5.2.4, CertC++-EXP36 : Type-safety ensured by casting from type
Copy link
Contributor

Choose a reason for hiding this comment

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

@mossmaurice I still think the justification is not accurate/understandable. type erasure should be mentioned.

auto f = reinterpret_cast<ReturnType (*)(ArgTypes...)>(target);
m_functionPointer([](void* target, ArgTypes... args) -> ReturnType {
using PointerType = ReturnType (*)(ArgTypes...);
// AXIVION Next Construct AutosarC++19_03-A5.2.4 : Type-safety ensured by casting from type
Copy link
Contributor

Choose a reason for hiding this comment

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

@mossmaurice I still find the justification lacking here, hence my comment about the reason.

Without extra knowledge of how it works, I could not infer it from the justification.

More precisely
the class design ensures a cast to the actual type of target

@mossmaurice mossmaurice force-pushed the iox-#1394-fix-axivion-warning-in-function-ref branch from ffd5a26 to 16fd6c2 Compare July 15, 2022 12:01
@mossmaurice mossmaurice merged commit 9537beb into eclipse-iceoryx:master Jul 15, 2022
@mossmaurice mossmaurice deleted the iox-#1394-fix-axivion-warning-in-function-ref branch July 15, 2022 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AUTOSAR Warning of an Adpative Autosar C++14 rule CERT Warning of a SEI CERT C++ 2016 rule clang-tidy Warning of a clang-tidy rule
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Address Autosar Violations using Axivion Enable clang-tidy checks and fix warnings in code
4 participants