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

Reply via email to