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
