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

Reply via email to