[clang] [Sema] Enforce parameter match for ownership_returns attribute (PR #192339)
David Meng via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 27 13:52:38 PDT 2026
https://github.com/davidmenggx updated https://github.com/llvm/llvm-project/pull/192339
>From 391061108d2170a56c18d10810c48b5eacec0444 Mon Sep 17 00:00:00 2001
From: David Meng <davidmenggx at gmail.com>
Date: Wed, 15 Apr 2026 06:38:21 -0700
Subject: [PATCH 1/7] [Sema] Enforce parameter match for ownership_returns
attribute
Previously parsing multiple ownership_returns attributes with different
arguments could lead to a crash. The documentation states that if
forward declarations have this attribute, they must have the same
arguments, and it may appear at most once per declaration.
This patch ensures that if multiple ownership_returns attributes are
present, their arguments (identifier and the optional index) must
exactly match. The diagonstic err_ownership_param_mismatch is
introduced for clarity.
Test cases for f15, C::f, and the newly added f22 were also updated
to match the requirement that all declarations of ownership_returns have
the same arguments, using the err_ownership_param_mismatch diagonstic.
Fixes #188733
---
.../clang/Basic/DiagnosticSemaKinds.td | 2 +
clang/lib/Sema/SemaDeclAttr.cpp | 56 ++++++++++---------
clang/test/Sema/attr-ownership.c | 8 ++-
clang/test/Sema/attr-ownership.cpp | 14 ++---
4 files changed, 44 insertions(+), 36 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4cd4efc55c416..c94d8beadb706 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3516,6 +3516,8 @@ def err_ownership_returns_index_mismatch : Error<
"'ownership_returns' attribute index does not match; here it is %0">;
def note_ownership_returns_index_mismatch : Note<
"declared with index %0 here">;
+def err_ownership_param_mismatch : Error<
+ "'ownership_returns' attribute arguments do not match the previous declaration">;
def err_ownership_takes_class_mismatch : Error<
"'ownership_takes' attribute class does not match; here it is '%0'">;
def note_ownership_takes_class_mismatch : Note<
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 8a856215a9627..bd01522f441f5 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1558,38 +1558,40 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
// Cannot have two ownership attributes of different kinds for the same
// index.
if (I->getOwnKind() != K && llvm::is_contained(I->args(), Idx)) {
- S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
- << AL << I
- << (AL.isRegularKeywordAttribute() ||
- I->isRegularKeywordAttribute());
- return;
- } else if (K == OwnershipAttr::Returns &&
- I->getOwnKind() == OwnershipAttr::Returns) {
- // A returns attribute conflicts with any other returns attribute using
- // a different index.
- if (!llvm::is_contained(I->args(), Idx)) {
- S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
- << I->args_begin()->getSourceIndex();
- if (I->args_size())
- S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
- << Idx.getSourceIndex() << Ex->getSourceRange();
- return;
- }
- } else if (K == OwnershipAttr::Takes &&
- I->getOwnKind() == OwnershipAttr::Takes) {
- if (I->getModule()->getName() != ModuleName) {
- S.Diag(I->getLocation(), diag::err_ownership_takes_class_mismatch)
- << I->getModule()->getName();
- S.Diag(AL.getLoc(), diag::note_ownership_takes_class_mismatch)
- << ModuleName << Ex->getSourceRange();
-
- return;
- }
+ S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
+ << AL << I
+ << (AL.isRegularKeywordAttribute() ||
+ I->isRegularKeywordAttribute());
+ return;
}
}
OwnershipArgs.push_back(Idx);
}
+ for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
+ if (K == OwnershipAttr::Returns &&
+ I->getOwnKind() == OwnershipAttr::Returns) {
+ // Enforce that all ownership_returns attributes have the exact same
+ // arguments.
+ bool ExactMatch =
+ (I->getModule() == Module) && llvm::equal(I->args(), OwnershipArgs);
+
+ if (!ExactMatch) {
+ S.Diag(AL.getLoc(), diag::err_ownership_param_mismatch);
+ }
+ return;
+ } else if (K == OwnershipAttr::Takes &&
+ I->getOwnKind() == OwnershipAttr::Takes) {
+ if (I->getModule() != Module) {
+ S.Diag(I->getLocation(), diag::err_ownership_takes_class_mismatch)
+ << I->getModule()->getName();
+ S.Diag(AL.getLoc(), diag::note_ownership_takes_class_mismatch)
+ << ModuleName << AL.getRange();
+ return;
+ }
+ }
+ }
+
ParamIdx *Start = OwnershipArgs.data();
unsigned Size = OwnershipArgs.size();
llvm::array_pod_sort(Start, Start + Size);
diff --git a/clang/test/Sema/attr-ownership.c b/clang/test/Sema/attr-ownership.c
index 515428d7d6c44..c0040d6464be8 100644
--- a/clang/test/Sema/attr-ownership.c
+++ b/clang/test/Sema/attr-ownership.c
@@ -19,8 +19,8 @@ void f13(int *i, int *j) __attribute__((ownership_holds(foo, 1))) __attribute__(
void f14(int i, int j, int *k) __attribute__((ownership_holds(foo, 3))) __attribute__((ownership_takes(foo, 3))); // expected-error {{'ownership_takes' and 'ownership_holds' attributes are not compatible}}
void *f15(int, int)
- __attribute__((ownership_returns(foo, 1))) // expected-error {{'ownership_returns' attribute index does not match; here it is 1}}
- __attribute__((ownership_returns(foo, 2))); // expected-note {{declared with index 2 here}}
+ __attribute__((ownership_returns(foo, 1)))
+ __attribute__((ownership_returns(foo, 2))); // expected-error {{'ownership_returns' attribute arguments do not match the previous declaration}}
void f16(int *i, int *j) __attribute__((ownership_holds(foo, 1))) __attribute__((ownership_holds(foo, 1))); // OK, same index
void f17(void*) __attribute__((ownership_takes(__, 1)));
void f18() __attribute__((ownership_takes(foo, 1))); // expected-warning {{'ownership_takes' attribute only applies to non-K&R-style functions}}
@@ -31,3 +31,7 @@ int f19(void *)
void f20(void) __attribute__((ownership_returns(foo))); // expected-error {{'ownership_returns' attribute only applies to functions that return a pointer}}
int f21(void) __attribute__((ownership_returns(foo))); // expected-error {{'ownership_returns' attribute only applies to functions that return a pointer}}
+
+void *f22(int, int)
+ __attribute__((ownership_returns(used)))
+ __attribute__((ownership_returns(foo, 2))); // expected-error {{'ownership_returns' attribute arguments do not match the previous declaration}}
diff --git a/clang/test/Sema/attr-ownership.cpp b/clang/test/Sema/attr-ownership.cpp
index 0626efa5aaf9a..a8cee71fbc5b2 100644
--- a/clang/test/Sema/attr-ownership.cpp
+++ b/clang/test/Sema/attr-ownership.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only
-
-class C {
- void *f(int, int)
- __attribute__((ownership_returns(foo, 2))) // expected-error {{'ownership_returns' attribute index does not match; here it is 2}}
- __attribute__((ownership_returns(foo, 3))); // expected-note {{declared with index 3 here}}
-};
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+class C {
+ void *f(int, int)
+ __attribute__((ownership_returns(foo, 2)))
+ __attribute__((ownership_returns(foo, 3))); // expected-error {{'ownership_returns' attribute arguments do not match the previous declaration}}
+};
>From 3a1b8e205f00a4aadd1fd83e20254edf38982fc2 Mon Sep 17 00:00:00 2001
From: David Meng <davidmenggx at gmail.com>
Date: Fri, 24 Apr 2026 11:50:30 -0700
Subject: [PATCH 2/7] Return to using err_ownership_returns_index_mismatch
dialogue and match existing loop structure
---
clang/docs/ReleaseNotes.rst | 1 +
.../clang/Basic/DiagnosticSemaKinds.td | 6 +-
clang/lib/Sema/SemaDeclAttr.cpp | 60 ++++++++++++-------
clang/test/Sema/attr-ownership.c | 8 +--
clang/test/Sema/attr-ownership.cpp | 4 +-
5 files changed, 46 insertions(+), 33 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1db1d9fea6b98..538e4c67416d8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -414,6 +414,7 @@ Bug Fixes in This Version
- Fixed incorrect rejection of ``auto`` with reordered declaration specifiers in C23. (#GH164121)
- Fixed a crash where constexpr evaluation encountered invalid overrides. (#GH183290)
- Fixed a crash when assigning to an element of an ``ext_vector_type`` with ``bool`` element type. (#GH189260)
+- Fixed a crash caused by declaring multiple ``ownership_returns`` attributes with mismatched or missing arguments. (#GH188733)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c94d8beadb706..dfd659863d36d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3513,11 +3513,9 @@ def err_ownership_type : Error<
def err_ownership_takes_return_type : Error<
"'ownership_returns' attribute only applies to functions that return a pointer">;
def err_ownership_returns_index_mismatch : Error<
- "'ownership_returns' attribute index does not match; here it is %0">;
+ "'ownership_returns' attribute index does not match; here it is %select{%0|omitted}1">;
def note_ownership_returns_index_mismatch : Note<
- "declared with index %0 here">;
-def err_ownership_param_mismatch : Error<
- "'ownership_returns' attribute arguments do not match the previous declaration">;
+ "declared %select{with index %0|without an index}1 here">;
def err_ownership_takes_class_mismatch : Error<
"'ownership_takes' attribute class does not match; here it is '%0'">;
def note_ownership_takes_class_mismatch : Note<
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index bd01522f441f5..22832a0cc35c7 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1526,6 +1526,20 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
Module = &S.PP.getIdentifierTable().get(ModuleName);
}
+ // Check if the new ownership_returns attribute does not contain
+ // an index, but previous attributes do
+ if (K == OwnershipAttr::Returns && AL.getNumArgs() == 1) {
+ for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
+ if (I->getOwnKind() == OwnershipAttr::Returns && I->args_size() > 0) {
+ S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
+ << I->args_begin()->getSourceIndex() << 0;
+ S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
+ << 0 << 1;
+ return;
+ }
+ }
+ }
+
SmallVector<ParamIdx, 8> OwnershipArgs;
for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
Expr *Ex = AL.getArgAsExpr(i);
@@ -1563,33 +1577,33 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
<< (AL.isRegularKeywordAttribute() ||
I->isRegularKeywordAttribute());
return;
- }
- }
- OwnershipArgs.push_back(Idx);
- }
+ } else if (K == OwnershipAttr::Returns &&
+ I->getOwnKind() == OwnershipAttr::Returns) {
+ bool IHasArgs = I->args_size() > 0;
- for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
- if (K == OwnershipAttr::Returns &&
- I->getOwnKind() == OwnershipAttr::Returns) {
- // Enforce that all ownership_returns attributes have the exact same
- // arguments.
- bool ExactMatch =
- (I->getModule() == Module) && llvm::equal(I->args(), OwnershipArgs);
+ if (!IHasArgs || !llvm::is_contained(I->args(), Idx)) {
+ unsigned IIdx = IHasArgs ? I->args_begin()->getSourceIndex() : 0;
- if (!ExactMatch) {
- S.Diag(AL.getLoc(), diag::err_ownership_param_mismatch);
- }
- return;
- } else if (K == OwnershipAttr::Takes &&
- I->getOwnKind() == OwnershipAttr::Takes) {
- if (I->getModule() != Module) {
- S.Diag(I->getLocation(), diag::err_ownership_takes_class_mismatch)
- << I->getModule()->getName();
- S.Diag(AL.getLoc(), diag::note_ownership_takes_class_mismatch)
- << ModuleName << AL.getRange();
- return;
+ S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
+ << IIdx << (IHasArgs ? 0 : 1);
+
+ S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
+ << Idx.getSourceIndex() << 0 << Ex->getSourceRange();
+ return;
+ }
+ } else if (K == OwnershipAttr::Takes &&
+ I->getOwnKind() == OwnershipAttr::Takes) {
+ if (I->getModule()->getName() != ModuleName) {
+ S.Diag(I->getLocation(), diag::err_ownership_takes_class_mismatch)
+ << I->getModule()->getName();
+ S.Diag(AL.getLoc(), diag::note_ownership_takes_class_mismatch)
+ << ModuleName << Ex->getSourceRange();
+
+ return;
+ }
}
}
+ OwnershipArgs.push_back(Idx);
}
ParamIdx *Start = OwnershipArgs.data();
diff --git a/clang/test/Sema/attr-ownership.c b/clang/test/Sema/attr-ownership.c
index c0040d6464be8..e5288a2f6103c 100644
--- a/clang/test/Sema/attr-ownership.c
+++ b/clang/test/Sema/attr-ownership.c
@@ -19,8 +19,8 @@ void f13(int *i, int *j) __attribute__((ownership_holds(foo, 1))) __attribute__(
void f14(int i, int j, int *k) __attribute__((ownership_holds(foo, 3))) __attribute__((ownership_takes(foo, 3))); // expected-error {{'ownership_takes' and 'ownership_holds' attributes are not compatible}}
void *f15(int, int)
- __attribute__((ownership_returns(foo, 1)))
- __attribute__((ownership_returns(foo, 2))); // expected-error {{'ownership_returns' attribute arguments do not match the previous declaration}}
+ __attribute__((ownership_returns(foo, 1))) // expected-error {{'ownership_returns' attribute index does not match; here it is 1}}
+ __attribute__((ownership_returns(foo, 2))); // expected-note {{declared with index 2 here}}
void f16(int *i, int *j) __attribute__((ownership_holds(foo, 1))) __attribute__((ownership_holds(foo, 1))); // OK, same index
void f17(void*) __attribute__((ownership_takes(__, 1)));
void f18() __attribute__((ownership_takes(foo, 1))); // expected-warning {{'ownership_takes' attribute only applies to non-K&R-style functions}}
@@ -33,5 +33,5 @@ void f20(void) __attribute__((ownership_returns(foo))); // expected-error {{'ow
int f21(void) __attribute__((ownership_returns(foo))); // expected-error {{'ownership_returns' attribute only applies to functions that return a pointer}}
void *f22(int, int)
- __attribute__((ownership_returns(used)))
- __attribute__((ownership_returns(foo, 2))); // expected-error {{'ownership_returns' attribute arguments do not match the previous declaration}}
+ __attribute__((ownership_returns(used))) // expected-error {{'ownership_returns' attribute index does not match; here it is omitted}}
+ __attribute__((ownership_returns(foo, 2))); // expected-note {{declared with index 2 here}}
diff --git a/clang/test/Sema/attr-ownership.cpp b/clang/test/Sema/attr-ownership.cpp
index a8cee71fbc5b2..2d636b20907b9 100644
--- a/clang/test/Sema/attr-ownership.cpp
+++ b/clang/test/Sema/attr-ownership.cpp
@@ -2,6 +2,6 @@
class C {
void *f(int, int)
- __attribute__((ownership_returns(foo, 2)))
- __attribute__((ownership_returns(foo, 3))); // expected-error {{'ownership_returns' attribute arguments do not match the previous declaration}}
+ __attribute__((ownership_returns(foo, 2))) // expected-error {{'ownership_returns' attribute index does not match; here it is 2}}
+ __attribute__((ownership_returns(foo, 3))); // expected-note {{declared with index 3 here}}
};
>From 8530f783f3d871efeba426b0ad6a9f10d7bf472c Mon Sep 17 00:00:00 2001
From: David Meng <davidmenggx at gmail.com>
Date: Sat, 25 Apr 2026 06:55:21 -0700
Subject: [PATCH 3/7] Update to follow the else-after-return rule
---
clang/lib/Sema/SemaDeclAttr.cpp | 8 ++++++--
clang/test/Sema/attr-ownership.cpp | 14 +++++++-------
2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 22832a0cc35c7..97d0f957df0ea 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1577,7 +1577,9 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
<< (AL.isRegularKeywordAttribute() ||
I->isRegularKeywordAttribute());
return;
- } else if (K == OwnershipAttr::Returns &&
+ }
+
+ if (K == OwnershipAttr::Returns &&
I->getOwnKind() == OwnershipAttr::Returns) {
bool IHasArgs = I->args_size() > 0;
@@ -1591,7 +1593,9 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
<< Idx.getSourceIndex() << 0 << Ex->getSourceRange();
return;
}
- } else if (K == OwnershipAttr::Takes &&
+ }
+
+ if (K == OwnershipAttr::Takes &&
I->getOwnKind() == OwnershipAttr::Takes) {
if (I->getModule()->getName() != ModuleName) {
S.Diag(I->getLocation(), diag::err_ownership_takes_class_mismatch)
diff --git a/clang/test/Sema/attr-ownership.cpp b/clang/test/Sema/attr-ownership.cpp
index 2d636b20907b9..0626efa5aaf9a 100644
--- a/clang/test/Sema/attr-ownership.cpp
+++ b/clang/test/Sema/attr-ownership.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only
-
-class C {
- void *f(int, int)
- __attribute__((ownership_returns(foo, 2))) // expected-error {{'ownership_returns' attribute index does not match; here it is 2}}
- __attribute__((ownership_returns(foo, 3))); // expected-note {{declared with index 3 here}}
-};
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+class C {
+ void *f(int, int)
+ __attribute__((ownership_returns(foo, 2))) // expected-error {{'ownership_returns' attribute index does not match; here it is 2}}
+ __attribute__((ownership_returns(foo, 3))); // expected-note {{declared with index 3 here}}
+};
>From 00a54e9c7c2f11b09ac017d087182e3012eef09f Mon Sep 17 00:00:00 2001
From: David Meng <davidmenggx at gmail.com>
Date: Mon, 27 Apr 2026 12:19:18 -0700
Subject: [PATCH 4/7] Re-add else if block because previous conditional does
not return unconditionally
---
clang/lib/Sema/SemaDeclAttr.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 97d0f957df0ea..1db3ad103d5ec 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1527,7 +1527,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
// Check if the new ownership_returns attribute does not contain
- // an index, but previous attributes do
+ // an index, but previous attributes do.
if (K == OwnershipAttr::Returns && AL.getNumArgs() == 1) {
for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
if (I->getOwnKind() == OwnershipAttr::Returns && I->args_size() > 0) {
@@ -1593,9 +1593,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
<< Idx.getSourceIndex() << 0 << Ex->getSourceRange();
return;
}
- }
-
- if (K == OwnershipAttr::Takes &&
+ } else if (K == OwnershipAttr::Takes &&
I->getOwnKind() == OwnershipAttr::Takes) {
if (I->getModule()->getName() != ModuleName) {
S.Diag(I->getLocation(), diag::err_ownership_takes_class_mismatch)
>From 4100202cb32c72dfe00fe3c8838a4d28952483eb Mon Sep 17 00:00:00 2001
From: David Meng <davidmenggx at gmail.com>
Date: Mon, 27 Apr 2026 13:37:41 -0700
Subject: [PATCH 5/7] Fix whitespace
---
clang/docs/ReleaseNotes.rst | 3 +++
clang/lib/Sema/SemaDeclAttr.cpp | 4 ++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 538e4c67416d8..ea8bf00969153 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -415,6 +415,9 @@ Bug Fixes in This Version
- Fixed a crash where constexpr evaluation encountered invalid overrides. (#GH183290)
- Fixed a crash when assigning to an element of an ``ext_vector_type`` with ``bool`` element type. (#GH189260)
- Fixed a crash caused by declaring multiple ``ownership_returns`` attributes with mismatched or missing arguments. (#GH188733)
+- Clang now emits an error for friend declarations of lambda members. (#GH26540)
+- Fixed a crash caused by lambda capture handling in delayed default arguments. (#GH176534)
+- Fixed a crash when parsing invalid ``static_assert`` declarations with string-literal messages (#GH187690).
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1db3ad103d5ec..67c2c1ad71303 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1526,7 +1526,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
Module = &S.PP.getIdentifierTable().get(ModuleName);
}
- // Check if the new ownership_returns attribute does not contain
+ // Check if the new ownership_returns attribute does not contain
// an index, but previous attributes do.
if (K == OwnershipAttr::Returns && AL.getNumArgs() == 1) {
for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
@@ -1580,7 +1580,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
if (K == OwnershipAttr::Returns &&
- I->getOwnKind() == OwnershipAttr::Returns) {
+ I->getOwnKind() == OwnershipAttr::Returns) {
bool IHasArgs = I->args_size() > 0;
if (!IHasArgs || !llvm::is_contained(I->args(), Idx)) {
>From 91afecbd3b769e4e951f30a869a03cd56c31f1da Mon Sep 17 00:00:00 2001
From: David Meng <davidmenggx at gmail.com>
Date: Mon, 27 Apr 2026 13:45:58 -0700
Subject: [PATCH 6/7] Revert "Fix whitespace"
This reverts commit 4100202cb32c72dfe00fe3c8838a4d28952483eb.
---
clang/docs/ReleaseNotes.rst | 3 ---
clang/lib/Sema/SemaDeclAttr.cpp | 4 ++--
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ea8bf00969153..538e4c67416d8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -415,9 +415,6 @@ Bug Fixes in This Version
- Fixed a crash where constexpr evaluation encountered invalid overrides. (#GH183290)
- Fixed a crash when assigning to an element of an ``ext_vector_type`` with ``bool`` element type. (#GH189260)
- Fixed a crash caused by declaring multiple ``ownership_returns`` attributes with mismatched or missing arguments. (#GH188733)
-- Clang now emits an error for friend declarations of lambda members. (#GH26540)
-- Fixed a crash caused by lambda capture handling in delayed default arguments. (#GH176534)
-- Fixed a crash when parsing invalid ``static_assert`` declarations with string-literal messages (#GH187690).
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 67c2c1ad71303..1db3ad103d5ec 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1526,7 +1526,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
Module = &S.PP.getIdentifierTable().get(ModuleName);
}
- // Check if the new ownership_returns attribute does not contain
+ // Check if the new ownership_returns attribute does not contain
// an index, but previous attributes do.
if (K == OwnershipAttr::Returns && AL.getNumArgs() == 1) {
for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
@@ -1580,7 +1580,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
if (K == OwnershipAttr::Returns &&
- I->getOwnKind() == OwnershipAttr::Returns) {
+ I->getOwnKind() == OwnershipAttr::Returns) {
bool IHasArgs = I->args_size() > 0;
if (!IHasArgs || !llvm::is_contained(I->args(), Idx)) {
>From 0622f32de9df42486d68b210b3c126be691a80ec Mon Sep 17 00:00:00 2001
From: David Meng <davidmenggx at gmail.com>
Date: Mon, 27 Apr 2026 13:52:15 -0700
Subject: [PATCH 7/7] Fix whitespace
---
clang/lib/Sema/SemaDeclAttr.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1db3ad103d5ec..67c2c1ad71303 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1526,7 +1526,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
Module = &S.PP.getIdentifierTable().get(ModuleName);
}
- // Check if the new ownership_returns attribute does not contain
+ // Check if the new ownership_returns attribute does not contain
// an index, but previous attributes do.
if (K == OwnershipAttr::Returns && AL.getNumArgs() == 1) {
for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
@@ -1580,7 +1580,7 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
if (K == OwnershipAttr::Returns &&
- I->getOwnKind() == OwnershipAttr::Returns) {
+ I->getOwnKind() == OwnershipAttr::Returns) {
bool IHasArgs = I->args_size() > 0;
if (!IHasArgs || !llvm::is_contained(I->args(), Idx)) {
More information about the cfe-commits
mailing list