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@+1{{Excessive padding in 'struct NoUniqueAddressWarn1' (6 padding}} +struct NoUniqueAddressWarn1 { + char c1; + [[no_unique_address]] Empty empty; + int i; + char c2; +}; + +// expected-warning@+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; +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits