NorenaLeonetti updated this revision to Diff 113654.
NorenaLeonetti added a comment.
Herald added a subscriber: JDevlieghere.
Added a test for C++ style cast and modified the docs.
Repository:
rL LLVM
https://reviews.llvm.org/D33826
Files:
clang-tidy/cert/AvoidPointerCastToMoreStrictAlignmentCheck.cpp
clang-tidy/cert/AvoidPointerCastToMoreStrictAlignmentCheck.h
clang-tidy/cert/CERTTidyModule.cpp
clang-tidy/cert/CMakeLists.txt
docs/ReleaseNotes.rst
docs/clang-tidy/checks/cert-exp36-c.rst
docs/clang-tidy/checks/list.rst
test/clang-tidy/cert-avoid-pointer-cast-to-more-strict-alignment.c
test/clang-tidy/cert-avoid-pointer-cast-to-more-strict-alignment.cpp
Index: test/clang-tidy/cert-avoid-pointer-cast-to-more-strict-alignment.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/cert-avoid-pointer-cast-to-more-strict-alignment.cpp
@@ -0,0 +1,7 @@
+// RUN: %check_clang_tidy %s cert-exp36-c %t
+
+void function(void) {
+ char c = 'x';
+ int *ip = reinterpret_cast<int *>(&c);
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not cast pointers into more strictly aligned pointer types [cert-exp36-c]
+}
Index: test/clang-tidy/cert-avoid-pointer-cast-to-more-strict-alignment.c
===================================================================
--- /dev/null
+++ test/clang-tidy/cert-avoid-pointer-cast-to-more-strict-alignment.c
@@ -0,0 +1,45 @@
+// RUN: %check_clang_tidy %s cert-exp36-c %t -- -- -std=c11
+
+void function(void) {
+ char c = 'x';
+ int *ip = (int *)&c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not cast pointers into more strictly aligned pointer types [cert-exp36-c]
+}
+
+struct foo_header {
+ int len;
+};
+
+void function2(char *data, unsigned offset) {
+ struct foo_header *tmp;
+ struct foo_header header;
+
+ tmp = (struct foo_header *)(data + offset);
+ // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not cast pointers into more strictly aligned pointer types [cert-exp36-c]
+}
+
+
+// Something that does not trigger the check:
+
+struct w;
+
+void function3(struct w *v) {
+ int *ip = (int *)v;
+ struct w *u = (struct w *)ip;
+}
+
+struct x {
+ _Alignas(int) char c;
+};
+
+void function4(void) {
+ struct x c = {'x'};
+ int *ip = (int *)&c;
+}
+
+// FIXME: we do not want a warning for this
+void function5(void) {
+ _Alignas(int) char c = 'x';
+ int *ip = (int *)&c;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not cast pointers into more strictly aligned pointer types [cert-exp36-c]
+}
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -20,6 +20,7 @@
bugprone-integer-division
bugprone-suspicious-memset-usage
bugprone-undefined-memory-manipulation
+ cert-exp36-c
cert-dcl03-c (redirects to misc-static-assert) <cert-dcl03-c>
cert-dcl21-cpp
cert-dcl50-cpp
Index: docs/clang-tidy/checks/cert-exp36-c.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/cert-exp36-c.rst
@@ -0,0 +1,45 @@
+.. title:: clang-tidy - cert-exp36-c
+
+cert-exp36-c
+============
+
+This check will give a warning if a pointer value is converted to
+a pointer type that is more strictly aligned than the referenced type.
+
+This check is the same as `-Wcast-align`, except it checks for `reinterpret_cast` as well.
+
+ Here's an example:
+
+ .. code-block:: c
+
+ char c = 'x';
+ int *ip = (int *)&c;
+ // warning: do not cast pointers into more strictly aligned pointer types
+
+ This check does not completely include warnings for types with explicitly
+ specified alignment, this remains a possible future extension.
+
+ See the example:
+
+ .. code-block:: c
+
+ // Works fine:
+ struct x {
+ _Alignas(int) char c;
+ };
+
+ void function3(void) {
+ struct x c = {'x'};
+ int *ip = (int *)&c;
+ }
+
+ // Won't work:
+ void function4(void) {
+ _Alignas(int) char c = 'x';
+ int *ip = (int *)&c;
+ // the check will give a warning for this
+ }
+
+ This check corresponds to the CERT C Coding Standard rule
+ `EXP36-C. Do not cast pointers into more strictly aligned pointer types
+<https://www.securecoding.cert.org/confluence/display/c/EXP36-C.+Do+not+cast+pointers+into+more+strictly+aligned+pointer+types>`_.
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -56,6 +56,10 @@
Improvements to clang-tidy
--------------------------
+- New `cert-exp36-c
+ <http://clang.llvm.org/extra/clang-tidy/checks/cert-exp36-c.html>`_ check
+
+ Checks if a pointer value is casted to a more stricter alignment.
- Renamed checks to use correct term "implicit conversion" instead of "implicit
cast" and modified messages and option names accordingly:
@@ -143,7 +147,7 @@
option.
- Added alias `hicpp-braces-around-statements <http://clang.llvm.org/extra/clang-tidy/checks/hicpp-braces-around-statements.html>`_
-
+
Improvements to include-fixer
-----------------------------
Index: clang-tidy/cert/CMakeLists.txt
===================================================================
--- clang-tidy/cert/CMakeLists.txt
+++ clang-tidy/cert/CMakeLists.txt
@@ -1,6 +1,7 @@
set(LLVM_LINK_COMPONENTS support)
add_clang_library(clangTidyCERTModule
+ AvoidPointerCastToMoreStrictAlignmentCheck.cpp
CERTTidyModule.cpp
CommandProcessorCheck.cpp
DontModifyStdNamespaceCheck.cpp
Index: clang-tidy/cert/CERTTidyModule.cpp
===================================================================
--- clang-tidy/cert/CERTTidyModule.cpp
+++ clang-tidy/cert/CERTTidyModule.cpp
@@ -16,6 +16,7 @@
#include "../misc/NonCopyableObjects.h"
#include "../misc/StaticAssertCheck.h"
#include "../misc/ThrowByValueCatchByReferenceCheck.h"
+#include "AvoidPointerCastToMoreStrictAlignmentCheck.h"
#include "CommandProcessorCheck.h"
#include "DontModifyStdNamespaceCheck.h"
#include "FloatLoopCounter.h"
@@ -64,6 +65,9 @@
CheckFactories.registerCheck<misc::StaticAssertCheck>("cert-dcl03-c");
// ENV
CheckFactories.registerCheck<CommandProcessorCheck>("cert-env33-c");
+ // EXP
+ CheckFactories.registerCheck<AvoidPointerCastToMoreStrictAlignmentCheck>(
+ "cert-exp36-c");
// FLP
CheckFactories.registerCheck<FloatLoopCounter>("cert-flp30-c");
// FIO
Index: clang-tidy/cert/AvoidPointerCastToMoreStrictAlignmentCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/cert/AvoidPointerCastToMoreStrictAlignmentCheck.h
@@ -0,0 +1,37 @@
+//===--- AvoidPointerCastToMoreStrictAlignmentCheck.h - clang-tidy*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_AVOID_POINTER_CAST_TO_MORE_STRICT_ALIGNMENT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_AVOID_POINTER_CAST_TO_MORE_STRICT_ALIGNMENT_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace cert {
+
+/// This check will give a warning if a pointer value is
+/// converted to a pointer type that is more strictly
+/// aligned than the referenced type.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cert-exp36-c.html;;
+class AvoidPointerCastToMoreStrictAlignmentCheck : public ClangTidyCheck {
+public:
+ AvoidPointerCastToMoreStrictAlignmentCheck(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_AVOID_POINTER_CAST_TO_MORE_STRICT_ALIGNMENT_H
Index: clang-tidy/cert/AvoidPointerCastToMoreStrictAlignmentCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/cert/AvoidPointerCastToMoreStrictAlignmentCheck.cpp
@@ -0,0 +1,56 @@
+//===--- AvoidPointerCastToMoreStrictAlignmentCheck.cpp - clang-tidy-------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AvoidPointerCastToMoreStrictAlignmentCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace cert {
+
+void AvoidPointerCastToMoreStrictAlignmentCheck::registerMatchers(
+ MatchFinder *Finder) {
+ Finder->addMatcher(
+ castExpr(hasSourceExpression(expr().bind("source"))).bind("target"),
+ this);
+}
+
+void AvoidPointerCastToMoreStrictAlignmentCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ const auto *Source = Result.Nodes.getNodeAs<Expr>("source");
+ const auto *Target = Result.Nodes.getNodeAs<CastExpr>("target");
+
+ QualType SourceType = Source->getType();
+ QualType TargetType = Target->getType();
+
+ if (!SourceType->isPointerType() || !TargetType->isPointerType())
+ return;
+
+ QualType SourcePointedType = SourceType->getPointeeType();
+ QualType TargetPointedType = TargetType->getPointeeType();
+
+ if (SourcePointedType->isIncompleteType() ||
+ TargetPointedType->isIncompleteType())
+ return;
+
+ if (Result.Context->getTypeAlign(SourcePointedType) >=
+ Result.Context->getTypeAlign(TargetPointedType))
+ return;
+
+ if (Target->getCastKind() == CK_BitCast)
+ diag(Target->getLocStart(),
+ "do not cast pointers into more strictly aligned pointer types");
+}
+
+} // namespace cert
+} // namespace tidy
+} // namespace clang
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits