diff options
author | Timm Baeder <tbaeder@redhat.com> | 2025-07-18 11:20:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-18 11:20:48 +0200 |
commit | b7660a54157fd45e6276acf35176851196f5df71 (patch) | |
tree | 0e0256d10f6308907217ee3663493122801617b7 /clang/test/AST/ByteCode | |
parent | 3bb4355bb83692d9c859043076db16baa86431e1 (diff) | |
download | llvm-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.cpp | 56 |
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 |