Skip to content

Commit

Permalink
Add clang-tidy check for overflow in constructing energy quantity fro…
Browse files Browse the repository at this point in the history
…m int
  • Loading branch information
BrettDong committed Feb 2, 2024
1 parent fa7c040 commit 8e4847d
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 0 deletions.
2 changes: 2 additions & 0 deletions tools/clang-tidy-plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ set(CataAnalyzerSrc
TranslationsInDebugMessagesCheck.cpp
TranslatorCommentsCheck.cpp
U8PathCheck.cpp
UnitOverflowCheck.cpp
UnsequencedCallsCheck.cpp
UnusedStaticsCheck.cpp
UseLocalizedSortingCheck.cpp
Expand All @@ -54,6 +55,7 @@ if (CATA_CLANG_TIDY_EXECUTABLE)
else ()
set(CataAnalyzerName CataAnalyzerPlugin)
add_library(${CataAnalyzerName} MODULE ${CataAnalyzerSrc})
target_link_libraries(${CataAnalyzerName} PRIVATE clangTidy)
endif ()

target_include_directories(${CataAnalyzerName} SYSTEM PRIVATE
Expand Down
2 changes: 2 additions & 0 deletions tools/clang-tidy-plugin/CataTidyModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "TranslationsInDebugMessagesCheck.h"
#include "TranslatorCommentsCheck.h"
#include "U8PathCheck.h"
#include "UnitOverflowCheck.h"
#include "UnsequencedCallsCheck.h"
#include "UnusedStaticsCheck.h"
#include "UseLocalizedSortingCheck.h"
Expand Down Expand Up @@ -100,6 +101,7 @@ class CataModule : public ClangTidyModule
"cata-translations-in-debug-messages" );
CheckFactories.registerCheck<TranslatorCommentsCheck>( "cata-translator-comments" );
CheckFactories.registerCheck<U8PathCheck>( "cata-u8-path" );
CheckFactories.registerCheck<UnitOverflowCheck>( "cata-unit-overflow" );
CheckFactories.registerCheck<UnsequencedCallsCheck>( "cata-unsequenced-calls" );
CheckFactories.registerCheck<UnusedStaticsCheck>( "cata-unused-statics" );
CheckFactories.registerCheck<UseLocalizedSortingCheck>( "cata-use-localized-sorting" );
Expand Down
67 changes: 67 additions & 0 deletions tools/clang-tidy-plugin/UnitOverflowCheck.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "UnitOverflowCheck.h"
#include "Utils.h"

#include <clang/ASTMatchers/ASTMatchers.h>
#include <clang/Basic/Diagnostic.h>

#include <string>
#include <utility>
#include <vector>

using namespace clang::ast_matchers;

namespace clang::tidy::cata
{

static std::vector<std::pair<std::string_view, std::string_view>> unitFunctions {
{"energy", "from_joule"},
{"energy", "from_kilojoule"},
};

static std::string_view unitOfFunction( const std::string_view queryFunctionName )
{
for( const auto &[unit, functionName] : unitFunctions ) {
if( queryFunctionName == functionName ) {
return unit;
}
}
return "?";
}

void UnitOverflowCheck::registerMatchers( ast_matchers::MatchFinder *Finder )
{
for( const auto &[unit, functionName] : unitFunctions ) {
Finder->addMatcher(
callExpr( callee( functionDecl( hasName( functionName ) ).bind( "func" ) ), hasArgument( 0,
expr( hasType(
isInteger() ) ).bind(
"arg" ) ) ),
this
);
}
}

void UnitOverflowCheck::check( const ast_matchers::MatchFinder::MatchResult &Result )
{
const FunctionDecl *func = Result.Nodes.getNodeAs<FunctionDecl>( "func" );
const Expr *arg = Result.Nodes.getNodeAs<Expr>( "arg" );
if( !func || !arg ) {
return;
}
const QualType type = arg->getType();
const std::uint64_t width = Result.Context->getTypeInfo( type ).Width;
if( width >= 64 ) {
return;
}
const SourceManager &sourceManager = *Result.SourceManager;
if( sourceManager.getFilename( arg->getBeginLoc() ).ends_with( "src/units.h" ) ) {
return;
}
diag( arg->getBeginLoc(),
"constructing a %0 quantity from '%1' potentially overflows inside '%2' in multiplying with conversion factor" )
<< unitOfFunction( func->getNameAsString() ) << type.getAsString() << func->getName()
<< FixItHint::CreateReplacement( arg->getSourceRange(),
( Twine( "static_cast<std::int64_t>( " ) + getText( Result, arg ) + " )" ).str() );
}

}

Check failure on line 67 in tools/clang-tidy-plugin/UnitOverflowCheck.cpp

View workflow job for this annotation

GitHub Actions / build (other)

namespace 'clang::tidy::cata' not terminated with a closing comment [llvm-namespace-comment,-warnings-as-errors]
30 changes: 30 additions & 0 deletions tools/clang-tidy-plugin/UnitOverflowCheck.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef CATA_TOOLS_CLANG_TIDY_PLUGIN_UNITOVERFLOWCHECK_H
#define CATA_TOOLS_CLANG_TIDY_PLUGIN_UNITOVERFLOWCHECK_H

#include <clang-tidy/ClangTidy.h>
#include <clang-tidy/ClangTidyCheck.h>
#include <clang/ASTMatchers/ASTMatchFinder.h>

namespace clang
{

namespace tidy
{
class ClangTidyContext;

namespace cata
{

class UnitOverflowCheck : public ClangTidyCheck
{
public:
UnitOverflowCheck( StringRef Name, ClangTidyContext *Context ) : ClangTidyCheck( Name, Context ) {}
void registerMatchers( ast_matchers::MatchFinder *Finder ) override;
void check( const ast_matchers::MatchFinder::MatchResult &Result ) override;
};

} // namespace cata
} //namespace tidy
} // namespace clang

#endif // CATA_TOOLS_CLANG_TIDY_PLUGIN_UNITOVERFLOWCHECK_H

0 comments on commit 8e4847d

Please sign in to comment.