summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clang-tidy')
-rw-r--r--clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp14
-rw-r--r--clang-tools-extra/clang-tidy/cert/CMakeLists.txt1
-rw-r--r--clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp74
-rw-r--r--clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.h35
4 files changed, 119 insertions, 5 deletions
diff --git a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
index 23820446cd1..3130dad68ff 100644
--- a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
@@ -19,6 +19,7 @@
#include "../performance/MoveConstructorInitCheck.h"
#include "../readability/UppercaseLiteralSuffixCheck.h"
#include "CommandProcessorCheck.h"
+#include "DefaultOperatorNewAlignmentCheck.h"
#include "DontModifyStdNamespaceCheck.h"
#include "FloatLoopCounter.h"
#include "LimitedRandomnessCheck.h"
@@ -48,11 +49,6 @@ public:
"cert-dcl58-cpp");
CheckFactories.registerCheck<google::build::UnnamedNamespaceInHeaderCheck>(
"cert-dcl59-cpp");
- // OOP
- CheckFactories.registerCheck<performance::MoveConstructorInitCheck>(
- "cert-oop11-cpp");
- CheckFactories.registerCheck<bugprone::UnhandledSelfAssignmentCheck>(
- "cert-oop54-cpp");
// ERR
CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>(
"cert-err09-cpp");
@@ -61,10 +57,18 @@ public:
CheckFactories.registerCheck<ThrownExceptionTypeCheck>("cert-err60-cpp");
CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>(
"cert-err61-cpp");
+ // MEM
+ CheckFactories.registerCheck<DefaultOperatorNewAlignmentCheck>(
+ "cert-mem57-cpp");
// MSC
CheckFactories.registerCheck<LimitedRandomnessCheck>("cert-msc50-cpp");
CheckFactories.registerCheck<ProperlySeededRandomGeneratorCheck>(
"cert-msc51-cpp");
+ // OOP
+ CheckFactories.registerCheck<performance::MoveConstructorInitCheck>(
+ "cert-oop11-cpp");
+ CheckFactories.registerCheck<bugprone::UnhandledSelfAssignmentCheck>(
+ "cert-oop54-cpp");
// C checkers
// DCL
diff --git a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt
index 474d9356adf..0363db7cf02 100644
--- a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangTidyCERTModule
CERTTidyModule.cpp
CommandProcessorCheck.cpp
+ DefaultOperatorNewAlignmentCheck.cpp
DontModifyStdNamespaceCheck.cpp
FloatLoopCounter.cpp
LimitedRandomnessCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
new file mode 100644
index 00000000000..48eee8e6949
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.cpp
@@ -0,0 +1,74 @@
+//===--- DefaultOperatorNewCheck.cpp - clang-tidy --------------------===//
+//
+// 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 "DefaultOperatorNewAlignmentCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace cert {
+
+AST_MATCHER(CXXNewExpr, isPlacementNew) {
+ return Node.getNumPlacementArgs() > 0;
+}
+
+void DefaultOperatorNewAlignmentCheck::registerMatchers(MatchFinder *Finder) {
+ // Check not applicable in C++17 (or newer).
+ if (getLangOpts().CPlusPlus17)
+ return;
+
+ Finder->addMatcher(cxxNewExpr(unless(isPlacementNew())).bind("new"), this);
+}
+
+void DefaultOperatorNewAlignmentCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ // Get the found 'new' expression.
+ const auto *NewExpr = Result.Nodes.getNodeAs<CXXNewExpr>("new");
+
+ QualType T = NewExpr->getAllocatedType();
+ // Dependent types do not have fixed alignment.
+ if (T->isDependentType())
+ return;
+ const TagDecl *D = T->getAsTagDecl();
+ // Alignment can not be obtained for undefined type.
+ if (!D || !D->getDefinition() || !D->isCompleteDefinition())
+ return;
+
+ ASTContext &Context = D->getASTContext();
+
+ // Check if no alignment was specified for the type.
+ if (!Context.isAlignmentRequired(T))
+ return;
+
+ // The user-specified alignment (in bits).
+ unsigned SpecifiedAlignment = D->getMaxAlignment();
+ // Double-check if no alignment was specified.
+ if (!SpecifiedAlignment)
+ return;
+ // The alignment used by default 'operator new' (in bits).
+ unsigned DefaultNewAlignment = Context.getTargetInfo().getNewAlign();
+
+ bool OverAligned = SpecifiedAlignment > DefaultNewAlignment;
+ bool HasDefaultOperatorNew =
+ !NewExpr->getOperatorNew() || NewExpr->getOperatorNew()->isImplicit();
+
+ unsigned CharWidth = Context.getTargetInfo().getCharWidth();
+ if (HasDefaultOperatorNew && OverAligned)
+ diag(NewExpr->getBeginLoc(),
+ "allocation function returns a pointer with alignment %0 but the "
+ "over-aligned type being allocated requires alignment %1")
+ << (DefaultNewAlignment / CharWidth)
+ << (SpecifiedAlignment / CharWidth);
+}
+
+} // namespace cert
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.h b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.h
new file mode 100644
index 00000000000..12729874411
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/cert/DefaultOperatorNewAlignmentCheck.h
@@ -0,0 +1,35 @@
+//===--- DefaultOperatorNewCheck.h - clang-tidy -----------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_DEFAULTOPERATORNEWALIGNMENTCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_DEFAULTOPERATORNEWALIGNMENTCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace cert {
+
+/// Checks if an object of type with extended alignment is allocated by using
+/// the default operator new.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cert-mem57-cpp.html
+class DefaultOperatorNewAlignmentCheck : public ClangTidyCheck {
+public:
+ DefaultOperatorNewAlignmentCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace cert
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_DEFAULTOPERATORNEWALIGNMENTCHECK_H
OpenPOWER on IntegriCloud