[PATCH] D152548: [Clang][Interp] Diagnose uninitialized ctor of global record arrays
This revision was automatically updated to reflect the committed changes. Closed by commit rGdfb85c3ce09a: [Clang][Interp] Diagnose uninitialized ctor of global record arrays (authored by hazohelet). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D152548/new/ https://reviews.llvm.org/D152548 Files: clang/lib/AST/Interp/ByteCodeExprGen.h clang/lib/AST/Interp/Interp.cpp clang/test/AST/Interp/cxx20.cpp Index: clang/test/AST/Interp/cxx20.cpp === --- clang/test/AST/Interp/cxx20.cpp +++ clang/test/AST/Interp/cxx20.cpp @@ -138,14 +138,43 @@ namespace UninitializedFields { class A { public: -int a; // expected-note 3{{subobject declared here}} \ - // ref-note 3{{subobject declared here}} +int a; // expected-note 4{{subobject declared here}} \ + // ref-note 4{{subobject declared here}} constexpr A() {} }; constexpr A a; // expected-error {{must be initialized by a constant expression}} \ // expected-note {{subobject 'a' is not initialized}} \ // ref-error {{must be initialized by a constant expression}} \ // ref-note {{subobject 'a' is not initialized}} + constexpr A aarr[2]; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{subobject 'a' is not initialized}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{subobject 'a' is not initialized}} + class F { +public: + int f; // expected-note 3{{subobject declared here}} \ + // ref-note 3{{subobject declared here}} + + constexpr F() {} + constexpr F(bool b) { +if (b) + f = 42; + } + }; + + constexpr F foo[2] = {true}; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{subobject 'f' is not initialized}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{subobject 'f' is not initialized}} + constexpr F foo2[3] = {true, false, true}; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{subobject 'f' is not initialized}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{subobject 'f' is not initialized}} + constexpr F foo3[3] = {true, true, F()}; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{subobject 'f' is not initialized}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{subobject 'f' is not initialized}} + class Base { Index: clang/lib/AST/Interp/Interp.cpp === --- clang/lib/AST/Interp/Interp.cpp +++ clang/lib/AST/Interp/Interp.cpp @@ -456,8 +456,11 @@ bool CheckCtorCall(InterpState , CodePtr OpPC, const Pointer ) { assert(!This.isZero()); - const Record *R = This.getRecord(); - return CheckFieldsInitialized(S, OpPC, This, R); + if (const Record *R = This.getRecord()) +return CheckFieldsInitialized(S, OpPC, This, R); + const auto *CAT = + cast(This.getType()->getAsArrayTypeUnsafe()); + return CheckArrayInitialized(S, OpPC, This, CAT); } bool CheckFloatResult(InterpState , CodePtr OpPC, APFloat::opStatus Status) { Index: clang/lib/AST/Interp/ByteCodeExprGen.h === --- clang/lib/AST/Interp/ByteCodeExprGen.h +++ clang/lib/AST/Interp/ByteCodeExprGen.h @@ -166,7 +166,8 @@ if (!visitInitializer(Init)) return false; -if (Init->getType()->isRecordType() && !this->emitCheckGlobalCtor(Init)) +if ((Init->getType()->isArrayType() || Init->getType()->isRecordType()) && +!this->emitCheckGlobalCtor(Init)) return false; return this->emitPopPtr(Init); Index: clang/test/AST/Interp/cxx20.cpp === --- clang/test/AST/Interp/cxx20.cpp +++ clang/test/AST/Interp/cxx20.cpp @@ -138,14 +138,43 @@ namespace UninitializedFields { class A { public: -int a; // expected-note 3{{subobject declared here}} \ - // ref-note 3{{subobject declared here}} +int a; // expected-note 4{{subobject declared here}} \ + // ref-note 4{{subobject declared here}} constexpr A() {} }; constexpr A a; // expected-error {{must be initialized by a constant expression}} \ // expected-note {{subobject 'a' is not
[PATCH] D152548: [Clang][Interp] Diagnose uninitialized ctor of global record arrays
tbaeder accepted this revision. tbaeder added a comment. This revision is now accepted and ready to land. LGTM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D152548/new/ https://reviews.llvm.org/D152548 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D152548: [Clang][Interp] Diagnose uninitialized ctor of global record arrays
hazohelet updated this revision to Diff 532554. hazohelet marked an inline comment as done. hazohelet added a comment. Address comment from @tbaeder - NFC stylistic change in test CHANGES SINCE LAST ACTION https://reviews.llvm.org/D152548/new/ https://reviews.llvm.org/D152548 Files: clang/lib/AST/Interp/ByteCodeExprGen.h clang/lib/AST/Interp/Interp.cpp clang/test/AST/Interp/cxx20.cpp Index: clang/test/AST/Interp/cxx20.cpp === --- clang/test/AST/Interp/cxx20.cpp +++ clang/test/AST/Interp/cxx20.cpp @@ -138,14 +138,43 @@ namespace UninitializedFields { class A { public: -int a; // expected-note 3{{subobject declared here}} \ - // ref-note 3{{subobject declared here}} +int a; // expected-note 4{{subobject declared here}} \ + // ref-note 4{{subobject declared here}} constexpr A() {} }; constexpr A a; // expected-error {{must be initialized by a constant expression}} \ // expected-note {{subobject 'a' is not initialized}} \ // ref-error {{must be initialized by a constant expression}} \ // ref-note {{subobject 'a' is not initialized}} + constexpr A aarr[2]; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{subobject 'a' is not initialized}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{subobject 'a' is not initialized}} + class F { +public: + int f; // expected-note 3{{subobject declared here}} \ + // ref-note 3{{subobject declared here}} + + constexpr F() {} + constexpr F(bool b) { +if (b) + f = 42; + } + }; + + constexpr F foo[2] = {true}; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{subobject 'f' is not initialized}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{subobject 'f' is not initialized}} + constexpr F foo2[3] = {true, false, true}; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{subobject 'f' is not initialized}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{subobject 'f' is not initialized}} + constexpr F foo3[3] = {true, true, F()}; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{subobject 'f' is not initialized}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{subobject 'f' is not initialized}} + class Base { Index: clang/lib/AST/Interp/Interp.cpp === --- clang/lib/AST/Interp/Interp.cpp +++ clang/lib/AST/Interp/Interp.cpp @@ -456,8 +456,11 @@ bool CheckCtorCall(InterpState , CodePtr OpPC, const Pointer ) { assert(!This.isZero()); - const Record *R = This.getRecord(); - return CheckFieldsInitialized(S, OpPC, This, R); + if (const Record *R = This.getRecord()) +return CheckFieldsInitialized(S, OpPC, This, R); + const auto *CAT = + cast(This.getType()->getAsArrayTypeUnsafe()); + return CheckArrayInitialized(S, OpPC, This, CAT); } bool CheckFloatResult(InterpState , CodePtr OpPC, APFloat::opStatus Status) { Index: clang/lib/AST/Interp/ByteCodeExprGen.h === --- clang/lib/AST/Interp/ByteCodeExprGen.h +++ clang/lib/AST/Interp/ByteCodeExprGen.h @@ -166,7 +166,8 @@ if (!visitInitializer(Init)) return false; -if (Init->getType()->isRecordType() && !this->emitCheckGlobalCtor(Init)) +if ((Init->getType()->isArrayType() || Init->getType()->isRecordType()) && +!this->emitCheckGlobalCtor(Init)) return false; return this->emitPopPtr(Init); Index: clang/test/AST/Interp/cxx20.cpp === --- clang/test/AST/Interp/cxx20.cpp +++ clang/test/AST/Interp/cxx20.cpp @@ -138,14 +138,43 @@ namespace UninitializedFields { class A { public: -int a; // expected-note 3{{subobject declared here}} \ - // ref-note 3{{subobject declared here}} +int a; // expected-note 4{{subobject declared here}} \ + // ref-note 4{{subobject declared here}} constexpr A() {} }; constexpr A a; // expected-error {{must be initialized by a constant expression}} \ // expected-note {{subobject 'a' is not initialized}} \ // ref-error {{must be
[PATCH] D152548: [Clang][Interp] Diagnose uninitialized ctor of global record arrays
tbaeder added inline comments. Comment at: clang/test/AST/Interp/cxx20.cpp:177 + // ref-note {{subobject 'f' is not initialized}} + We usually have a space after the `;` and keep the comments aligned on the `//`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D152548/new/ https://reviews.llvm.org/D152548 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D152548: [Clang][Interp] Diagnose uninitialized ctor of global record arrays
hazohelet created this revision. hazohelet added reviewers: aaron.ballman, tbaeder, shafik. Herald added a project: All. hazohelet requested review of this revision. Herald added a project: clang. This patch adds a check for uninitialized subobjects of global variables that are record arrays. e.g. `constexpr Foo f[2];` Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D152548 Files: clang/lib/AST/Interp/ByteCodeExprGen.h clang/lib/AST/Interp/Interp.cpp clang/test/AST/Interp/cxx20.cpp Index: clang/test/AST/Interp/cxx20.cpp === --- clang/test/AST/Interp/cxx20.cpp +++ clang/test/AST/Interp/cxx20.cpp @@ -138,14 +138,43 @@ namespace UninitializedFields { class A { public: -int a; // expected-note 3{{subobject declared here}} \ - // ref-note 3{{subobject declared here}} +int a; // expected-note 4{{subobject declared here}} \ + // ref-note 4{{subobject declared here}} constexpr A() {} }; constexpr A a; // expected-error {{must be initialized by a constant expression}} \ // expected-note {{subobject 'a' is not initialized}} \ // ref-error {{must be initialized by a constant expression}} \ // ref-note {{subobject 'a' is not initialized}} + constexpr A aarr[2]; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{subobject 'a' is not initialized}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{subobject 'a' is not initialized}} + class F { +public: + int f;// expected-note 3{{subobject declared here}} \ +// ref-note 3{{subobject declared here}} + + constexpr F() {} + constexpr F(bool b) { +if (b) + f = 42; + } + }; + + constexpr F foo[2] = {true};// expected-error {{must be initialized by a constant expression}} \ + // expected-note {{subobject 'f' is not initialized}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{subobject 'f' is not initialized}} + constexpr F foo2[3] = {true, false, true};// expected-error {{must be initialized by a constant expression}} \ + // expected-note {{subobject 'f' is not initialized}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{subobject 'f' is not initialized}} + constexpr F foo3[3] = {true, true, F()};// expected-error {{must be initialized by a constant expression}} \ + // expected-note {{subobject 'f' is not initialized}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{subobject 'f' is not initialized}} + class Base { Index: clang/lib/AST/Interp/Interp.cpp === --- clang/lib/AST/Interp/Interp.cpp +++ clang/lib/AST/Interp/Interp.cpp @@ -455,8 +455,11 @@ bool CheckCtorCall(InterpState , CodePtr OpPC, const Pointer ) { assert(!This.isZero()); - const Record *R = This.getRecord(); - return CheckFieldsInitialized(S, OpPC, This, R); + if (const Record *R = This.getRecord()) +return CheckFieldsInitialized(S, OpPC, This, R); + const auto *CAT = + cast(This.getType()->getAsArrayTypeUnsafe()); + return CheckArrayInitialized(S, OpPC, This, CAT); } bool CheckFloatResult(InterpState , CodePtr OpPC, APFloat::opStatus Status) { Index: clang/lib/AST/Interp/ByteCodeExprGen.h === --- clang/lib/AST/Interp/ByteCodeExprGen.h +++ clang/lib/AST/Interp/ByteCodeExprGen.h @@ -164,7 +164,8 @@ if (!visitInitializer(Init)) return false; -if (Init->getType()->isRecordType() && !this->emitCheckGlobalCtor(Init)) +if ((Init->getType()->isArrayType() || Init->getType()->isRecordType()) && +!this->emitCheckGlobalCtor(Init)) return false; return this->emitPopPtr(Init); Index: clang/test/AST/Interp/cxx20.cpp === --- clang/test/AST/Interp/cxx20.cpp +++ clang/test/AST/Interp/cxx20.cpp @@ -138,14 +138,43 @@ namespace UninitializedFields { class A { public: -int a; // expected-note 3{{subobject declared here}} \ - // ref-note 3{{subobject declared here}} +int a; // expected-note 4{{subobject declared here}} \ + // ref-note 4{{subobject declared here}} constexpr A() {} }; constexpr A a; // expected-error {{must be initialized by a constant expression}} \ // expected-note {{subobject 'a' is not initialized}} \ // ref-error {{must be initialized by a constant expression}} \ //