mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-10-07 19:03:57 +00:00
[libc++] Add clang-tidy check for version checks
This check flags code which uses `_LIBCPP_STD_VER` the wrong way, or tries to use `__cplusplus`. It flags cases where we use `_LIBCPP_STD_VER >` instead of `_LIBCPP_STD_VER >=` and where wrong values are used (e.g. `_LIBCPP_STD_VER >= 24`). Reviewed By: ldionne, #libc Spies: libcxx-commits Differential Revision: https://reviews.llvm.org/D144261
This commit is contained in:
parent
6f216f0539
commit
07efa28314
@ -20,12 +20,12 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
template <class _Tp>
|
||||
concept __is_hh_mm_ss = __is_specialization_v<_Tp, chrono::hh_mm_ss>;
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 17
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
@ -50,6 +50,7 @@
|
||||
# define _LIBCPP_FREESTANDING
|
||||
# endif
|
||||
|
||||
// NOLINTBEGIN(libcpp-cpp-version-check)
|
||||
# ifndef _LIBCPP_STD_VER
|
||||
# if __cplusplus <= 201103L
|
||||
# define _LIBCPP_STD_VER 11
|
||||
@ -64,6 +65,7 @@
|
||||
# define _LIBCPP_STD_VER 23
|
||||
# endif
|
||||
# endif // _LIBCPP_STD_VER
|
||||
// NOLINTEND(libcpp-cpp-version-check)
|
||||
|
||||
# if defined(__ELF__)
|
||||
# define _LIBCPP_OBJECT_FORMAT_ELF 1
|
||||
@ -181,6 +183,7 @@
|
||||
# define _LIBCPP_TOSTRING2(x) #x
|
||||
# define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
|
||||
|
||||
// NOLINTNEXTLINE(libcpp-cpp-version-check)
|
||||
# if __cplusplus < 201103L
|
||||
# define _LIBCPP_CXX03_LANG
|
||||
# endif
|
||||
|
@ -513,8 +513,6 @@ put_time(const tm* __tm, const _CharT* __fmt)
|
||||
return __iom_t10<_CharT>(__tm, __fmt);
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 11
|
||||
|
||||
template <class _CharT, class _Traits>
|
||||
_LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
|
||||
__quoted_output(basic_ostream<_CharT, _Traits>& __os,
|
||||
@ -622,8 +620,6 @@ __quoted(basic_string<_CharT, _Traits, _Allocator>& __s, _CharT __delim = _CharT
|
||||
return __quoted_proxy<_CharT, _Traits, _Allocator>(__s, __delim, __escape);
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 11
|
||||
|
||||
#if _LIBCPP_STD_VER >= 14
|
||||
|
||||
template <class _CharT>
|
||||
|
@ -17,6 +17,7 @@ endif()
|
||||
set(SOURCES
|
||||
abi_tag_on_virtual.cpp
|
||||
hide_from_abi.cpp
|
||||
proper_version_checks.cpp
|
||||
qualify_declval.cpp
|
||||
robust_against_adl.cpp
|
||||
uglify_attributes.cpp
|
||||
|
@ -11,8 +11,9 @@
|
||||
|
||||
#include "abi_tag_on_virtual.hpp"
|
||||
#include "hide_from_abi.hpp"
|
||||
#include "robust_against_adl.hpp"
|
||||
#include "proper_version_checks.hpp"
|
||||
#include "qualify_declval.hpp"
|
||||
#include "robust_against_adl.hpp"
|
||||
#include "uglify_attributes.hpp"
|
||||
|
||||
namespace {
|
||||
@ -21,6 +22,7 @@ public:
|
||||
void addCheckFactories(clang::tidy::ClangTidyCheckFactories& check_factories) override {
|
||||
check_factories.registerCheck<libcpp::abi_tag_on_virtual>("libcpp-avoid-abi-tag-on-virtual");
|
||||
check_factories.registerCheck<libcpp::hide_from_abi>("libcpp-hide-from-abi");
|
||||
check_factories.registerCheck<libcpp::proper_version_checks>("libcpp-cpp-version-check");
|
||||
check_factories.registerCheck<libcpp::robust_against_adl_check>("libcpp-robust-against-adl");
|
||||
check_factories.registerCheck<libcpp::uglify_attributes>("libcpp-uglify-attributes");
|
||||
check_factories.registerCheck<libcpp::qualify_declval>("libcpp-qualify-declval");
|
||||
|
@ -0,0 +1,74 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "proper_version_checks.hpp"
|
||||
|
||||
#include <clang/Lex/Lexer.h>
|
||||
#include <clang/Lex/PPCallbacks.h>
|
||||
#include <clang/Lex/Preprocessor.h>
|
||||
|
||||
namespace libcpp {
|
||||
namespace {
|
||||
class proper_version_checks_callbacks : public clang::PPCallbacks {
|
||||
public:
|
||||
proper_version_checks_callbacks(clang::Preprocessor& preprocessor, clang::tidy::ClangTidyCheck& check)
|
||||
: preprocessor_(preprocessor), check_(check) {}
|
||||
|
||||
void If(clang::SourceLocation location, clang::SourceRange condition_range, ConditionValueKind) override {
|
||||
check_condition(location, condition_range);
|
||||
}
|
||||
|
||||
void Elif(clang::SourceLocation location,
|
||||
clang::SourceRange condition_range,
|
||||
ConditionValueKind,
|
||||
clang::SourceLocation if_location) override {
|
||||
check_condition(location, condition_range);
|
||||
}
|
||||
|
||||
private:
|
||||
void check_condition(clang::SourceLocation location, clang::SourceRange condition_range) {
|
||||
std::string_view condition = clang::Lexer::getSourceText(
|
||||
clang::CharSourceRange::getTokenRange(condition_range),
|
||||
preprocessor_.getSourceManager(),
|
||||
preprocessor_.getLangOpts());
|
||||
if (preprocessor_.getSourceManager().isInMainFile(location))
|
||||
return;
|
||||
|
||||
if (condition.starts_with("_LIBCPP_STD_VER") && condition.find(">") != std::string_view::npos &&
|
||||
condition.find(">=") == std::string_view::npos)
|
||||
check_.diag(location, "_LIBCPP_STD_VER >= version should be used instead of _LIBCPP_STD_VER > prev_version");
|
||||
|
||||
else if (condition.starts_with("__cplusplus"))
|
||||
check_.diag(location, "Use _LIBCPP_STD_VER instead of __cplusplus to constrain based on the C++ version");
|
||||
|
||||
else if (condition == "_LIBCPP_STD_VER >= 11")
|
||||
check_.diag(location, "_LIBCPP_STD_VER >= 11 is always true. Did you mean '#ifndef _LIBCPP_CXX03_LANG'?");
|
||||
|
||||
else if (condition.starts_with("_LIBCPP_STD_VER >= ") &&
|
||||
std::ranges::none_of(std::array{"14", "17", "20", "23"}, [&](auto val) {
|
||||
return condition.find(val) != std::string_view::npos;
|
||||
}))
|
||||
check_.diag(location, "Not a valid value for _LIBCPP_STD_VER. Use 14, 17, 20 or 23");
|
||||
}
|
||||
|
||||
clang::Preprocessor& preprocessor_;
|
||||
clang::tidy::ClangTidyCheck& check_;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
proper_version_checks::proper_version_checks(llvm::StringRef name, clang::tidy::ClangTidyContext* context)
|
||||
: clang::tidy::ClangTidyCheck(name, context) {}
|
||||
|
||||
void proper_version_checks::registerPPCallbacks(
|
||||
const clang::SourceManager& source_manager,
|
||||
clang::Preprocessor* preprocessor,
|
||||
clang::Preprocessor* module_expander) {
|
||||
preprocessor->addPPCallbacks(std::make_unique<proper_version_checks_callbacks>(*preprocessor, *this));
|
||||
}
|
||||
|
||||
} // namespace libcpp
|
@ -0,0 +1,19 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang-tidy/ClangTidyCheck.h"
|
||||
|
||||
namespace libcpp {
|
||||
class proper_version_checks : public clang::tidy::ClangTidyCheck {
|
||||
public:
|
||||
proper_version_checks(llvm::StringRef, clang::tidy::ClangTidyContext*);
|
||||
void registerPPCallbacks(const clang::SourceManager& source_manager,
|
||||
clang::Preprocessor* preprocessor,
|
||||
clang::Preprocessor* module_expander) override;
|
||||
};
|
||||
} // namespace libcpp
|
Loading…
Reference in New Issue
Block a user