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

Fix clang-tidy warnings to make it actually useful #1048

Merged
merged 59 commits into from
Jan 13, 2025
Merged

Conversation

azrogers
Copy link
Contributor

@azrogers azrogers commented Dec 19, 2024

When we first added clang-tidy to Cesium Native, we left the warnings as merely informational, because there were too many of them to fix at the moment. Unfortunately, this leaves clang-tidy as an afterthought, because I don't imagine many of us are poking through the CI logs to see if our changes produced any new clang-tidy warnings when there's already hundreds of existing warnings. This change attempts to fix this: resolve the existing warnings, enable any useful checks that weren't already enabled, and treat the warnings as errors so we'll notice them.

Changes in this PR:

  • clang-tidy on CI now uses clang-tidy version 19, because earlier versions don't support the ExcludeHeaderFilterRegex config option we're using to remove ezvcpkg headers from the build.
  • We are now following Include-What-You-Use, thanks to clang-tidy's misc-include-cleaner check. This has resulted in pretty much every file in the project receiving a change, but it's worth it.
  • Every bugprone clang-tidy check has been enabled, with the following exceptions:
    • bugprone-exception-escape, as fixing this is already a pending issue (Functions are declared noexcept, even though they may throw #348).
    • bugprone-misplaced-widening-cast, as it results in extremely verbose lines (like size_t pixels = static_cast<size_t>(image.width) * static_cast<size_t>(image.height) * static_cast<size_t>(image.channels) instead of just size_t pixels = static_cast<size_t>(image.width * image.height * image.channels).
    • bugprone-unhandled-exception-at-new, as this is both part of Functions are declared noexcept, even though they may throw #348, and also extremely nitpicky - I don't think we need to wrap every call to new in a try...catch.
  • Most modernize and misc checks have been enabled, where they didn't conflict with the style guide or produce way too many changes for one PR. The following I decided were too much for just this PR, but they can be automatically applied at a later date using clang-tidy-fix:
    • misc-const-correctness detects every variable that could be declared const.
    • modernize-loop-convert uses range-based for loops instead of manually advancing the iterator.
    • modernize-type-traits changes traits<...>::type and traits<..>::value to traits_t<...> and traits_v<...>
    • modernize-use-constraints replaces std::enable_if with C++20 requires clauses.
    • modernize-use-using replaces typedef with using.
    • modernize-return-braced-init-list replaces statements like return glm::dvec2(0.5, 0.5); with return {0.5, 0.5};
    • modernize-use-designated-initializers would mean adding .field= to initializer statements, like {.x = 0.5, .y = 0.5}, which would prevent bugs when changing the order of fields.
  • All performance checks have been enabled, with the exception of performance-enum-size, as I felt that saving three bytes by defining an enum with int8_t instead of the default int32_t didn't seem like it was worth the change.
  • readability checks are mostly style guide-related, but might be worth looking into. readability-else-after-return and readability-braces-around-statements seem like they could be good to add.
  • All warnings are now treated as errors.

Fixes #203

@azrogers
Copy link
Contributor Author

azrogers commented Jan 6, 2025

@kring When you're back, I believe I've tackled the remaining review comments.

@@ -708,7 +732,7 @@ void updateExtensionWithJsonStringProperty(
// Because serialized string json will add double quotations in the
// buffer which is not needed by us, we will manually add the string to
// the buffer
const auto& rapidjsonStr = it->IsNull() ? *noDataValue : it->GetString();
const auto& rapidjsonStr = it->GetString();
Copy link
Member

@kring kring Jan 13, 2025

Choose a reason for hiding this comment

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

The more I look at this code, the more I think it's wrong (both before and after this PR).

The intention of this if/else is, AFAICT, to make sure that property values are shown the same way they would be if serialize to JSON, except that strings should not be quoted. So we should go into the if when we have a non-string, and into the else when we have a string (so that we can remove the quotes).

Mostly this is straightforward, but there's one tricky bit. If the value is null, and the property has a default value, then we need to use that default value (which is always a string).

But that's not what this code is going to do. If the value is null, then it->IsString() will be false, and so we'll always go into the if block and never the else. That will end up writing the string null to the buffer instead of the default value.

I believe the correct code looks roughly like:

if (it->IsString() || (it->IsNull() && noDataValue)) {
    // use string formatting that removes quotes
} else {
    // Use JSON formatting
}

I'll make this change and push it into this PR.

@kring
Copy link
Member

kring commented Jan 13, 2025

I've reviewed everything now and it all looks great. Just a couple comments/questions above and this is ready to merge!

@azrogers
Copy link
Contributor Author

Addressed your comments @kring!

@kring
Copy link
Member

kring commented Jan 13, 2025

Thanks @azrogers! 🎉

@kring kring merged commit 132f87a into main Jan 13, 2025
22 checks passed
@kring kring deleted the clang-tidy-cleanup branch January 13, 2025 22:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add clang-tidy and cppcheck to CI process
3 participants