https://github.com/juanvazquez updated 
https://github.com/llvm/llvm-project/pull/178432

>From 44da13274ff4aca6c9b355f18731b0cb201a780d Mon Sep 17 00:00:00 2001
From: Juan Vazquez <[email protected]>
Date: Wed, 28 Jan 2026 15:09:54 +0100
Subject: [PATCH] [clang] Add clang::default_constructed_after_move attribute

The default_constructed_after_move attribute can be applied to a class to
indicate that, when an object of this type is moved from, it is guaranteed to
be in the same state as a default-constructed object.

This attribute can be interpreted by static analyzers that warn
about potential uses of an object after it is moved. For types
with this attribute, analyzers can assume that accessing a moved object
is as safe as accessing a default-constructed object.

A typical use case is to annotate smart pointer classes, which often guarantee
that a pointer is null, and hence in a default-constructed state, after the
move.

The plan is to use it with clang-tidy's bugprone-use-after-move check next.
---
 clang/include/clang/Basic/Attr.td             |  8 +++++
 clang/include/clang/Basic/AttrDocs.td         | 18 ++++++++++
 .../attr-default-constructed-after-move.cpp   | 35 +++++++++++++++++++
 3 files changed, 61 insertions(+)
 create mode 100644 clang/test/SemaCXX/attr-default-constructed-after-move.cpp

diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 2335168e4510c..9b9c52c14efee 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4799,6 +4799,14 @@ def Reinitializes : InheritableAttr {
   let SimpleHandler = 1;
 }
 
+def DefaultConstructedAfterMove : InheritableAttr {
+  let Spellings = [Clang<"default_constructed_after_move", 0>];
+  let Subjects = SubjectList<[CXXRecord], ErrorDiag>;
+  let Documentation = [DefaultConstructedAfterMoveDocs];
+  let SimpleHandler = 1;
+  let PragmaAttributeSupport = 0;
+}
+
 def NoDestroy : InheritableAttr {
   let Spellings = [Clang<"no_destroy", 0>];
   let Subjects = SubjectList<[Var]>;
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 6e2c73f924352..24c7c872a0d77 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -7152,6 +7152,24 @@ a container class:
   }];
 }
 
+def DefaultConstructedAfterMoveDocs : Documentation {
+  let Category = DocCatType;
+  let Content = [{
+The ``default_constructed_after_move`` attribute can be applied to a class to
+indicate that, when an object of this type is moved from, it is guaranteed to
+be in the same state as a default-constructed object.
+
+This attribute can be interpreted by static analyzers that warn
+about potential uses of an object after it is moved. For types
+with this attribute, analyzers can assume that accessing a moved object
+is as safe as accessing a default-constructed object.
+
+A typical use case is to annotate smart pointer classes, which often guarantee
+that a pointer is null, and hence in a default-constructed state, after the
+move.
+}];
+}
+
 def AlwaysDestroyDocs : Documentation {
   let Category = DocCatVariable;
   let Content = [{
diff --git a/clang/test/SemaCXX/attr-default-constructed-after-move.cpp 
b/clang/test/SemaCXX/attr-default-constructed-after-move.cpp
new file mode 100644
index 0000000000000..2bedf579c0f02
--- /dev/null
+++ b/clang/test/SemaCXX/attr-default-constructed-after-move.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+[[clang::default_constructed_after_move]] int a; // expected-error 
{{'clang::default_constructed_after_move' attribute only applies to classes}}
+
+[[clang::default_constructed_after_move]] void f(); // expected-error {{only 
applies to}}
+
+enum [[clang::default_constructed_after_move]] E { A, B }; // expected-error 
{{only applies to}}
+
+void foo( [[clang::default_constructed_after_move]] int param); // 
expected-error {{only applies to}}
+
+struct MyStruct {
+  [[clang::default_constructed_after_move]] int member; // expected-error 
{{only applies to}}
+};
+
+class [[clang::default_constructed_after_move]] C {
+public:
+  C();
+  C(C &&);
+  C &operator=(C &&);
+};
+
+C [[clang::default_constructed_after_move]] c_var; // expected-error 
{{'clang::default_constructed_after_move' attribute cannot be applied to types}}
+
+struct [[clang::default_constructed_after_move]] S {
+  S();
+  S(S &&);
+  S &operator=(S &&);
+};
+
+union [[clang::default_constructed_after_move]] U {
+  int a;
+  float b;
+  U(U &&);
+  U &operator=(U &&);
+};

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to