Skip to content

Fix a number of clang-tidy detected defects#22416

Open
jblomer wants to merge 36 commits into
root-project:masterfrom
jblomer:tidy
Open

Fix a number of clang-tidy detected defects#22416
jblomer wants to merge 36 commits into
root-project:masterfrom
jblomer:tidy

Conversation

@jblomer

@jblomer jblomer commented May 28, 2026

Copy link
Copy Markdown
Contributor

A test run of clang-tidy on the RNTuple code with the following checks

Checks: 'bugprone-*,-bugprone-assignment-in-if-condition,-bugprone-branch-clone,-bugprone-derived-method-shadowing-base-method,-bugprone-easily-swappable-parameters,-bugprone-implicit-widening-of-multiplication-result,-bugprone-incorrect-enable-if,-bugprone-macro-parentheses,-bugprone-multi-level-implicit-pointer-conversion,-bugprone-narrowing-conversions,-bugprone-not-null-terminated-result,-bugprone-random-generator-seed,-bugprone-reserved-identifier,-bugprone-signed-char-misuse,-bugprone-std-namespace-modification,-bugprone-switch-missing-default-case,-bugprone-throwing-static-initialization,-bugprone-too-small-loop-variable,-bugprone-unchecked-optional-access,-bugprone-unhandled-self-assignment,-bugprone-unused-return-value,-bugprone-virtual-near-miss,cppcoreguidelines-virtual-class-destructor,misc-*,-misc-non-private-member-variables-in-classes,-misc-include-cleaner,-misc-misplaced-const,-misc-multiple-inheritance,-misc-no-recursion,misc-non-copyable-objects,-misc-non-private-member-variables-in-classes,-misc-predictable-rand,-misc-unconventional-assign-operator,-misc-use-anonymous-namespace,performance-*,-performance-enum-size,-performance-inefficient-string-concatenation,-performance-no-int-to-ptr,-performance-noexcept-swap,readability-duplicate-include,readability-delete-null-pointer,readability-misleading-indentation,readability-redundant-control-flow,readability-redundant-declaration,readability-redundant-function-ptr-dereference,readability-reference-to-constructed-temporary'

@jblomer jblomer self-assigned this May 28, 2026
@jblomer jblomer requested review from dpiparo and pcanal as code owners May 28, 2026 12:14
@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown

Test Results

    20 files      20 suites   3d 6h 35m 22s ⏱️
 3 865 tests  3 852 ✅   0 💤 13 ❌
68 876 runs  68 745 ✅ 118 💤 13 ❌

For more details on these failures, see this check.

Results for commit 135b5ba.

♻️ This comment has been updated with latest results.

@dpiparo dpiparo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for these changes! Would it be useful to expand this kind of campaigns to other portions of the codebase, e.g. roofit or RDF, or explore other checks?

{
return 0 == name.compare(0, 17, "std::__pair_base<") || 0 == name.compare(0, 12, "__pair_base<");
}
inline std::string GetUniquePtrType(std::string_view name)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

TClassEdit is a public interface and thus this 'could' be used outside of ROOT. Should we deprecated it instead of removing it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Note that the function as is returns a temporary, so it may crash if actually used. No one complained so far.

I can still deprecate it but I'd have a preference for removing. Let me know if you'd prefer a slower removal.

@pcanal pcanal left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM.

@ferdymercury

Copy link
Copy Markdown
Collaborator

Thanks for this, it's great!

Thanks for these changes! Would it be useful to expand this kind of campaigns to other portions of the codebase, e.g. roofit or RDF, or explore other checks?

Yes. Maybe even sth like:
https://github.com/HorstBaerbel/action-clang-tidy
or
https://github.com/marketplace/actions/clang-tidy-review
https://github.com/marketplace/actions/c-c-linter

@hahnjo hahnjo self-requested a review June 4, 2026 11:32
Comment thread core/foundation/inc/ROOT/RError.hxx
Comment thread core/foundation/inc/ROOT/RError.hxx Outdated
Comment thread core/foundation/src/RError.cxx Outdated
@jblomer

jblomer commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for this, it's great!

Thanks for these changes! Would it be useful to expand this kind of campaigns to other portions of the codebase, e.g. roofit or RDF, or explore other checks?

Yes. Maybe even sth like: https://github.com/HorstBaerbel/action-clang-tidy or https://github.com/marketplace/actions/clang-tidy-review https://github.com/marketplace/actions/c-c-linter

Maybe. I think the next step would be a regular clang-tidy check for RNTuple as part of the CI. Looking into it.

@jblomer jblomer force-pushed the tidy branch 2 times, most recently from b6666a1 to 45e70d6 Compare June 8, 2026 13:28

@hahnjo hahnjo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

~RResult() = default;

/// Used by R__FORWARD_RESULT in order to keep track of the stack trace in case of errors
RResult &Forward(RError::RLocation &&sourceLocation)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Still taking xvalue reference, not sure if this should also take const ref

@@ -280,7 +303,7 @@ public:
RResult &Forward(RError::RLocation &&sourceLocation)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Still taking xvalue reference, not sure if this should also take const ref

@jblomer jblomer added the clean build Ask CI to do non-incremental build on PR label Jun 11, 2026
jblomer added 26 commits June 15, 2026 17:20
With commit c5ee8b5 (enable unique_ptr
support for nested STL collections), the method
TClassEdit::GetUniquePtrType() became obsolete.

@silverweed silverweed left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks! I have just a few comments

{
// A copy constructor of an exception should not throw; otherwise, during `throw RException(...)`,
// a second exception may be thrown that would immediately terminate the program.
// The fError member may throw due to the memory allocation in its string and vector members.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If we OOM, don't we want to terminate the program anyway?

std::string GetRenormalizedMetaTypeName(const std::string &metaNormalizedName)
{
const auto canonicalTypePrefix = ROOT::Internal::GetCanonicalTypePrefix(metaNormalizedName);
auto canonicalTypePrefix = ROOT::Internal::GetCanonicalTypePrefix(metaNormalizedName);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How is this improving the performance?

RPage(const RPage &) = delete;
RPage &operator=(const RPage &) = delete;
RPage(RPage &&other)
RPage(RPage &&other) noexcept

@silverweed silverweed Jun 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any reason to make this particular class's move ctor noexcept?
EDIT: I see there are more later on, see the other comment about it

mutable std::atomic<const std::type_info *> fTypeInfo = nullptr;

RValue(RFieldBase *field, std::shared_ptr<void> objPtr) : fField(field), fObjPtr(objPtr) {}
RValue(RFieldBase *field, std::shared_ptr<void> objPtr) : fField(field), fObjPtr(std::move(objPtr)) {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are these moves actually making a difference in the generated assembly?

}
RValue(RValue &&other) : fField(other.fField), fObjPtr(std::move(other.fObjPtr)) {}
RValue &operator=(RValue &&other)
RValue(RValue &&other) noexcept : fField(other.fField), fObjPtr(std::move(other.fObjPtr)) {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we in general want to adopt this convention? I vaguely know this might have some performance implications in certain cases, but is this something worth committing to? (I'm personally not a fan of noexcept but we can discuss if it can have a concrete impact)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clean build Ask CI to do non-incremental build on PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants