tbaeder created this revision. tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik. Herald added a project: All. tbaeder requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This is a c++20 extension as far as I know. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D136751 Files: clang/lib/AST/Interp/Interp.cpp clang/lib/AST/Interp/Pointer.h 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 @@ -113,3 +113,20 @@ // ref-error {{must be initialized by a constant expression}} \ // ref-note {{subobject of type 'int' is not initialized}} }; + +namespace ConstThis { + class Foo { + const int T = 12; // expected-note {{declared const here}} \ + // ref-note {{declared const here}} + int a; + public: + constexpr Foo() { + this->a = 10; + T = 13; // expected-error {{cannot assign to non-static data member 'T' with const-qualified type}} \ + // ref-error {{cannot assign to non-static data member 'T' with const-qualified type}} + } + }; + constexpr Foo F; // expected-error {{must be initialized by a constant expression}} \ + // ref-error {{must be initialized by a constant expression}} + +}; Index: clang/lib/AST/Interp/Pointer.h =================================================================== --- clang/lib/AST/Interp/Pointer.h +++ clang/lib/AST/Interp/Pointer.h @@ -282,6 +282,8 @@ /// Returns the number of elements. unsigned getNumElems() const { return getSize() / elemSize(); } + Block *block() const { return Pointee; } + /// Returns the index into an array. int64_t getIndex() const { if (isElementPastEnd()) Index: clang/lib/AST/Interp/Interp.cpp =================================================================== --- clang/lib/AST/Interp/Interp.cpp +++ clang/lib/AST/Interp/Interp.cpp @@ -261,6 +261,14 @@ return true; } + const Function *Func = S.Current->getFunction(); + if (Func && Func->isConstructor()) { + // The This pointer is writable in constructors, even if + // isConst() returns true. + if (Ptr.block() == S.Current->getThis().block()) + return true; + } + const QualType Ty = Ptr.getType(); const SourceInfo &Loc = S.Current->getSource(OpPC); S.FFDiag(Loc, diag::note_constexpr_modify_const_type) << Ty;
Index: clang/test/AST/Interp/cxx20.cpp =================================================================== --- clang/test/AST/Interp/cxx20.cpp +++ clang/test/AST/Interp/cxx20.cpp @@ -113,3 +113,20 @@ // ref-error {{must be initialized by a constant expression}} \ // ref-note {{subobject of type 'int' is not initialized}} }; + +namespace ConstThis { + class Foo { + const int T = 12; // expected-note {{declared const here}} \ + // ref-note {{declared const here}} + int a; + public: + constexpr Foo() { + this->a = 10; + T = 13; // expected-error {{cannot assign to non-static data member 'T' with const-qualified type}} \ + // ref-error {{cannot assign to non-static data member 'T' with const-qualified type}} + } + }; + constexpr Foo F; // expected-error {{must be initialized by a constant expression}} \ + // ref-error {{must be initialized by a constant expression}} + +}; Index: clang/lib/AST/Interp/Pointer.h =================================================================== --- clang/lib/AST/Interp/Pointer.h +++ clang/lib/AST/Interp/Pointer.h @@ -282,6 +282,8 @@ /// Returns the number of elements. unsigned getNumElems() const { return getSize() / elemSize(); } + Block *block() const { return Pointee; } + /// Returns the index into an array. int64_t getIndex() const { if (isElementPastEnd()) Index: clang/lib/AST/Interp/Interp.cpp =================================================================== --- clang/lib/AST/Interp/Interp.cpp +++ clang/lib/AST/Interp/Interp.cpp @@ -261,6 +261,14 @@ return true; } + const Function *Func = S.Current->getFunction(); + if (Func && Func->isConstructor()) { + // The This pointer is writable in constructors, even if + // isConst() returns true. + if (Ptr.block() == S.Current->getThis().block()) + return true; + } + const QualType Ty = Ptr.getType(); const SourceInfo &Loc = S.Current->getSource(OpPC); S.FFDiag(Loc, diag::note_constexpr_modify_const_type) << Ty;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits