aboutsummaryrefslogtreecommitdiff
path: root/clang/test/AST/ByteCode/mutable.cpp
blob: 35c5a0389921e0118977a50e468bd0e41587d1fd (plain)
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