[clang] c558b1f - [analyzer] Fix calculating offset for fields with an empty type

Georgy Komarov via cfe-commits cfe-commits at lists.llvm.org
Sat Jul 3 20:57:37 PDT 2021


Author: Georgy Komarov
Date: 2021-07-04T06:57:11+03:00
New Revision: c558b1fca7350f4f4d8e7387fb2ead951284a5cf

URL: https://github.com/llvm/llvm-project/commit/c558b1fca7350f4f4d8e7387fb2ead951284a5cf
DIFF: https://github.com/llvm/llvm-project/commit/c558b1fca7350f4f4d8e7387fb2ead951284a5cf.diff

LOG: [analyzer] Fix calculating offset for fields with an empty type

Fix offset calculation routines in padding checker to avoid assertion
errors described in bugzilla issue 50426. The fields that are subojbects
of zero size, marked with [[no_unique_address]] or empty bitfields will
be excluded from padding calculation routines.

Reviewed By: NoQ

Differential Revision: https://reviews.llvm.org/D104097

Added: 
    clang/test/Analysis/padding_no_unique_address.cpp

Modified: 
    clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
index 96f0d9bb3c3de..40472ccfe7e66 100644
--- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
@@ -193,6 +193,11 @@ class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
     CharUnits PaddingSum;
     CharUnits Offset = ASTContext.toCharUnitsFromBits(RL.getFieldOffset(0));
     for (const FieldDecl *FD : RD->fields()) {
+      // Skip field that is a subobject of zero size, marked with
+      // [[no_unique_address]] or an empty bitfield, because its address can be
+      // set the same as the other fields addresses.
+      if (FD->isZeroSize(ASTContext))
+        continue;
       // This checker only cares about the padded size of the
       // field, and not the data size. If the field is a record
       // with tail padding, then we won't put that number in our
@@ -249,7 +254,7 @@ class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
       RetVal.Field = FD;
       auto &Ctx = FD->getASTContext();
       auto Info = Ctx.getTypeInfoInChars(FD->getType());
-      RetVal.Size = Info.Width;
+      RetVal.Size = FD->isZeroSize(Ctx) ? CharUnits::Zero() : Info.Width;
       RetVal.Align = Info.Align;
       assert(llvm::isPowerOf2_64(RetVal.Align.getQuantity()));
       if (auto Max = FD->getMaxAlignment())

diff  --git a/clang/test/Analysis/padding_no_unique_address.cpp b/clang/test/Analysis/padding_no_unique_address.cpp
new file mode 100644
index 0000000000000..4f26922c9450d
--- /dev/null
+++ b/clang/test/Analysis/padding_no_unique_address.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-linux-gnu -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
+
+class Empty {}; // no-warning
+
+// expected-warning at +1{{Excessive padding in 'struct NoUniqueAddressWarn1' (6 padding}}
+struct NoUniqueAddressWarn1 {
+  char c1;
+  [[no_unique_address]] Empty empty;
+  int i;
+  char c2;
+};
+
+// expected-warning at +1{{Excessive padding in 'struct NoUniqueAddressWarn2' (6 padding}}
+struct NoUniqueAddressWarn2 {
+    char c1;
+    [[no_unique_address]] Empty e1, e2;
+    int i;
+    char c2;
+};
+
+struct NoUniqueAddressNoWarn1 {
+  char c1;
+  [[no_unique_address]] Empty empty;
+  char c2;
+};
+
+struct NoUniqueAddressNoWarn2 {
+  char c1;
+  [[no_unique_address]] Empty e1, e2;
+};


        


More information about the cfe-commits mailing list