https://github.com/vvuksanovic updated https://github.com/llvm/llvm-project/pull/150025
>From 118f0c1aff19b7e9db01da349e3089846afd015d Mon Sep 17 00:00:00 2001 From: Vladimir Vuksanovic <vladimir.vuksano...@htecgroup.com> Date: Fri, 11 Jul 2025 04:14:43 -0700 Subject: [PATCH 1/4] [Sema] Fix false positive warnings for misaligned member access Potential misaligned accesses are collected and reported on a per full expression basis, however some of them are discarded before reporting. When a nested full expression is completed it will emit diagnostics for all potential misaligned accesses collected up to that point. That includes candidates that were found in the parent expression, even though they might have gotten discarded later. This is fixed by maintaining separate potential candidate lists per expression evaluation context and processing only the list for the current context. --- clang/include/clang/Sema/Sema.h | 7 ++++--- clang/lib/Sema/SemaChecking.cpp | 17 ++++++++++------- clang/lib/Sema/SemaExpr.cpp | 2 ++ clang/test/Sema/address-packed.c | 8 ++++++++ 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index b331acbe606b7..22651f1107fb3 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3110,9 +3110,6 @@ class Sema final : public SemaBase { bool operator==(const MisalignedMember &m) { return this->E == m.E; } }; - /// Small set of gathered accesses to potentially misaligned members - /// due to the packed attribute. - SmallVector<MisalignedMember, 4> MisalignedMembers; /// Adds an expression to the set of gathered misaligned members. void AddPotentialMisalignedMembers(Expr *E, RecordDecl *RD, ValueDecl *MD, @@ -6765,6 +6762,10 @@ class Sema final : public SemaBase { /// InLifetimeExtendingContext is true. SmallVector<MaterializeTemporaryExpr *, 8> ForRangeLifetimeExtendTemps; + /// Small set of gathered accesses to potentially misaligned members + /// due to the packed attribute. + SmallVector<MisalignedMember, 4> MisalignedMembers; + /// \brief Describes whether we are in an expression constext which we have /// to handle differently. enum ExpressionKind { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index dd5b710d7e1d4..683a3e0970670 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -14084,7 +14084,6 @@ void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc, CheckUnsequencedOperations(E); if (!IsConstexpr && !E->isValueDependent()) CheckForIntOverflow(E); - DiagnoseMisalignedMembers(); } void Sema::CheckBitFieldInitialization(SourceLocation InitLoc, @@ -15529,11 +15528,13 @@ void Sema::CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr, void Sema::AddPotentialMisalignedMembers(Expr *E, RecordDecl *RD, ValueDecl *MD, CharUnits Alignment) { - MisalignedMembers.emplace_back(E, RD, MD, Alignment); + currentEvaluationContext().MisalignedMembers.emplace_back(E, RD, MD, + Alignment); } void Sema::DiagnoseMisalignedMembers() { - for (MisalignedMember &m : MisalignedMembers) { + auto &MisalignedMembersForExpr = currentEvaluationContext().MisalignedMembers; + for (MisalignedMember &m : MisalignedMembersForExpr) { const NamedDecl *ND = m.RD; if (ND->getName().empty()) { if (const TypedefNameDecl *TD = m.RD->getTypedefNameForAnonDecl()) @@ -15542,7 +15543,7 @@ void Sema::DiagnoseMisalignedMembers() { Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member) << m.MD << ND << m.E->getSourceRange(); } - MisalignedMembers.clear(); + MisalignedMembersForExpr.clear(); } void Sema::DiscardMisalignedMemberAddress(const Type *T, Expr *E) { @@ -15553,13 +15554,15 @@ void Sema::DiscardMisalignedMemberAddress(const Type *T, Expr *E) { cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf) { auto *Op = cast<UnaryOperator>(E)->getSubExpr()->IgnoreParens(); if (isa<MemberExpr>(Op)) { - auto *MA = llvm::find(MisalignedMembers, MisalignedMember(Op)); - if (MA != MisalignedMembers.end() && + auto &MisalignedMembersForExpr = + currentEvaluationContext().MisalignedMembers; + auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op)); + if (MA != MisalignedMembersForExpr.end() && (T->isDependentType() || T->isIntegerType() || (T->isPointerType() && (T->getPointeeType()->isIncompleteType() || Context.getTypeAlignInChars( T->getPointeeType()) <= MA->Alignment)))) - MisalignedMembers.erase(MA); + MisalignedMembersForExpr.erase(MA); } } } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 728ada33e2e63..79732d1890d9a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -18105,6 +18105,8 @@ void Sema::PopExpressionEvaluationContext() { MaybeODRUseExprs.insert_range(Rec.SavedMaybeODRUseExprs); } + DiagnoseMisalignedMembers(); + // Pop the current expression evaluation context off the stack. ExprEvalContexts.pop_back(); } diff --git a/clang/test/Sema/address-packed.c b/clang/test/Sema/address-packed.c index 29f12490e9fab..f826b7d57d91c 100644 --- a/clang/test/Sema/address-packed.c +++ b/clang/test/Sema/address-packed.c @@ -338,3 +338,11 @@ struct Invalid0 { void *g14(struct Invalid0 *ivl) { return &(ivl->x); } + +void to_void_with_expr(void *ptr, int expr); + +void g15(void) { + struct Arguable arguable; + to_void_with_expr(&arguable.x, 3); // no-warning + to_void_with_expr(&arguable.x, ({3;})); // no-warning +} >From 75a04c52e2d6ce5760408f3be2e11bf751bb5481 Mon Sep 17 00:00:00 2001 From: Vladimir Vuksanovic <vladimir.vuksano...@htecgroup.com> Date: Wed, 6 Aug 2025 08:25:42 -0700 Subject: [PATCH 2/4] Add release notes entry --- clang/docs/ReleaseNotes.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index fcd3887ec7a09..3ad6b82929e95 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -716,6 +716,10 @@ Improvements to Clang's diagnostics Added a new warning in this group for the case where the attribute is missing/implicit on an override of a virtual method. +- Fixed false positives in ``-Waddress-of-packed-member`` diagnostics when + potential misaligned members get processed before they can get discarded. + (#GH144729) + Improvements to Clang's time-trace ---------------------------------- >From b4db556cca6b1415a9ba42d4a2ca6c6de6d86432 Mon Sep 17 00:00:00 2001 From: Vladimir Vuksanovic <vladimir.vuksano...@htecgroup.com> Date: Mon, 11 Aug 2025 06:35:20 -0700 Subject: [PATCH 3/4] Fix function comment --- clang/include/clang/Sema/Sema.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 22651f1107fb3..4b0cc1d1c7f87 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2652,9 +2652,9 @@ class Sema final : public SemaBase { /// identifies the magic value. typedef std::pair<const IdentifierInfo *, uint64_t> TypeTagMagicValue; - /// Diagnoses the current set of gathered accesses. This typically - /// happens at full expression level. The set is cleared after emitting the - /// diagnostics. + /// Diagnoses the current set of gathered accesses. This happens at the end of + /// each expression evaluation context. Diagnostics are emitted only for + /// accesses gathered in the current evaluation context. void DiagnoseMisalignedMembers(); /// This function checks if the expression is in the sef of potentially >From a8db767305eec3e9ae410c3e2a1be5151bac10b0 Mon Sep 17 00:00:00 2001 From: Vladimir Vuksanovic <vladimir.vuksano...@htecgroup.com> Date: Wed, 13 Aug 2025 07:37:25 -0700 Subject: [PATCH 4/4] Remove alias variable --- clang/lib/Sema/SemaChecking.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 683a3e0970670..761a7433df4c4 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -15533,8 +15533,7 @@ void Sema::AddPotentialMisalignedMembers(Expr *E, RecordDecl *RD, ValueDecl *MD, } void Sema::DiagnoseMisalignedMembers() { - auto &MisalignedMembersForExpr = currentEvaluationContext().MisalignedMembers; - for (MisalignedMember &m : MisalignedMembersForExpr) { + for (MisalignedMember &m : currentEvaluationContext().MisalignedMembers) { const NamedDecl *ND = m.RD; if (ND->getName().empty()) { if (const TypedefNameDecl *TD = m.RD->getTypedefNameForAnonDecl()) @@ -15543,7 +15542,7 @@ void Sema::DiagnoseMisalignedMembers() { Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member) << m.MD << ND << m.E->getSourceRange(); } - MisalignedMembersForExpr.clear(); + currentEvaluationContext().MisalignedMembers.clear(); } void Sema::DiscardMisalignedMemberAddress(const Type *T, Expr *E) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits