NorenaLeonetti updated this revision to Diff 116510.
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,122 @@
+// 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]
+}
+
+// Test from -Wcast-align check:
+
+// Simple casts.
+void test0(char *P) {
+ char *a = (char*) P;
+ short *b = (short*) P;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not cast pointers into more strictly aligned pointer types [cert-exp36-c]
+ int *c = (int*) P;
+ // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not cast pointers into more strictly aligned pointer types [cert-exp36-c]
+}
+
+// Casts from void* are a special case.
+void test1(void *P) {
+ char *a = (char*) P;
+ short *b = (short*) P;
+ int *c = (int*) P;
+
+ const volatile void *P2 = P;
+ char *d = (char*) P2;
+ short *e = (short*) P2;
+ int *f = (int*) P2;
+
+ const char *g = (const char*) P2;
+ const short *h = (const short*) P2;
+ const int *i = (const int*) P2;
+
+ const volatile char *j = (const volatile char*) P2;
+ const volatile short *k = (const volatile short*) P2;
+ const volatile int *l = (const volatile int*) P2;
+}
+
+// Aligned struct.
+struct __attribute__((aligned(16))) A {
+ char buffer[16];
+};
+void test2(char *P) {
+ struct A *a = (struct A*) P;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: do not cast pointers into more strictly aligned pointer types [cert-exp36-c]
+}
+
+// Incomplete type.
+void test3(char *P) {
+ struct B *b = (struct B*) P;
+}
+
+// Do not issue a warning. The aligned attribute changes the alignment of the
+// variables and fields.
+char __attribute__((aligned(4))) a[16];
+
+struct S0 {
+ char a[16];
+};
+
+struct S {
+ char __attribute__((aligned(4))) a[16];
+ struct S0 __attribute__((aligned(4))) s0;
+};
+
+// same FIXME as in line 120
+void test4() {
+ struct S s;
+ int *i = (int *)s.a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not cast pointers into more strictly aligned pointer types [cert-exp36-c]
+ i = (int *)&s.s0;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not cast pointers into more strictly aligned pointer types [cert-exp36-c]
+ i = (int *)a;
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not cast pointers into more strictly aligned pointer types [cert-exp36-c]
+}
+
+// No warnings.
+typedef int (*FnTy)(void);
+unsigned int func5(void);
+
+FnTy test5(void) {
+ return (FnTy)&func5;
+}
+
+
+// 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:
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,59 @@
+//===--- 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;
+
+ if (SourceType->isDependentType() || TargetType->isDependentType())
+ 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