[clang] [Clang] Remove `[[carries_dependency]]` (PR #219912)
Corentin Jabot via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 31 01:38:48 PDT 2026
https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/219912
>From 06e2853d4dbc91674ada0daa24221a7b27f1d55d Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Thu, 27 Aug 2026 13:35:36 +0200
Subject: [PATCH 1/2] [Clang] Removes carries_dependency.
---
clang/docs/ReleaseNotes.md | 13 ++++++--
clang/include/clang/Basic/Attr.td | 7 ----
clang/include/clang/Basic/AttrDocs.td | 17 ----------
.../clang/Basic/DiagnosticSemaKinds.td | 8 -----
clang/lib/Parse/ParseDeclCXX.cpp | 1 -
clang/lib/Sema/SemaDecl.cpp | 30 -----------------
clang/lib/Sema/SemaDeclAttr.cpp | 25 ++-------------
.../dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp | 32 -------------------
.../dcl.dcl/dcl.attr/dcl.attr.depend/p2.cpp | 14 --------
clang/test/CodeCompletion/attr.cpp | 12 ++-----
...a-attribute-supported-attributes-list.test | 1 -
clang/test/Parser/cxx0x-attributes.cpp | 5 +--
clang/test/Parser/cxx11-stmt-attributes.cpp | 30 ++++++++---------
clang/test/Parser/cxx1z-decomposition.cpp | 1 -
clang/test/Parser/stmt-attributes.c | 28 ++++++++--------
clang/test/Preprocessor/has_attribute.cpp | 3 +-
.../macro-reserved-attrs-cxx11.cpp | 9 +++---
clang/test/SemaCXX/attr-cxx0x.cpp | 3 +-
clang/test/SemaCXX/cxx2c-attributes.cpp | 3 +-
clang/www/cxx_status.html | 6 ++--
20 files changed, 63 insertions(+), 185 deletions(-)
delete mode 100644 clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
delete mode 100644 clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p2.cpp
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index bdbabf2cd98d0..dae7ae5f16949 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -54,6 +54,11 @@ in a future version of Clang.
### C++ Specific Potentially Breaking Changes
+- The `[[carries_dependency]]` attribute is no longer recognized, in any language
+ mode, as it was removed from the standard by
+ [P3475R2](https://wg21.link/P3475R2).
+
+
### Objective-C Specific Potentially Breaking Changes
- Fixed an issue where AST consumers based on `RecursiveASTVisitor` would bypass
@@ -73,7 +78,7 @@ features cannot lower the translation-unit ABI level;
- On SPARC, a `_Complex` value with an integer element type is now passed and
returned packed into the one or two integer registers it fits in, matching GCC.
Clang previously passed such a value indirectly and returned it with one part
- per register.
+ per register.
`-fclang-abi-compat=23` restores the previous behavior. (#GH212340)
- On SPARC64, a `_Complex char` or `_Complex short` is now
@@ -119,7 +124,7 @@ features cannot lower the translation-unit ABI level;
- `CompletionString.availability` now returns instances of `AvailabilityKind`.
As a result, the `__str__` representation of its return values changed.
- Like other libclang enums, it now follows the `CompletionChunkKind.VARIANT_NAME` scheme instead of `VariantName`.
+ Like other libclang enums, it now follows the `CompletionChunkKind.VARIANT_NAME` scheme instead of `VariantName`.
### OpenCL Potentially Breaking Changes
@@ -150,6 +155,10 @@ features cannot lower the translation-unit ABI level;
- Clang now supports [P3533R2](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3533r2.html) (constexpr virtual inheritance).
+- Implemented the language part of [P3475R2](https://wg21.link/P3475R2) (Defang
+ and deprecate `memory_order::consume`) by removing support for the
+ `[[carries_dependency]]` attribute.
+
#### C++23 Feature Support
#### C++20 Feature Support
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 252b53e25e5c8..8530216f2c214 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1299,13 +1299,6 @@ def Bounded : IgnoredAttr {
let Spellings = [GNU<"bounded">];
}
-def CarriesDependency : InheritableParamAttr {
- let Spellings = [GNU<"carries_dependency">,
- CXX11<"","carries_dependency", 200809>];
- let Subjects = SubjectList<[ParmVar, ObjCMethod, Function], ErrorDiag>;
- let Documentation = [CarriesDependencyDocs];
-}
-
def CDecl : DeclOrTypeAttr {
let Spellings = [GCC<"cdecl">, CustomKeyword<"__cdecl">, CustomKeyword<"_cdecl">];
// let Subjects = [Function, ObjCMethod];
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 95e27ad9a47c4..285cf02c047cd 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -442,23 +442,6 @@ void maybeundeffunc(int __attribute__((maybe_undef))param);
}];
}
-def CarriesDependencyDocs : Documentation {
- let Category = DocCatFunction;
- let Content = [{
-The `carries_dependency` attribute specifies dependency propagation into and
-out of functions.
-
-When specified on a function or Objective-C method, the `carries_dependency`
-attribute means that the return value carries a dependency out of the function,
-so that the implementation need not constrain ordering upon return from that
-function. Implementations of the function and its caller may choose to preserve
-dependencies instead of emitting memory ordering instructions such as fences.
-
-Note, this attribute does not change the meaning of the program, but may result
-in generation of more efficient code.
- }];
-}
-
def CPUSpecificCPUDispatchDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 24ecc88d2fbc0..68b7bae903bc4 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11471,14 +11471,6 @@ def err_noreturn_has_return_expr : Error<
def warn_noreturn_coroutine : Warning<
"coroutine %0 cannot be declared 'noreturn' as it always returns a coroutine handle">,
InGroup<InvalidNoreturn>;
-def err_carries_dependency_missing_on_first_decl : Error<
- "%select{function|parameter}0 declared '[[carries_dependency]]' "
- "after its first declaration">;
-def note_carries_dependency_missing_first_decl : Note<
- "declaration missing '[[carries_dependency]]' attribute is here">;
-def err_carries_dependency_param_not_function_decl : Error<
- "'[[carries_dependency]]' attribute only allowed on parameter in a function "
- "declaration or lambda">;
def err_block_not_allowed_on : Error<
"'__block' is not allowed on %enum_select<NotAllowedBlockVarReason>{"
"%NonlocalVariable{a nonlocal variable}|"
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index d701cbaa43bdd..274d509a2ec62 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4465,7 +4465,6 @@ static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
IdentifierInfo *ScopeName) {
switch (
ParsedAttr::getParsedKind(AttrName, ScopeName, ParsedAttr::AS_CXX11)) {
- case ParsedAttr::AT_CarriesDependency:
case ParsedAttr::AT_Deprecated:
case ParsedAttr::AT_FallThrough:
case ParsedAttr::AT_CXX11NoReturn:
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 07c6157ab8f31..577f59a1bd8e9 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3457,24 +3457,6 @@ static void propagateAttributes(ParmVarDecl *To, const ParmVarDecl *From,
static void mergeParamDeclAttributes(ParmVarDecl *newDecl,
const ParmVarDecl *oldDecl,
Sema &S) {
- // C++11 [dcl.attr.depend]p2:
- // The first declaration of a function shall specify the
- // carries_dependency attribute for its declarator-id if any declaration
- // of the function specifies the carries_dependency attribute.
- const CarriesDependencyAttr *CDA = newDecl->getAttr<CarriesDependencyAttr>();
- if (CDA && !oldDecl->hasAttr<CarriesDependencyAttr>()) {
- S.Diag(CDA->getLocation(),
- diag::err_carries_dependency_missing_on_first_decl) << 1/*Param*/;
- // Find the first declaration of the parameter.
- // FIXME: Should we build redeclaration chains for function parameters?
- const FunctionDecl *FirstFD =
- cast<FunctionDecl>(oldDecl->getDeclContext())->getFirstDecl();
- const ParmVarDecl *FirstVD =
- FirstFD->getParamDecl(oldDecl->getFunctionScopeIndex());
- S.Diag(FirstVD->getLocation(),
- diag::note_carries_dependency_missing_first_decl) << 1/*Param*/;
- }
-
propagateAttributes(
newDecl, oldDecl, [&S](ParmVarDecl *To, const ParmVarDecl *From) {
unsigned found = 0;
@@ -4231,18 +4213,6 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, Scope *S,
Diag(Old->getLocation(), diag::note_previous_declaration);
}
- // C++11 [dcl.attr.depend]p2:
- // The first declaration of a function shall specify the
- // carries_dependency attribute for its declarator-id if any declaration
- // of the function specifies the carries_dependency attribute.
- const CarriesDependencyAttr *CDA = New->getAttr<CarriesDependencyAttr>();
- if (CDA && !Old->hasAttr<CarriesDependencyAttr>()) {
- Diag(CDA->getLocation(),
- diag::err_carries_dependency_missing_on_first_decl) << 0/*Function*/;
- Diag(Old->getFirstDecl()->getLocation(),
- diag::note_carries_dependency_missing_first_decl) << 0/*Function*/;
- }
-
// SYCL 2020 section 5.10.1, "SYCL functions and member functions linkage":
// When a function is declared with SYCL_EXTERNAL, that macro must be
// used on the first declaration of that function in the translation unit.
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index a61fc54ade757..106605962171b 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2295,21 +2295,6 @@ static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
D->addAttr(::new (S.Context) VecReturnAttr(S.Context, AL));
}
-static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
- const ParsedAttr &AL) {
- if (isa<ParmVarDecl>(D)) {
- // [[carries_dependency]] can only be applied to a parameter if it is a
- // parameter of a function declaration or lambda.
- if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
- S.Diag(AL.getLoc(),
- diag::err_carries_dependency_param_not_function_decl);
- return;
- }
- }
-
- D->addAttr(::new (S.Context) CarriesDependencyAttr(S.Context, AL));
-}
-
static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
bool IsCXX17Attr = AL.isCXX11Attribute() && !AL.getScopeName();
@@ -7570,7 +7555,7 @@ static void handlePersonalityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
/// the attribute applies to decls. If the attribute is a type attribute, just
/// silently ignore it if a GNU attribute.
static void
-ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
+ProcessDeclAttribute(Sema &S, Decl *D, const ParsedAttr &AL,
const Sema::ProcessDeclAttributeOptions &Options) {
if (AL.isInvalid() || AL.getKind() == ParsedAttr::IgnoredAttribute)
return;
@@ -7793,9 +7778,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_Availability:
handleAvailabilityAttr(S, D, AL);
break;
- case ParsedAttr::AT_CarriesDependency:
- handleDependencyAttr(S, scope, D, AL);
- break;
case ParsedAttr::AT_CPUDispatch:
case ParsedAttr::AT_CPUSpecific:
handleCPUSpecificAttr(S, D, AL);
@@ -8569,7 +8551,7 @@ void Sema::ProcessDeclAttributeList(
return;
for (const ParsedAttr &AL : AttrList)
- ProcessDeclAttribute(*this, S, D, AL, Options);
+ ProcessDeclAttribute(*this, D, AL, Options);
// FIXME: We should be able to handle these cases in TableGen.
// GCC accepts
@@ -8690,8 +8672,7 @@ bool Sema::ProcessAccessDeclAttributeList(
AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) {
for (const ParsedAttr &AL : AttrList) {
if (AL.getKind() == ParsedAttr::AT_Annotate) {
- ProcessDeclAttribute(*this, nullptr, ASDecl, AL,
- ProcessDeclAttributeOptions());
+ ProcessDeclAttribute(*this, ASDecl, AL, ProcessDeclAttributeOptions());
} else {
Diag(AL.getLoc(), diag::err_only_annotate_after_access_spec);
return true;
diff --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
deleted file mode 100644
index 424b159667c3b..0000000000000
--- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p1.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: %clang_cc1 -verify -std=c++11 %s
-
-[[carries_dependency, carries_dependency]] int m1(); // ok
-[[carries_dependency]] [[carries_dependency]] int m2(); // ok
-[[carries_dependency()]] int m3(); // expected-error {{attribute 'carries_dependency' cannot have an argument list}}
-
-[[carries_dependency]] void f1(); // FIXME: warn here
-[[carries_dependency]] int f2(); // ok
-int f3(int param [[carries_dependency]]); // ok
-[[carries_dependency]] int (*f4)(); // expected-error {{'carries_dependency' attribute only applies to parameters, Objective-C methods, and functions}}
-int (*f5 [[carries_dependency]])(); // expected-error {{'carries_dependency' attribute only applies to}}
-int (*f6)() [[carries_dependency]]; // expected-error {{'carries_dependency' attribute cannot be applied to types}}
-int (*f7)(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
-int (((f8)))(int n [[carries_dependency]]); // ok
-int (*f9(int n))(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
-int typedef f10(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
-using T = int(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
-struct S {
- [[carries_dependency]] int f(int n [[carries_dependency]]); // ok
- int (*p)(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
-};
-void f() {
- [[carries_dependency]] int f(int n [[carries_dependency]]); // ok
- [[carries_dependency]] // expected-error {{'carries_dependency' attribute only applies to}}
- int (*p)(int n [[carries_dependency]]); // expected-error {{'[[carries_dependency]]' attribute only allowed on parameter in a function declaration}}
-}
-
-auto l1 = [](int n [[carries_dependency]]) {};
-// There's no way to write a lambda such that the return value carries
-// a dependency, because an attribute applied to the lambda appertains to
-// the *type* of the operator() function, not to the function itself.
-auto l2 = []() [[carries_dependency]] {}; // expected-error {{'carries_dependency' attribute cannot be applied to types}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p2.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p2.cpp
deleted file mode 100644
index d5b0ebf459f88..0000000000000
--- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.depend/p2.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: %clang_cc1 -verify -std=c++11 %s
-
-int f(int); // expected-note 2{{declaration missing '[[carries_dependency]]' attribute is here}}
-[[carries_dependency]] int f(int); // expected-error {{function declared '[[carries_dependency]]' after its first declaration}}
-int f(int n [[carries_dependency]]); // expected-error {{parameter declared '[[carries_dependency]]' after its first declaration}}
-
-int g([[carries_dependency]] int n); // expected-note {{declaration missing '[[carries_dependency]]' attribute is here}}
-int g(int);
-[[carries_dependency]] int g(int); // expected-error {{function declared '[[carries_dependency]]' after its first declaration}}
-int g(int n [[carries_dependency]]);
-
-int h [[carries_dependency]]();
-int h();
-[[carries_dependency]] int h();
diff --git a/clang/test/CodeCompletion/attr.cpp b/clang/test/CodeCompletion/attr.cpp
index cff0fa7224b6c..cf7298e742e83 100644
--- a/clang/test/CodeCompletion/attr.cpp
+++ b/clang/test/CodeCompletion/attr.cpp
@@ -1,12 +1,10 @@
int a [[gnu::used]];
// RUN: %clang_cc1 -code-completion-at=%s:%(line-1):9 %s | FileCheck --check-prefix=STD %s
-// STD: COMPLETION: Pattern : __carries_dependency__
// STD-NOT: COMPLETION: Pattern : __convergent__
// STD: COMPLETION: Pattern : __gnu__::__used__
// STD-NOT: COMPLETION: Pattern : __gnu__::used
// STD-NOT: COMPLETION: Pattern : __used__
// STD: COMPLETION: Pattern : _Clang::__convergent__
-// STD: COMPLETION: Pattern : carries_dependency
// STD-NOT: COMPLETION: Pattern : clang::called_once
// STD: COMPLETION: Pattern : clang::convergent
// STD-NOT: COMPLETION: Pattern : convergent
@@ -15,11 +13,10 @@ int a [[gnu::used]];
// STD: COMPLETION: Pattern : gnu::alias(<#Aliasee#>)
// STD: COMPLETION: Pattern : gnu::used
// STD-NOT: COMPLETION: Pattern : used
-// RUN: %clang_cc1 -code-completion-at=%s:%(line-17):9 -xobjective-c++ %s | FileCheck --check-prefix=STD-OBJC %s
+// RUN: %clang_cc1 -code-completion-at=%s:%(line-15):9 -xobjective-c++ %s | FileCheck --check-prefix=STD-OBJC %s
// STD-OBJC: COMPLETION: Pattern : clang::called_once
-// RUN: %clang_cc1 -code-completion-at=%s:%(line-19):14 %s | FileCheck --check-prefix=STD-NS %s
+// RUN: %clang_cc1 -code-completion-at=%s:%(line-17):14 %s | FileCheck --check-prefix=STD-NS %s
// STD-NS-NOT: COMPLETION: Pattern : __used__
-// STD-NS-NOT: COMPLETION: Pattern : carries_dependency
// STD-NS-NOT: COMPLETION: Pattern : clang::convergent
// STD-NS-NOT: COMPLETION: Pattern : convergent
// STD-NS-NOT: COMPLETION: Pattern : gnu::used
@@ -33,21 +30,18 @@ int c [[using gnu: used]];
// RUN: %clang_cc1 -code-completion-at=%s:%(line-1):15 %s | FileCheck --check-prefix=STD-USING %s
// STD-USING: COMPLETION: __gnu__
// STD-USING: COMPLETION: _Clang
-// STD-USING-NOT: COMPLETION: Pattern : carries_dependency
// STD-USING: COMPLETION: clang
// STD-USING-NOT: COMPLETION: Pattern : clang::
// STD-USING-NOT: COMPLETION: Pattern : gnu::
// STD-USING: COMPLETION: gnu
-// RUN: %clang_cc1 -code-completion-at=%s:%(line-9):20 %s | FileCheck --check-prefix=STD-NS %s
+// RUN: %clang_cc1 -code-completion-at=%s:%(line-8):20 %s | FileCheck --check-prefix=STD-NS %s
int d __attribute__((used));
// RUN: %clang_cc1 -code-completion-at=%s:%(line-1):22 %s | FileCheck --check-prefix=GNU %s
-// GNU: COMPLETION: Pattern : __carries_dependency__
// GNU: COMPLETION: Pattern : __convergent__
// GNU-NOT: COMPLETION: Pattern : __gnu__::__used__
// GNU: COMPLETION: Pattern : __used__
// GNU-NOT: COMPLETION: Pattern : _Clang::__convergent__
-// GNU: COMPLETION: Pattern : carries_dependency
// GNU-NOT: COMPLETION: Pattern : clang::convergent
// GNU: COMPLETION: Pattern : convergent
// GNU-NOT: COMPLETION: Pattern : gnu::used
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 8bca68e2119e7..ed2022e3b40d9 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -51,7 +51,6 @@
// CHECK-NEXT: Callback (SubjectMatchRule_function)
// CHECK-NEXT: CalledOnce (SubjectMatchRule_variable_is_parameter)
// CHECK-NEXT: Capability (SubjectMatchRule_record, SubjectMatchRule_type_alias)
-// CHECK-NEXT: CarriesDependency (SubjectMatchRule_variable_is_parameter, SubjectMatchRule_objc_method, SubjectMatchRule_function)
// CHECK-NEXT: Cleanup (SubjectMatchRule_variable_is_local)
// CHECK-NEXT: ClspvLibclcBuiltin (SubjectMatchRule_function)
// CHECK-NEXT: CmseNSEntry (SubjectMatchRule_function)
diff --git a/clang/test/Parser/cxx0x-attributes.cpp b/clang/test/Parser/cxx0x-attributes.cpp
index 220fddb98127a..a587f40aadd98 100644
--- a/clang/test/Parser/cxx0x-attributes.cpp
+++ b/clang/test/Parser/cxx0x-attributes.cpp
@@ -355,7 +355,7 @@ unsigned [[gnu::used]] static int [[gnu::unused]] v1; // expected-error {{'gnu::
expected-error {{an attribute list cannot appear here}}
typedef [[gnu::used]] unsigned long [[gnu::unused]] v2; // expected-error {{'gnu::unused' attribute cannot be applied to types}} \
expected-error {{an attribute list cannot appear here}}
-int [[carries_dependency]] foo(int [[carries_dependency]] x); // expected-error 2{{'carries_dependency' attribute cannot be applied to types}}
+int [[deprecated]] foo(int [[deprecated]] x); // expected-error 2{{'deprecated' attribute cannot be applied to types}}
// Forbid [[gnu::...]] attributes on declarator chunks.
int *[[gnu::unused]] v3; // expected-warning {{attribute 'gnu::unused' ignored}}
@@ -364,7 +364,8 @@ int v5()[[gnu::unused]]; // expected-warning {{attribute 'gnu::unused' ignored}}
[[attribute_declaration]]; // expected-warning {{unknown attribute 'attribute_declaration' ignored}}
[[noreturn]]; // expected-error {{'noreturn' attribute only applies to functions}}
-[[carries_dependency]]; // expected-error {{'carries_dependency' attribute only applies to parameters, Objective-C methods, and functions}}
+// carries_dependency was removed from the standard by P3475R2.
+[[carries_dependency]]; // expected-warning {{unknown attribute 'carries_dependency' ignored}}
class A {
A([[gnu::unused]] int a);
diff --git a/clang/test/Parser/cxx11-stmt-attributes.cpp b/clang/test/Parser/cxx11-stmt-attributes.cpp
index 75fb37ea9fb44..09e1fe892daf4 100644
--- a/clang/test/Parser/cxx11-stmt-attributes.cpp
+++ b/clang/test/Parser/cxx11-stmt-attributes.cpp
@@ -42,7 +42,7 @@ void foo(int i) {
[[unused]] switch (i) { // expected-warning {{unknown attribute 'unused' ignored}}
[[uuid]] case 0: // expected-warning {{unknown attribute 'uuid' ignored}}
[[visibility]] default: // expected-warning {{unknown attribute 'visibility' ignored}}
- [[carries_dependency]] break; // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] break; // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
}
[[fastcall]] goto there; // expected-warning {{unknown attribute 'fastcall' ignored}}
@@ -54,28 +54,28 @@ void foo(int i) {
[[weakref]] return; // expected-warning {{unknown attribute 'weakref' ignored}}
- [[carries_dependency]] ; // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- [[carries_dependency]] { } // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- [[carries_dependency]] if (0) { } // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- [[carries_dependency]] for (;;); // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- [[carries_dependency]] do { // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- [[carries_dependency]] continue; // expected-error {{'carries_dependency' attribute cannot be applied to a statement}} ignored}}
+ [[gnu::nonnull]] ; // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] { } // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] if (0) { } // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] for (;;); // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] do { // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] continue; // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}} ignored}}
} while (0);
- [[carries_dependency]] while (0); // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] while (0); // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
- [[carries_dependency]] switch (i) { // expected-error {{'carries_dependency' attribute cannot be applied to a statement}} ignored}}
- [[carries_dependency]] case 0: // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- [[carries_dependency]] default: // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- [[carries_dependency]] break; // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] switch (i) { // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}} ignored}}
+ [[gnu::nonnull]] case 0: // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] default: // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] break; // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
}
- [[carries_dependency]] goto here; // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] goto here; // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
- [[carries_dependency]] try { // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] try { // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
} catch (...) {
}
- [[carries_dependency]] return; // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
+ [[gnu::nonnull]] return; // expected-error {{'gnu::nonnull' attribute cannot be applied to a statement}}
{
[[ ]] // expected-error {{an attribute list cannot appear here}}
diff --git a/clang/test/Parser/cxx1z-decomposition.cpp b/clang/test/Parser/cxx1z-decomposition.cpp
index 916d4f74b0075..45329b766bc28 100644
--- a/clang/test/Parser/cxx1z-decomposition.cpp
+++ b/clang/test/Parser/cxx1z-decomposition.cpp
@@ -213,7 +213,6 @@ void invalid_attributes() {
// pre2c-warning at +1 {{an attribute specifier sequence attached to a structured binding declaration is a C++2c extension}}
auto [a alignas(42) // expected-error {{'alignas' attribute only applies to variables, data members and tag types}}
[[assume(true), // expected-error {{'assume' attribute cannot be applied to a declaration}}
- carries_dependency, // expected-error {{'carries_dependency' attribute only applies to parameters, Objective-C methods, and functions}}
fallthrough, // expected-error {{'fallthrough' attribute cannot be applied to a declaration}}
likely, // expected-error {{'likely' attribute cannot be applied to a declaration}}
unlikely, // expected-error {{'unlikely' attribute cannot be applied to a declaration}}
diff --git a/clang/test/Parser/stmt-attributes.c b/clang/test/Parser/stmt-attributes.c
index 782e055f6263e..b89714b4e7c74 100644
--- a/clang/test/Parser/stmt-attributes.c
+++ b/clang/test/Parser/stmt-attributes.c
@@ -41,7 +41,7 @@ void foo(int i) {
__attribute__((unused)) switch (i) { // expected-error {{'unused' attribute cannot be applied to a statement}}
__attribute__((uuid)) case 0: // expected-warning {{unknown attribute 'uuid' ignored}}
__attribute__((visibility(""))) default: // expected-error {{'visibility' attribute cannot be applied to a statement}}
- __attribute__((carries_dependency)) break; // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
+ __attribute__((nonnull)) break; // expected-error {{'nonnull' attribute cannot be applied to a statement}}
}
__attribute__((fastcall)) goto there; // expected-error {{'fastcall' attribute cannot be applied to a statement}}
@@ -49,26 +49,26 @@ void foo(int i) {
__attribute__((weakref)) return; // expected-error {{'weakref' attribute only applies to variables and functions}}
- __attribute__((carries_dependency)); // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- __attribute__((carries_dependency)) {} // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- __attribute__((carries_dependency)) if (0) {} // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- __attribute__((carries_dependency)) for (;;); // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- __attribute__((carries_dependency)) do { // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- __attribute__((carries_dependency)) continue; // expected-error {{'carries_dependency' attribute cannot be applied to a statement}} ignored}}
+ __attribute__((nonnull)); // expected-error {{'nonnull' attribute cannot be applied to a statement}}
+ __attribute__((nonnull)) {} // expected-error {{'nonnull' attribute cannot be applied to a statement}}
+ __attribute__((nonnull)) if (0) {} // expected-error {{'nonnull' attribute cannot be applied to a statement}}
+ __attribute__((nonnull)) for (;;); // expected-error {{'nonnull' attribute cannot be applied to a statement}}
+ __attribute__((nonnull)) do { // expected-error {{'nonnull' attribute cannot be applied to a statement}}
+ __attribute__((nonnull)) continue; // expected-error {{'nonnull' attribute cannot be applied to a statement}} ignored}}
}
while (0)
;
- __attribute__((carries_dependency)) while (0); // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
+ __attribute__((nonnull)) while (0); // expected-error {{'nonnull' attribute cannot be applied to a statement}}
- __attribute__((carries_dependency)) switch (i) { // expected-error {{'carries_dependency' attribute cannot be applied to a statement}} ignored}}
- __attribute__((carries_dependency)) case 0: // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- __attribute__((carries_dependency)) default: // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
- __attribute__((carries_dependency)) break; // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
+ __attribute__((nonnull)) switch (i) { // expected-error {{'nonnull' attribute cannot be applied to a statement}} ignored}}
+ __attribute__((nonnull)) case 0: // expected-error {{'nonnull' attribute cannot be applied to a statement}}
+ __attribute__((nonnull)) default: // expected-error {{'nonnull' attribute cannot be applied to a statement}}
+ __attribute__((nonnull)) break; // expected-error {{'nonnull' attribute cannot be applied to a statement}}
}
- __attribute__((carries_dependency)) goto here; // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
+ __attribute__((nonnull)) goto here; // expected-error {{'nonnull' attribute cannot be applied to a statement}}
- __attribute__((carries_dependency)) return; // expected-error {{'carries_dependency' attribute cannot be applied to a statement}}
+ __attribute__((nonnull)) return; // expected-error {{'nonnull' attribute cannot be applied to a statement}}
}
void bar(void);
diff --git a/clang/test/Preprocessor/has_attribute.cpp b/clang/test/Preprocessor/has_attribute.cpp
index 72af6de27e8bb..99a40194ac30d 100644
--- a/clang/test/Preprocessor/has_attribute.cpp
+++ b/clang/test/Preprocessor/has_attribute.cpp
@@ -46,6 +46,7 @@ CXX11(gnu::mips16)
// Test for standard attributes as listed in C++2a [cpp.cond] paragraph 6.
CXX11(assert)
+// carries_dependency was removed from the standard by P3475R2.
CXX11(carries_dependency)
CXX11(deprecated)
CXX11(ensures)
@@ -59,7 +60,7 @@ CXX11(nodiscard)
CXX11(noreturn)
CXX11(unlikely)
// FIXME(201806L) CHECK: assert: 0
-// CHECK: carries_dependency: 200809L
+// CHECK: carries_dependency: 0
// CHECK: deprecated: 201309L
// FIXME(201806L) CHECK: ensures: 0
// FIXME(201806L) CHECK: expects: 0
diff --git a/clang/test/Preprocessor/macro-reserved-attrs-cxx11.cpp b/clang/test/Preprocessor/macro-reserved-attrs-cxx11.cpp
index ab48f1b46df98..ac620ee3c6ca9 100644
--- a/clang/test/Preprocessor/macro-reserved-attrs-cxx11.cpp
+++ b/clang/test/Preprocessor/macro-reserved-attrs-cxx11.cpp
@@ -11,8 +11,9 @@
#define noreturn // expected-warning {{noreturn is a reserved attribute identifier}}
#undef noreturn // expected-warning {{noreturn is a reserved attribute identifier}}
-#define carries_dependency // expected-warning {{carries_dependency is a reserved attribute identifier}}
-#undef carries_dependency // expected-warning {{carries_dependency is a reserved attribute identifier}}
+// carries_dependency was removed from the standard by P3475R2.
+#define carries_dependency
+#undef carries_dependency
#define deprecated // expected-warning {{deprecated is a reserved attribute identifier}}
#undef deprecated // expected-warning {{deprecated is a reserved attribute identifier}}
@@ -43,8 +44,8 @@
#define noreturn "test" // expected-warning {{noreturn is a reserved attribute identifier}}
#undef noreturn // expected-warning {{noreturn is a reserved attribute identifier}}
-#define carries_dependency "test" // expected-warning {{carries_dependency is a reserved attribute identifier}}
-#undef carries_dependency // expected-warning {{carries_dependency is a reserved attribute identifier}}
+#define carries_dependency "test"
+#undef carries_dependency
#define deprecated "test" // expected-warning {{deprecated is a reserved attribute identifier}}
#undef deprecated // expected-warning {{deprecated is a reserved attribute identifier}}
diff --git a/clang/test/SemaCXX/attr-cxx0x.cpp b/clang/test/SemaCXX/attr-cxx0x.cpp
index 5b087be908a1f..4749f06f97c5a 100644
--- a/clang/test/SemaCXX/attr-cxx0x.cpp
+++ b/clang/test/SemaCXX/attr-cxx0x.cpp
@@ -46,7 +46,8 @@ static_assert(alignof(outer<int,char>::inner<double,short>) == alignof(int) * al
static_assert(alignof(int(int)) >= 1, "alignof(function) not positive"); // expected-error{{invalid application of 'alignof' to a function type}}
-[[__carries_dependency__]]
+// carries_dependency was removed from the standard by P3475R2.
+[[__carries_dependency__]] // expected-warning {{unknown attribute 'carries_dependency' ignored}}
void func(void);
alignas(4) auto PR19252 = 0;
diff --git a/clang/test/SemaCXX/cxx2c-attributes.cpp b/clang/test/SemaCXX/cxx2c-attributes.cpp
index c20a1b606a0fd..4a53ff0200bc4 100644
--- a/clang/test/SemaCXX/cxx2c-attributes.cpp
+++ b/clang/test/SemaCXX/cxx2c-attributes.cpp
@@ -6,7 +6,8 @@
// wg21.link/P2552
static_assert(__has_cpp_attribute(assume));
-// The standard does not prescribe a behavior for [[carries_dependency]]
+// [[carries_dependency]] was removed from the standard by P3475R2
+static_assert(!__has_cpp_attribute(carries_dependency));
static_assert(__has_cpp_attribute(deprecated));
static_assert(__has_cpp_attribute(fallthrough));
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index 40b0df3d33258..cdf93dae25757 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -390,7 +390,7 @@ <h2 id="cxx26">C++2c implementation status</h2>
<tr>
<td>Defang and deprecate <code>memory_order::consume</code></td>
<td><a href="https://wg21.link/P3475">P3475R2</a></td>
- <td class="none" align="center">No</td>
+ <td class="full" align="center">Clang 24</td>
</tr>
<tr>
<td>Concept and variable-template template-parameters</td>
@@ -1941,8 +1941,8 @@ <h2 id="cxx11">C++11 implementation status</h2>
</table>
<p>
-<span id="n2761">(1): The <code>[[carries_dependency]]</code> attribute
-has no effect.</span><br>
+<span id="n2761">(1): The <code>[[carries_dependency]]</code> attribute is not
+supported.</span><br>
<span id="n2670">(2): No compiler changes are required for an implementation
such as Clang that does not provide garbage collection.</span><br>
<span id="n2748">(3): All compare-exchange operations are emitted as
>From 5b02b302f2d8472547798cdef6cbea10585907e5 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Mon, 31 Aug 2026 10:38:30 +0200
Subject: [PATCH 2/2] format
---
clang/lib/Sema/SemaDecl.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 577f59a1bd8e9..89e867278decd 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3455,8 +3455,7 @@ static void propagateAttributes(ParmVarDecl *To, const ParmVarDecl *From,
/// mergeParamDeclAttributes - Copy attributes from the old parameter
/// to the new one.
static void mergeParamDeclAttributes(ParmVarDecl *newDecl,
- const ParmVarDecl *oldDecl,
- Sema &S) {
+ const ParmVarDecl *oldDecl, Sema &S) {
propagateAttributes(
newDecl, oldDecl, [&S](ParmVarDecl *To, const ParmVarDecl *From) {
unsigned found = 0;
More information about the cfe-commits
mailing list