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] [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 +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits