1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
// 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 {
mutable int a; // both-note {{declared here}} \
// both11-note {{declared here}}
int a2;
};
constexpr S s{12, 24};
static_assert(s.a == 12, ""); // both-error {{not an integral constant expression}} \
// both-note {{read of mutable member 'a'}}
static_assert(s.a2 == 24, "");
constexpr S s2{12, s2.a}; // both11-error {{must be initialized by a constant expression}} \
// both11-note {{read of mutable member 'a'}} \
// both11-note {{declared here}}
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
|