DennisL updated this revision to Diff 193715.
DennisL marked an inline comment as done.
DennisL retitled this revision from "[clang-tidy] Add
misc-placement-new-target-size check" to "[clang-tidy] Add
misc-placement-new-target-type-mismatch check".
DennisL edited the summary of this revision.
DennisL added a comment.
Addressed reviewer feedback and also simplified the implementation, renamed the
test to be more concise, and added more test cases.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D60139/new/
https://reviews.llvm.org/D60139
Files:
clang-tidy/misc/CMakeLists.txt
clang-tidy/misc/MiscTidyModule.cpp
clang-tidy/misc/PlacementNewTargetTypeMismatch.cpp
clang-tidy/misc/PlacementNewTargetTypeMismatch.h
docs/ReleaseNotes.rst
docs/clang-tidy/checks/list.rst
docs/clang-tidy/checks/misc-placement-new-target-type-mismatch.rst
test/clang-tidy/misc-placement-new-target-type-mismatch.cpp
Index: test/clang-tidy/misc-placement-new-target-type-mismatch.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/misc-placement-new-target-type-mismatch.cpp
@@ -0,0 +1,82 @@
+// RUN: %check_clang_tidy %s misc-placement-new-target-type-mismatch %t
+
+// definitions
+
+using size_type = unsigned long;
+void *operator new(size_type, void *);
+void *operator new[](size_type, void *);
+
+namespace std {
+template<class T> T* addressof(T& arg) noexcept;
+} // namespace std
+
+struct Foo {
+ int a;
+ int b;
+ int c;
+ int d;
+};
+
+template<typename T>
+T& getT() {
+ static T f;
+ return f;
+}
+
+// instances emitting warnings
+
+void f1() {
+ struct Dummy {
+ int a;
+ int b;
+ };
+ int *ptr = new int;
+ new (ptr) Dummy;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: placement new of incompatible types [misc-placement-new-target-type-mismatch]
+ delete ptr;
+}
+
+void f2() {
+ int * ptr = new int;
+ new (ptr) Foo;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: placement new of incompatible types [misc-placement-new-target-type-mismatch]
+ delete ptr;
+}
+
+void f3() {
+ char *ptr = new char[17*sizeof(char)];
+ new(ptr) float[13];
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: placement new of incompatible types [misc-placement-new-target-type-mismatch]
+ delete[] ptr;
+}
+
+void f4() {
+ new (std::addressof(getT<int>())) Foo;
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: placement new of incompatible types [misc-placement-new-target-type-mismatch]
+}
+
+void f5() {
+ char *ptr = new char[17*sizeof(char)];
+ new(ptr) float{13.f};
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: placement new of incompatible types [misc-placement-new-target-type-mismatch]
+ delete[] ptr;
+}
+
+// instances not emitting a warning
+
+void f6() {
+ Foo * ptr = new Foo;
+ new (ptr) Foo;
+ delete ptr;
+}
+
+void f7() {
+ new ((void *)std::addressof(getT<Foo>())) Foo;
+}
+
+void f8() {
+ char *ptr = new char[17*sizeof(char)];
+ new((float *)ptr) float{13.f};
+
+ delete[] ptr;
+}
\ No newline at end of file
Index: docs/clang-tidy/checks/misc-placement-new-target-type-mismatch.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/misc-placement-new-target-type-mismatch.rst
@@ -0,0 +1,8 @@
+.. title:: clang-tidy - misc-placement-new-target-type-mismatch
+
+misc-placement-new-target-type-mismatch
+=======================================
+
+Finds placement-new calls where the pointer type of the adress mismatches the
+type of the created value.
+
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -184,6 +184,7 @@
misc-new-delete-overloads
misc-non-copyable-objects
misc-non-private-member-variables-in-classes
+ misc-placement-new-target-type-mismatch
misc-redundant-expression
misc-static-assert
misc-throw-by-value-catch-by-reference
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -130,6 +130,13 @@
<clang-tidy/checks/modernize-use-override>` now supports `OverrideSpelling`
and `FinalSpelling` options.
+- New :doc:`misc-placement-new-target-type-mismatch
+ <clang-tidy/checks/misc-placement-new-target-type-mismatch>` check.
+
+ Finds placement-new calls where the size of the pointee type of the placement
+ parameter is smaller than the size of the constructed type and the pointer is
+ implicitly cast to ``void *``.
+
- New :doc:`openmp-exception-escape
<clang-tidy/checks/openmp-exception-escape>` check.
Index: clang-tidy/misc/PlacementNewTargetTypeMismatch.h
===================================================================
--- /dev/null
+++ clang-tidy/misc/PlacementNewTargetTypeMismatch.h
@@ -0,0 +1,36 @@
+//===--- PlacementNewTargetTypeMismatch.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_MISC_PLACEMENTNEWTARGETTYPEMISMATCHCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_PLACEMENTNEWTARGETTYPEMISMATCHCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// Finds placement-new calls where the pointer type of the adress mismatches
+/// the type of the created value.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-placement-new-target-type-mismatch.html
+class PlacementNewTargetTypeMismatch : public ClangTidyCheck {
+public:
+ PlacementNewTargetTypeMismatch(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_PLACEMENTNEWTARGETTYPEMISMATCHCHECK_H
Index: clang-tidy/misc/PlacementNewTargetTypeMismatch.cpp
===================================================================
--- /dev/null
+++ clang-tidy/misc/PlacementNewTargetTypeMismatch.cpp
@@ -0,0 +1,61 @@
+//===--- PlacementNewTargetTypeMismatch.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 "PlacementNewTargetTypeMismatch.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+void PlacementNewTargetTypeMismatch::registerMatchers(MatchFinder *Finder) {
+ // We only want the records that call 'new' with an adress parameter
+ Finder->addMatcher(
+ cxxNewExpr(hasDescendant(implicitCastExpr().bind("Cast"))).bind("Alloc"),
+ this);
+}
+
+void PlacementNewTargetTypeMismatch::check(
+ const MatchFinder::MatchResult &Result) {
+ const auto *Alloc = Result.Nodes.getNodeAs<CXXNewExpr>("Alloc");
+ assert(Alloc && "Matched node bound by 'Alloc' shoud be a 'CXXNewExpr'");
+
+ unsigned numPlacementArgs = Alloc->getNumPlacementArgs();
+ if (0 == numPlacementArgs) {
+ return;
+ }
+
+ const Type *SourceType =
+ Alloc->getAllocatedType()->getUnqualifiedDesugaredType();
+ const ImplicitCastExpr *Cast =
+ Result.Nodes.getNodeAs<ImplicitCastExpr>("Cast");
+
+ const QualType &CastType = Cast->getSubExpr()->getType();
+ const Type *TargetType =
+ CastType->isPointerType()
+ ? CastType->getPointeeType()->getUnqualifiedDesugaredType()
+ : CastType->getUnqualifiedDesugaredType();
+
+ if (!SourceType || !TargetType) {
+ // shall never happen
+ return;
+ }
+
+ if (SourceType != TargetType) {
+ diag(Alloc->getExprLoc(), "placement new of incompatible types");
+ }
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/misc/MiscTidyModule.cpp
===================================================================
--- clang-tidy/misc/MiscTidyModule.cpp
+++ clang-tidy/misc/MiscTidyModule.cpp
@@ -14,6 +14,7 @@
#include "NewDeleteOverloadsCheck.h"
#include "NonCopyableObjects.h"
#include "NonPrivateMemberVariablesInClassesCheck.h"
+#include "PlacementNewTargetTypeMismatch.h"
#include "RedundantExpressionCheck.h"
#include "StaticAssertCheck.h"
#include "ThrowByValueCatchByReferenceCheck.h"
@@ -39,6 +40,8 @@
"misc-non-copyable-objects");
CheckFactories.registerCheck<NonPrivateMemberVariablesInClassesCheck>(
"misc-non-private-member-variables-in-classes");
+ CheckFactories.registerCheck<PlacementNewTargetTypeMismatch>(
+ "misc-placement-new-target-type-mismatch");
CheckFactories.registerCheck<RedundantExpressionCheck>(
"misc-redundant-expression");
CheckFactories.registerCheck<StaticAssertCheck>("misc-static-assert");
Index: clang-tidy/misc/CMakeLists.txt
===================================================================
--- clang-tidy/misc/CMakeLists.txt
+++ clang-tidy/misc/CMakeLists.txt
@@ -7,6 +7,7 @@
NewDeleteOverloadsCheck.cpp
NonCopyableObjects.cpp
NonPrivateMemberVariablesInClassesCheck.cpp
+ PlacementNewTargetTypeMismatch.cpp
RedundantExpressionCheck.cpp
StaticAssertCheck.cpp
ThrowByValueCatchByReferenceCheck.cpp
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits