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