<div dir="ltr">Looks like this broke the sphinx bot: <a href="http://lab.llvm.org:8011/builders/clang-tools-sphinx-docs/builds/65757/steps/docs-clang-tools-html/logs/stdio">http://lab.llvm.org:8011/builders/clang-tools-sphinx-docs/builds/65757/steps/docs-clang-tools-html/logs/stdio</a><div><br>Can you take a look?</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Sep 8, 2020 at 9:36 AM Aaron Ballman via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
Author: Frank Derry Wanye<br>
Date: 2020-09-08T09:35:14-04:00<br>
New Revision: 156b127945a8c923d141e608b7380427da024376<br>
<br>
URL: <a href="https://github.com/llvm/llvm-project/commit/156b127945a8c923d141e608b7380427da024376" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/156b127945a8c923d141e608b7380427da024376</a><br>
DIFF: <a href="https://github.com/llvm/llvm-project/commit/156b127945a8c923d141e608b7380427da024376.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/156b127945a8c923d141e608b7380427da024376.diff</a><br>
<br>
LOG: Add a new altera check for structure packing and alignment.<br>
<br>
The altera struct pack align lint check finds structs that are inefficiently<br>
packed or aligned and recommends packing/aligning of the structs using the<br>
packed and aligned attributes as needed in a warning.<br>
<br>
Added: <br>
    clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp<br>
    clang-tools-extra/clang-tidy/altera/CMakeLists.txt<br>
    clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp<br>
    clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.h<br>
    clang-tools-extra/docs/clang-tidy/checks/altera-struct-pack-align.rst<br>
    clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp<br>
<br>
Modified: <br>
    clang-tools-extra/clang-tidy/CMakeLists.txt<br>
    clang-tools-extra/clang-tidy/ClangTidyForceLinker.h<br>
    clang-tools-extra/docs/ReleaseNotes.rst<br>
    clang-tools-extra/docs/clang-tidy/checks/list.rst<br>
    clang-tools-extra/docs/clang-tidy/index.rst<br>
<br>
Removed: <br>
<br>
<br>
<br>
################################################################################<br>
diff  --git a/clang-tools-extra/clang-tidy/CMakeLists.txt b/clang-tools-extra/clang-tidy/CMakeLists.txt<br>
index 02573534ccae..923976197ebe 100644<br>
--- a/clang-tools-extra/clang-tidy/CMakeLists.txt<br>
+++ b/clang-tools-extra/clang-tidy/CMakeLists.txt<br>
@@ -46,6 +46,7 @@ endif()<br>
 # If you add a check, also add it to ClangTidyForceLinker.h in this directory.<br>
 add_subdirectory(android)<br>
 add_subdirectory(abseil)<br>
+add_subdirectory(altera)<br>
 add_subdirectory(boost)<br>
 add_subdirectory(bugprone)<br>
 add_subdirectory(cert)<br>
@@ -71,6 +72,7 @@ add_subdirectory(zircon)<br>
 set(ALL_CLANG_TIDY_CHECKS<br>
   clangTidyAndroidModule<br>
   clangTidyAbseilModule<br>
+  clangTidyAlteraModule<br>
   clangTidyBoostModule<br>
   clangTidyBugproneModule<br>
   clangTidyCERTModule<br>
<br>
diff  --git a/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h b/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h<br>
index 1d6bd2a4fd62..63e681f878db 100644<br>
--- a/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h<br>
+++ b/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h<br>
@@ -20,6 +20,11 @@ extern volatile int AbseilModuleAnchorSource;<br>
 static int LLVM_ATTRIBUTE_UNUSED AbseilModuleAnchorDestination =<br>
     AbseilModuleAnchorSource;<br>
<br>
+// This anchor is used to force the linker to link the AlteraModule.<br>
+extern volatile int AlteraModuleAnchorSource;<br>
+static int LLVM_ATTRIBUTE_UNUSED AlteraModuleAnchorDestination =<br>
+    AlteraModuleAnchorSource;<br>
+<br>
 // This anchor is used to force the linker to link the AndroidModule.<br>
 extern volatile int AndroidModuleAnchorSource;<br>
 static int LLVM_ATTRIBUTE_UNUSED AndroidModuleAnchorDestination =<br>
<br>
diff  --git a/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp b/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp<br>
new file mode 100644<br>
index 000000000000..d91f67ac1485<br>
--- /dev/null<br>
+++ b/clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp<br>
@@ -0,0 +1,39 @@<br>
+//===--- AlteraTidyModule.cpp - clang-tidy --------------------------------===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "../ClangTidy.h"<br>
+#include "../ClangTidyModule.h"<br>
+#include "../ClangTidyModuleRegistry.h"<br>
+#include "StructPackAlignCheck.h"<br>
+<br>
+using namespace clang::ast_matchers;<br>
+<br>
+namespace clang {<br>
+namespace tidy {<br>
+namespace altera {<br>
+<br>
+class AlteraModule : public ClangTidyModule {<br>
+public:<br>
+  void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {<br>
+    CheckFactories.registerCheck<StructPackAlignCheck>(<br>
+        "altera-struct-pack-align");<br>
+  }<br>
+};<br>
+<br>
+} // namespace altera<br>
+<br>
+// Register the AlteraTidyModule using this statically initialized variable.<br>
+static ClangTidyModuleRegistry::Add<altera::AlteraModule><br>
+    X("altera-module", "Adds Altera FPGA OpenCL lint checks.");<br>
+<br>
+// This anchor is used to force the linker to link in the generated object file<br>
+// and thus register the AlteraModule.<br>
+volatile int AlteraModuleAnchorSource = 0;<br>
+<br>
+} // namespace tidy<br>
+} // namespace clang<br>
<br>
diff  --git a/clang-tools-extra/clang-tidy/altera/CMakeLists.txt b/clang-tools-extra/clang-tidy/altera/CMakeLists.txt<br>
new file mode 100644<br>
index 000000000000..45131c1809a2<br>
--- /dev/null<br>
+++ b/clang-tools-extra/clang-tidy/altera/CMakeLists.txt<br>
@@ -0,0 +1,15 @@<br>
+set(LLVM_LINK_COMPONENTS support)<br>
+<br>
+add_clang_library(clangTidyAlteraModule<br>
+  AlteraTidyModule.cpp<br>
+  StructPackAlignCheck.cpp<br>
+<br>
+  LINK_LIBS<br>
+  clangAnalysis<br>
+  clangAST<br>
+  clangASTMatchers<br>
+  clangBasic<br>
+  clangLex<br>
+  clangTidy<br>
+  clangTidyUtils<br>
+  )<br>
<br>
diff  --git a/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp b/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp<br>
new file mode 100644<br>
index 000000000000..9f28a22a9d03<br>
--- /dev/null<br>
+++ b/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp<br>
@@ -0,0 +1,144 @@<br>
+//===--- StructPackAlignCheck.cpp - clang-tidy ----------------------------===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "StructPackAlignCheck.h"<br>
+#include "clang/AST/ASTContext.h"<br>
+#include "clang/AST/RecordLayout.h"<br>
+#include "clang/ASTMatchers/ASTMatchFinder.h"<br>
+#include <math.h><br>
+#include <sstream><br>
+<br>
+using namespace clang::ast_matchers;<br>
+<br>
+namespace clang {<br>
+namespace tidy {<br>
+namespace altera {<br>
+<br>
+void StructPackAlignCheck::registerMatchers(MatchFinder *Finder) {<br>
+  Finder->addMatcher(recordDecl(isStruct(), isDefinition(),<br>
+                                unless(isExpansionInSystemHeader()))<br>
+                         .bind("struct"),<br>
+                     this);<br>
+}<br>
+<br>
+CharUnits<br>
+StructPackAlignCheck::computeRecommendedAlignment(CharUnits MinByteSize) {<br>
+  CharUnits NewAlign = CharUnits::fromQuantity(1);<br>
+  if (!MinByteSize.isPowerOfTwo()) {<br>
+    int MSB = (int)MinByteSize.getQuantity();<br>
+    for (; MSB > 0; MSB /= 2) {<br>
+      NewAlign = NewAlign.alignTo(<br>
+          CharUnits::fromQuantity(((int)NewAlign.getQuantity()) * 2));<br>
+      // Abort if the computed alignment meets the maximum configured alignment.<br>
+      if (NewAlign.getQuantity() >= MaxConfiguredAlignment)<br>
+        break;<br>
+    }<br>
+  } else {<br>
+    NewAlign = MinByteSize;<br>
+  }<br>
+  return NewAlign;<br>
+}<br>
+<br>
+void StructPackAlignCheck::check(const MatchFinder::MatchResult &Result) {<br>
+  const auto *Struct = Result.Nodes.getNodeAs<RecordDecl>("struct");<br>
+<br>
+  // Do not trigger on templated struct declarations because the packing and<br>
+  // alignment requirements are unknown.<br>
+  if (Struct->isTemplated())<br>
+     return;<br>
+<br>
+  // Get sizing info for the struct.<br>
+  llvm::SmallVector<std::pair<unsigned int, unsigned int>, 10> FieldSizes;<br>
+  unsigned int TotalBitSize = 0;<br>
+  for (const FieldDecl *StructField : Struct->fields()) {<br>
+    // For each StructField, record how big it is (in bits).<br>
+    // Would be good to use a pair of <offset, size> to advise a better<br>
+    // packing order.<br>
+    unsigned int StructFieldWidth =<br>
+        (unsigned int)Result.Context<br>
+            ->getTypeInfo(StructField->getType().getTypePtr())<br>
+            .Width;<br>
+    FieldSizes.emplace_back(StructFieldWidth, StructField->getFieldIndex());<br>
+    // FIXME: Recommend a reorganization of the struct (sort by StructField<br>
+    // size, largest to smallest).<br>
+    TotalBitSize += StructFieldWidth;<br>
+  }<br>
+<br>
+  uint64_t CharSize = Result.Context->getCharWidth();<br>
+  CharUnits CurrSize = Result.Context->getASTRecordLayout(Struct).getSize();<br>
+  CharUnits MinByteSize =<br>
+      CharUnits::fromQuantity(ceil((float)TotalBitSize / CharSize));<br>
+  CharUnits MaxAlign = CharUnits::fromQuantity(<br>
+      ceil((float)Struct->getMaxAlignment() / CharSize));<br>
+  CharUnits CurrAlign =<br>
+      Result.Context->getASTRecordLayout(Struct).getAlignment();<br>
+  CharUnits NewAlign = computeRecommendedAlignment(MinByteSize);<br>
+<br>
+  bool IsPacked = Struct->hasAttr<PackedAttr>();<br>
+  bool NeedsPacking = (MinByteSize < CurrSize) && (MaxAlign != NewAlign) &&<br>
+                      (CurrSize != NewAlign);<br>
+  bool NeedsAlignment = CurrAlign.getQuantity() != NewAlign.getQuantity();<br>
+<br>
+  if (!NeedsAlignment && !NeedsPacking)<br>
+    return;<br>
+<br>
+  // If it's using much more space than it needs, suggest packing.<br>
+  // (Do not suggest packing if it is currently explicitly aligned to what the<br>
+  // minimum byte size would suggest as the new alignment.)<br>
+  if (NeedsPacking && !IsPacked) {<br>
+    diag(Struct->getLocation(),<br>
+         "accessing fields in struct %0 is inefficient due to padding; only "<br>
+         "needs %1 bytes but is using %2 bytes")<br>
+        << Struct << (int)MinByteSize.getQuantity()<br>
+        << (int)CurrSize.getQuantity()<br>
+        << FixItHint::CreateInsertion(Struct->getEndLoc().getLocWithOffset(1),<br>
+                                      " __attribute__((packed))");<br>
+    diag(Struct->getLocation(),<br>
+         "use \"__attribute__((packed))\" to reduce the amount of padding "<br>
+         "applied to struct %0",<br>
+         DiagnosticIDs::Note)<br>
+        << Struct;<br>
+  }<br>
+<br>
+  FixItHint FixIt;<br>
+  AlignedAttr *Attribute = Struct->getAttr<AlignedAttr>();<br>
+  std::string NewAlignQuantity = std::to_string((int)NewAlign.getQuantity());<br>
+  if (Attribute) {<br>
+    std::ostringstream FixItString;<br>
+    FixItString << "aligned(" << NewAlignQuantity << ")";<br>
+    FixIt =<br>
+        FixItHint::CreateReplacement(Attribute->getRange(), FixItString.str());<br>
+  } else {<br>
+    std::ostringstream FixItString;<br>
+    FixItString << " __attribute__((aligned(" << NewAlignQuantity << ")))";<br>
+    FixIt = FixItHint::CreateInsertion(Struct->getEndLoc().getLocWithOffset(1),<br>
+                                       FixItString.str());<br>
+  }<br>
+<br>
+  // And suggest the minimum power-of-two alignment for the struct as a whole<br>
+  // (with and without packing).<br>
+  if (NeedsAlignment) {<br>
+    diag(Struct->getLocation(),<br>
+         "accessing fields in struct %0 is inefficient due to poor alignment; "<br>
+         "currently aligned to %1 bytes, but recommended alignment is %2 bytes")<br>
+        << Struct << (int)CurrAlign.getQuantity() << NewAlignQuantity << FixIt;<br>
+<br>
+    diag(Struct->getLocation(),<br>
+         "use \"__attribute__((aligned(%0)))\" to align struct %1 to %0 bytes",<br>
+         DiagnosticIDs::Note)<br>
+        << NewAlignQuantity << Struct;<br>
+  }<br>
+}<br>
+<br>
+void StructPackAlignCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {<br>
+  Options.store(Opts, "MaxConfiguredAlignment", MaxConfiguredAlignment);<br>
+}<br>
+<br>
+} // namespace altera<br>
+} // namespace tidy<br>
+} // namespace clang<br>
<br>
diff  --git a/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.h b/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.h<br>
new file mode 100644<br>
index 000000000000..b903641247e3<br>
--- /dev/null<br>
+++ b/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.h<br>
@@ -0,0 +1,41 @@<br>
+//===--- StructPackAlignCheck.h - clang-tidy --------------------*- C++ -*-===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_STRUCTPACKALIGNCHECK_H<br>
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_STRUCTPACKALIGNCHECK_H<br>
+<br>
+#include "../ClangTidyCheck.h"<br>
+<br>
+namespace clang {<br>
+namespace tidy {<br>
+namespace altera {<br>
+<br>
+/// Finds structs that are inefficiently packed or aligned, and recommends<br>
+/// packing and/or aligning of said structs as needed.<br>
+///<br>
+/// For the user-facing documentation see:<br>
+/// <a href="http://clang.llvm.org/extra/clang-tidy/checks/altera-struct-pack-align.html" rel="noreferrer" target="_blank">http://clang.llvm.org/extra/clang-tidy/checks/altera-struct-pack-align.html</a><br>
+class StructPackAlignCheck : public ClangTidyCheck {<br>
+public:<br>
+  StructPackAlignCheck(StringRef Name, ClangTidyContext *Context)<br>
+      : ClangTidyCheck(Name, Context),<br>
+    MaxConfiguredAlignment(Options.get("MaxConfiguredAlignment", 128)) {}<br>
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;<br>
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;<br>
+  void storeOptions(ClangTidyOptions::OptionMap &Opts);<br>
+<br>
+private:<br>
+  const unsigned MaxConfiguredAlignment;<br>
+  CharUnits computeRecommendedAlignment(CharUnits MinByteSize);<br>
+};<br>
+<br>
+} // namespace altera<br>
+} // namespace tidy<br>
+} // namespace clang<br>
+<br>
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_STRUCTPACKALIGNCHECK_H<br>
<br>
diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst<br>
index 781fef27c476..53c3894914e5 100644<br>
--- a/clang-tools-extra/docs/ReleaseNotes.rst<br>
+++ b/clang-tools-extra/docs/ReleaseNotes.rst<br>
@@ -67,6 +67,27 @@ The improvements are...<br>
 Improvements to clang-tidy<br>
 --------------------------<br>
<br>
+New modules<br>
+^^^^^^^^^^^<br>
+<br>
+- New :doc:`altera <clang-tidy/modules/altera>` module.<br>
+<br>
+  Includes checks related to OpenCL for FPGA coding guidelines, based on the<br>
+  `Altera SDK for OpenCL: Best Practices Guide<br>
+  <<a href="https://www.altera.com/en_US/pdfs/literature/hb/opencl-sdk/aocl_optimization_guide.pdf" rel="noreferrer" target="_blank">https://www.altera.com/en_US/pdfs/literature/hb/opencl-sdk/aocl_optimization_guide.pdf</a>>`_.<br>
+<br>
+New checks<br>
+^^^^^^^^^^<br>
+<br>
+- New :doc:`altera-struct-pack-align<br>
+  <clang-tidy/checks/altera-struct-pack-align>` check.<br>
+<br>
+  Finds structs that are inefficiently packed or aligned, and recommends<br>
+  packing and/or aligning of said structs as needed.<br>
+<br>
+- New :doc:`bugprone-misplaced-pointer-arithmetic-in-alloc<br>
+  <clang-tidy/checks/bugprone-misplaced-pointer-arithmetic-in-alloc>` check.<br>
+<br>
 - New :doc:`bugprone-redundant-branch-condition<br>
   <clang-tidy/checks/bugprone-redundant-branch-condition>` check.<br>
<br>
<br>
diff  --git a/clang-tools-extra/docs/clang-tidy/checks/altera-struct-pack-align.rst b/clang-tools-extra/docs/clang-tidy/checks/altera-struct-pack-align.rst<br>
new file mode 100644<br>
index 000000000000..b03a4fcf7fcf<br>
--- /dev/null<br>
+++ b/clang-tools-extra/docs/clang-tidy/checks/altera-struct-pack-align.rst<br>
@@ -0,0 +1,54 @@<br>
+.. title:: clang-tidy - altera-struct-pack-align<br>
+<br>
+altera-struct-pack-align<br>
+========================<br>
+<br>
+Finds structs that are inefficiently packed or aligned, and recommends<br>
+packing and/or aligning of said structs as needed.<br>
+<br>
+Structs that are not packed take up more space than they should, and accessing<br>
+structs that are not well aligned is inefficient.<br>
+<br>
+Fix-its are provided to fix both of these issues by inserting and/or amending<br>
+relevant struct attributes.<br>
+<br>
+Based on the `Altera SDK for OpenCL: Best Practices Guide<br>
+<<a href="https://www.altera.com/en_US/pdfs/literature/hb/opencl-sdk/aocl_optimization_guide.pdf" rel="noreferrer" target="_blank">https://www.altera.com/en_US/pdfs/literature/hb/opencl-sdk/aocl_optimization_guide.pdf</a>>`_.<br>
+<br>
+.. code-block:: c++<br>
+<br>
+  // The following struct is originally aligned to 4 bytes, and thus takes up<br>
+  // 12 bytes of memory instead of 10. Packing the struct will make it use<br>
+  // only 10 bytes of memory, and aligning it to 16 bytes will make it<br>
+  // efficient to access.<br>
+  struct example {<br>
+    char a;    // 1 byte<br>
+    double b;  // 8 bytes<br>
+    char c;    // 1 byte<br>
+  };<br>
+<br>
+  // The following struct is arranged in such a way that packing is not needed.<br>
+  // However, it is aligned to 4 bytes instead of 8, and thus needs to be<br>
+  // explicitly aligned.<br>
+  struct implicitly_packed_example {<br>
+    char a;  // 1 byte<br>
+    char b;  // 1 byte<br>
+    char c;  // 1 byte<br>
+    char d;  // 1 byte<br>
+    int e;   // 4 bytes<br>
+  };<br>
+<br>
+  // The following struct is explicitly aligned and packed.<br>
+  struct good_example {<br>
+    char a;    // 1 byte<br>
+    double b;  // 8 bytes<br>
+    char c;    // 1 byte<br>
+  } __attribute__((packed)) __attribute__((aligned(16));<br>
+<br>
+  // Explicitly aligning a struct to the wrong value will result in a warning.<br>
+  // The following example should be aligned to 16 bytes, not 32.<br>
+  struct badly_aligned_example {<br>
+    char a;    // 1 byte<br>
+    double b;  // 8 bytes<br>
+    char c;    // 1 byte<br>
+  } __attribute__((packed)) __attribute__((aligned(32)));<br>
<br>
diff  --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst<br>
index 91414ee8c90f..c569ce704d97 100644<br>
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst<br>
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst<br>
@@ -30,6 +30,7 @@ Clang-Tidy Checks<br>
    `abseil-time-comparison <abseil-time-comparison.html>`_, "Yes"<br>
    `abseil-time-subtraction <abseil-time-subtraction.html>`_, "Yes"<br>
    `abseil-upgrade-duration-conversions <abseil-upgrade-duration-conversions.html>`_, "Yes"<br>
+   `altera-struct-pack-align <altera-struct-pack-align.html>`_,<br>
    `android-cloexec-accept <android-cloexec-accept.html>`_, "Yes"<br>
    `android-cloexec-accept4 <android-cloexec-accept4.html>`_,<br>
    `android-cloexec-creat <android-cloexec-creat.html>`_, "Yes"<br>
<br>
diff  --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst<br>
index b9a4a7d694b4..a85c72154178 100644<br>
--- a/clang-tools-extra/docs/clang-tidy/index.rst<br>
+++ b/clang-tools-extra/docs/clang-tidy/index.rst<br>
@@ -58,6 +58,7 @@ There are currently the following groups of checks:<br>
 Name prefix            Description<br>
 ====================== =========================================================<br>
 ``abseil-``            Checks related to Abseil library.<br>
+``altera-``            Checks related to OpenCL programming for FPGAs.<br>
 ``android-``           Checks related to Android.<br>
 ``boost-``             Checks related to Boost library.<br>
 ``bugprone-``          Checks that target bugprone code constructs.<br>
<br>
diff  --git a/clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp b/clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp<br>
new file mode 100644<br>
index 000000000000..615b6cafe87a<br>
--- /dev/null<br>
+++ b/clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp<br>
@@ -0,0 +1,101 @@<br>
+// RUN: %check_clang_tidy %s altera-struct-pack-align %t -- -header-filter=.*<br>
+<br>
+// Struct needs both alignment and packing<br>
+struct error {<br>
+  char a;<br>
+  double b;<br>
+  char c;<br>
+};<br>
+// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'error' is inefficient due to padding; only needs 10 bytes but is using 24 bytes [altera-struct-pack-align]<br>
+// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((packed))" to reduce the amount of padding applied to struct 'error'<br>
+// CHECK-MESSAGES: :[[@LINE-7]]:8: warning: accessing fields in struct 'error' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]<br>
+// CHECK-MESSAGES: :[[@LINE-8]]:8: note: use "__attribute__((aligned(16)))" to align struct 'error' to 16 bytes<br>
+// CHECK-FIXES: __attribute__((packed))<br>
+// CHECK-FIXES: __attribute__((aligned(16)));<br>
+<br>
+// Struct is explicitly packed, but needs alignment<br>
+struct error_packed {<br>
+  char a;<br>
+  double b;<br>
+  char c;<br>
+} __attribute__((packed));<br>
+// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'error_packed' is inefficient due to poor alignment; currently aligned to 1 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]<br>
+// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'error_packed' to 16 bytes<br>
+// CHECK-FIXES: __attribute__((aligned(16)))<br>
+<br>
+// Struct is properly packed, but needs alignment<br>
+struct align_only {<br>
+  char a;<br>
+  char b;<br>
+  char c;<br>
+  char d;<br>
+  int e;<br>
+  double f;<br>
+};<br>
+// CHECK-MESSAGES: :[[@LINE-8]]:8: warning: accessing fields in struct 'align_only' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]<br>
+// CHECK-MESSAGES: :[[@LINE-9]]:8: note: use "__attribute__((aligned(16)))" to align struct 'align_only' to 16 bytes<br>
+// CHECK-FIXES: __attribute__((aligned(16)));<br>
+<br>
+// Struct is perfectly packed but wrongly aligned<br>
+struct bad_align {<br>
+  char a;<br>
+  double b;<br>
+  char c;<br>
+} __attribute__((packed)) __attribute__((aligned(8)));<br>
+// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]<br>
+// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align' to 16 bytes<br>
+// CHECK-FIXES: __attribute__((aligned(16)));<br>
+<br>
+struct bad_align2 {<br>
+  char a;<br>
+  double b;<br>
+  char c;<br>
+} __attribute__((packed)) __attribute__((aligned(32)));<br>
+// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align2' is inefficient due to poor alignment; currently aligned to 32 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]<br>
+// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align2' to 16 bytes<br>
+// CHECK-FIXES: __attribute__((aligned(16)));<br>
+<br>
+struct bad_align3 {<br>
+  char a;<br>
+  double b;<br>
+  char c;<br>
+} __attribute__((packed)) __attribute__((aligned(4)));<br>
+// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 'bad_align3' is inefficient due to poor alignment; currently aligned to 4 bytes, but recommended alignment is 16 bytes [altera-struct-pack-align]<br>
+// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((aligned(16)))" to align struct 'bad_align3' to 16 bytes<br>
+// CHECK-FIXES: __attribute__((aligned(16)));<br>
+<br>
+// Struct is both perfectly packed and aligned<br>
+struct success {<br>
+  char a;<br>
+  double b;<br>
+  char c;<br>
+} __attribute__((packed)) __attribute__((aligned(16)));<br>
+//Should take 10 bytes and be aligned to 16 bytes<br>
+<br>
+// Struct is properly packed, and explicitly aligned<br>
+struct success2 {<br>
+  int a;<br>
+  int b;<br>
+  int c;<br>
+} __attribute__((aligned(16)));<br>
+<br>
+// If struct is properly aligned, packing not needed<br>
+struct success3 {<br>
+  char a;<br>
+  double b;<br>
+  char c;<br>
+} __attribute__((aligned(16)));<br>
+<br>
+// If struct is templated, warnings should not be triggered<br>
+template <typename A, typename B><br>
+struct success4 {<br>
+  A a;<br>
+  B b;<br>
+  int c;<br>
+};<br>
+<br>
+// Warnings should not trigger on struct instantiations<br>
+void no_trigger_on_instantiation() {<br>
+  struct bad_align3 instantiated { 'a', 0.001, 'b' };<br>
+}<br>
+<br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>