aboutsummaryrefslogtreecommitdiff
path: root/clang/test/AST/ByteCode
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-07-18 11:20:48 +0200
committerGitHub <noreply@github.com>2025-07-18 11:20:48 +0200
commitb7660a54157fd45e6276acf35176851196f5df71 (patch)
tree0e0256d10f6308907217ee3663493122801617b7 /clang/test/AST/ByteCode
parent3bb4355bb83692d9c859043076db16baa86431e1 (diff)
downloadllvm-b7660a54157fd45e6276acf35176851196f5df71.zip
llvm-b7660a54157fd45e6276acf35176851196f5df71.tar.gz
llvm-b7660a54157fd45e6276acf35176851196f5df71.tar.bz2
[clang][bytecode] Fix const-in-mutable fields (#149286)
For mutable and const fields, we have two bits in InlineDescriptor, which both get inherited down the hierarchy. When a field is both const and mutable, we CAN read from it if it is a mutable-in-const field, but we _can't_ read from it if it is a const-in-mutable field. We need another bit to distinguish the two cases.
Diffstat (limited to 'clang/test/AST/ByteCode')
-rw-r--r--clang/test/AST/ByteCode/mutable.cpp56
1 files changed, 48 insertions, 8 deletions
diff --git a/clang/test/AST/ByteCode/mutable.cpp b/clang/test/AST/ByteCode/mutable.cpp
index aebbea9..35c5a03 100644
--- a/clang/test/AST/ByteCode/mutable.cpp
+++ b/clang/test/AST/ByteCode/mutable.cpp
@@ -1,11 +1,7 @@
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++11 -verify=expected,expected11,both,both11 %s
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++14 -verify=expected,expected14,both %s
-// RUN: %clang_cc1 -std=c++11 -verify=ref,ref11,both,both11 %s
-// RUN: %clang_cc1 -std=c++14 -verify=ref,ref14,both %s
-
-
-
-
+// RUN: %clang_cc1 -std=c++11 -verify=expected,expected11,both,both11 %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++14 -verify=expected,expected14,both %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++11 -verify=ref,ref11,both,both11 %s
+// RUN: %clang_cc1 -std=c++14 -verify=ref,ref14,both %s
namespace Simple {
struct S {
@@ -26,3 +22,47 @@ namespace Simple {
static_assert(s2.a2 == 12, ""); // both11-error {{not an integral constant expression}} \
// both11-note {{initializer of 's2' is not a constant expression}}
}
+#if __cplusplus >= 201402L
+namespace ConstInMutable {
+ class B {
+ public:
+
+ const int f;
+ constexpr B() : f(12) {}
+ };
+ class A {
+ public:
+ mutable B b;
+ constexpr A() = default;
+ };
+ constexpr int constInMutable() {
+ A a;
+
+ int *m = (int*)&a.b.f;
+ *m = 12; // both-note {{modification of object of const-qualified type 'const int' is not allowed in a constant expression}}
+ return 1;
+ }
+ static_assert(constInMutable() == 1, ""); // both-error {{not an integral constant expression}} \
+ // both-note {{in call to}}
+}
+
+namespace MutableInConst {
+ class C {
+ public:
+ mutable int c;
+ constexpr C() : c(50) {}
+ };
+ class D {
+ public:
+ C c;
+ constexpr D() {}
+ };
+ constexpr int mutableInConst() {
+ const D d{};
+ int *m = (int*)&d.c.c;
+ *m = 12;
+ return 1;
+ }
+ static_assert(mutableInConst() == 1, "");
+}
+#endif