Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ Improvements to Clang's diagnostics
"signedness of format specifier 'u' is incompatible with 'c' [-Wformat-signedness]"
and the API-visible diagnostic id will be appropriate.

- 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
----------------------------------

Expand Down
13 changes: 7 additions & 6 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -2659,9 +2659,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
Expand Down Expand Up @@ -3117,9 +3117,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,
Expand Down Expand Up @@ -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 {
Expand Down
16 changes: 9 additions & 7 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14125,7 +14125,6 @@ void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc,
CheckUnsequencedOperations(E);
if (!IsConstexpr && !E->isValueDependent())
CheckForIntOverflow(E);
DiagnoseMisalignedMembers();
}

void Sema::CheckBitFieldInitialization(SourceLocation InitLoc,
Expand Down Expand Up @@ -15570,11 +15569,12 @@ 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) {
for (MisalignedMember &m : currentEvaluationContext().MisalignedMembers) {
const NamedDecl *ND = m.RD;
if (ND->getName().empty()) {
if (const TypedefNameDecl *TD = m.RD->getTypedefNameForAnonDecl())
Expand All @@ -15583,7 +15583,7 @@ void Sema::DiagnoseMisalignedMembers() {
Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
<< m.MD << ND << m.E->getSourceRange();
}
MisalignedMembers.clear();
currentEvaluationContext().MisalignedMembers.clear();
}

void Sema::DiscardMisalignedMemberAddress(const Type *T, Expr *E) {
Expand All @@ -15594,13 +15594,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);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18121,6 +18121,8 @@ void Sema::PopExpressionEvaluationContext() {
MaybeODRUseExprs.insert_range(Rec.SavedMaybeODRUseExprs);
}

DiagnoseMisalignedMembers();

// Pop the current expression evaluation context off the stack.
ExprEvalContexts.pop_back();
}
Expand Down
8 changes: 8 additions & 0 deletions clang/test/Sema/address-packed.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
}