https://github.com/vvuksanovic created https://github.com/llvm/llvm-project/pull/150025
These warnings are reported on a per expression basis, however some potential misaligned accesses are discarded before that happens. The problem is when a new expression starts while processing another expression. The new expression will end first and emit 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. Fixed by checking if the candidate is located withing the currently processed expression. Fixes #144729 >From abe802b78723ab93d25d32e4736780b85ad2a3b5 Mon Sep 17 00:00:00 2001 From: Vladimir Vuksanovic <vladimir.vuksano...@htecgroup.com> Date: Wed, 2 Jul 2025 07:25:01 -0700 Subject: [PATCH] [Sema] Fix false positive warnings for misaligned member access These warnings are reported on a per expression basis, however some potential misaligned accesses are discarded before that happens. The problem is when a new expression starts while processing another expression. The new expression will end first and emit 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. Fixed by checking if the candidate is located withing the currently processed expression. Fixes #144729 --- clang/include/clang/Sema/Sema.h | 2 +- clang/lib/Sema/SemaChecking.cpp | 27 +++++++++++++++++++-------- clang/test/Sema/address-packed.c | 8 ++++++++ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index b331acbe606b7..a2ad749d67259 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2655,7 +2655,7 @@ class Sema final : public SemaBase { /// Diagnoses the current set of gathered accesses. This typically /// happens at full expression level. The set is cleared after emitting the /// diagnostics. - void DiagnoseMisalignedMembers(); + void DiagnoseMisalignedMembers(const Expr *E); /// This function checks if the expression is in the sef of potentially /// misaligned members and it is converted to some pointer type T with lower diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 5e523fe887318..032cda4bd5d58 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -14086,7 +14086,7 @@ void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc, CheckUnsequencedOperations(E); if (!IsConstexpr && !E->isValueDependent()) CheckForIntOverflow(E); - DiagnoseMisalignedMembers(); + DiagnoseMisalignedMembers(E); } void Sema::CheckBitFieldInitialization(SourceLocation InitLoc, @@ -15534,17 +15534,28 @@ void Sema::AddPotentialMisalignedMembers(Expr *E, RecordDecl *RD, ValueDecl *MD, MisalignedMembers.emplace_back(E, RD, MD, Alignment); } -void Sema::DiagnoseMisalignedMembers() { - for (MisalignedMember &m : MisalignedMembers) { - const NamedDecl *ND = m.RD; +void Sema::DiagnoseMisalignedMembers(const Expr *E) { + // Only emit diagnostics related to the current expression. + const auto *EmitFrom = MisalignedMembers.begin(); + if (E->getSourceRange().isValid()) { + EmitFrom = MisalignedMembers.end(); + for (const auto &m : llvm::reverse(MisalignedMembers)) { + if (m.E->getSourceRange().isValid() && + !E->getSourceRange().fullyContains(m.E->getSourceRange())) + break; + EmitFrom = &m; + } + } + for (const auto *m = EmitFrom; m != MisalignedMembers.end(); ++m) { + const NamedDecl *ND = m->RD; if (ND->getName().empty()) { - if (const TypedefNameDecl *TD = m.RD->getTypedefNameForAnonDecl()) + if (const TypedefNameDecl *TD = m->RD->getTypedefNameForAnonDecl()) ND = TD; } - Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member) - << m.MD << ND << m.E->getSourceRange(); + Diag(m->E->getBeginLoc(), diag::warn_taking_address_of_packed_member) + << m->MD << ND << m->E->getSourceRange(); } - MisalignedMembers.clear(); + MisalignedMembers.erase(EmitFrom, MisalignedMembers.end()); } void Sema::DiscardMisalignedMemberAddress(const Type *T, Expr *E) { 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