[clang] Add Clang attribute to ensure that fields are initialized explicitly (PR #102040)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 25 03:04:31 PST 2024
================
@@ -1472,3 +1472,144 @@ template<typename T> struct Outer {
};
};
Outer<int>::Inner outerinner;
+
+struct Polymorphic { virtual ~Polymorphic() { } };
+
+template<class... Bases>
+struct Inherit : Bases... { // #TYPE_INHERIT
+ int g1; // #FIELD_G1
+};
+
+template<class... Bases>
+struct InheritWithExplicit : Bases... { // #TYPE_INHERIT_WITH_EXPLICIT
+ int g2 [[clang::requires_explicit_initialization]]; // #FIELD_G2
+};
+
+struct Special {};
+
+template<>
+struct Inherit<Special> {
+ int g3 [[clang::requires_explicit_initialization]]; // #FIELD_G3
+};
+
+template<>
+struct InheritWithExplicit<Special> {
+ int g4; // #FIELD_G4
+};
+
+void aggregate() {
+ struct NonAgg {
+ NonAgg() { }
+ [[clang::requires_explicit_initialization]] int na; // expected-warning {{'requires_explicit_initialization' attribute is ignored in non-aggregate type 'NonAgg'}}
+ };
+ NonAgg nonagg; // no-warning
+ (void)nonagg;
+
+ struct S {
+ [[clang::requires_explicit_initialization]] int s1; // #FIELD_S1
+ int s2;
+ int s3 = 12;
+ [[clang::requires_explicit_initialization]] int s4 = 100; // #FIELD_S4
+ static void foo(S) { }
+ };
+
+ struct C {
+ [[clang::requires_explicit_initialization]] int c1; // #FIELD_C1
+#if 201703L <= __cplusplus && __cplusplus < 202002L
+ // expected-warning@#FIELD_C1 {{explicit initialization of field 'c1' will not be enforced in C++20 and later because 'C' has a user-declared constructor, making the type no longer an aggregate}}
+#endif
+ C() = default; // Test pre-C++20 aggregates
+ };
+
+ struct D : S { // #TYPE_D
+ int d1;
+ int d2 [[clang::requires_explicit_initialization]]; // #FIELD_D2
+ };
+
+ struct D2 : D { // #TYPE_D2
+ };
+
+ struct E { // #TYPE_E
+ int e1;
+ D e2 [[clang::requires_explicit_initialization]]; // #FIELD_E2
+ struct {
+ [[clang::requires_explicit_initialization]] D e3;
+ D2 e4 [[clang::requires_explicit_initialization]];
+ };
+ };
+
+ S::foo(S{1, 2, 3, 4});
+ S::foo(S{.s1 = 100, .s4 = 100});
+ S::foo(S{.s1 = 100}); // expected-warning {{field 's4' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_S4 {{'s4' declared here}}
+
+ S s{.s1 = 100, .s4 = 100};
+ (void)s;
+
+ S t{.s4 = 100}; // expected-warning {{field 's1' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_S1 {{'s1' declared here}}
+ (void)t;
+
+ S *ptr1 = new S; // expected-warning {{field in 'S' requires explicit initialization but is not explicitly initialized}} expected-note@#FIELD_S4 {{'s4' declared here}} expected-note@#FIELD_S1 {{'s1' declared here}}
+ delete ptr1;
+
+ S *ptr2 = new S{.s1 = 100, .s4 = 100};
+ delete ptr2;
+
+#if __cplusplus >= 202002L
----------------
higher-performance wrote:
Done.
https://github.com/llvm/llvm-project/pull/102040
More information about the cfe-commits
mailing list