aboutsummaryrefslogtreecommitdiff
path: root/clang/test/SemaCXX/attr-annotate.cpp
blob: 6f5ba7919927f4298ab0481558eb58a188cf68d0 (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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// RUN: %clang_cc1 -std=gnu++20 -fsyntax-only -verify %s

template<bool If, typename Type>
struct enable_if {
  using type= Type;
};

template<typename Type>
struct enable_if<false, Type> {};

template<typename T1, typename T2>
struct is_same {
  static constexpr bool value = false;
};

template<typename T1>
struct is_same<T1, T1> {
  static constexpr bool value = true;
};

constexpr const char *str() {
  return "abc";
}

template<typename T, typename enable_if<!is_same<int, T>::value, int>::type = 0>
constexpr T fail_on_int(T t) {return t;}
// expected-note@-1 {{candidate template ignored: requirement}}

namespace test0 {
  template<typename T, T v>
  struct A {
    [[clang::annotate("test", fail_on_int(v))]] void t() {}
    // expected-error@-1 {{no matching function for call to 'fail_on_int'}}
    [[clang::annotate("test", (typename enable_if<!is_same<long, T>::value, int>::type)v)]] void t1() {}
    // expected-error@-1 {{failed requirement}}
  };
  A<int, 9> a;
// expected-note@-1 {{in instantiation of template class}}
  A<long, 7> a1;
// expected-note@-1 {{in instantiation of template class}}
  A<unsigned long, 6> a2;

  template<typename T>
  struct B {
    [[clang::annotate("test", ((void)T{}, 9))]] void t() {}
    // expected-error@-1 {{cannot create object of function type 'void ()'}}
  };
  B<int> b;
  B<void ()> b1;
// expected-note@-1 {{in instantiation of template class}}
}

namespace test1 {
int g_i; // expected-note {{declared here}}

[[clang::annotate("test", "arg")]] void t3() {}

template <typename T, T V>
struct B {
  static T b; // expected-note {{declared here}}
  static constexpr T cb = V;
  template <typename T1, T1 V1>
  struct foo {
    static T1 f; // expected-note {{declared here}}
    static constexpr T1 cf = V1;
    int v __attribute__((annotate("v_ann_0", str(), 90, V, g_i))) __attribute__((annotate("v_ann_1", V1)));
    // expected-error@-1 {{'annotate' attribute requires parameter 4 to be a constant expression}}
    // expected-note@-2 {{is not allowed in a constant expression}}
    [[clang::annotate("qdwqwd", cf, cb)]] void t() {}
    [[clang::annotate("qdwqwd", f, cb)]] void t1() {}
    // expected-error@-1 {{'clang::annotate' attribute requires parameter 1 to be a constant expression}}
    // expected-note@-2 {{is not allowed in a constant expression}}
    [[clang::annotate("jui", b, cf)]] void t2() {}
    // expected-error@-1 {{'clang::annotate' attribute requires parameter 1 to be a constant expression}}
    // expected-note@-2 {{is not allowed in a constant expression}}
    [[clang::annotate("jui", ((void)b, 0), cf)]] [[clang::annotate("jui", &b, cf, &foo::t2, str())]] void t3() {}
  };
};

static B<int long, -1>::foo<unsigned, 9> gf; // expected-note {{in instantiation of}}
static B<int long, -2> gf1;

} // namespace test1

namespace test2 {

template<int I>
int f() {
  [[clang::annotate("test", I)]] int v = 0; // expected-note {{declared here}}
  [[clang::annotate("test", v)]] int v2 = 0;
  // expected-error@-1 {{'clang::annotate' attribute requires parameter 1 to be a constant expression}}
  // expected-note@-2 {{is not allowed in a constant expression}}
  [[clang::annotate("test", rtyui)]] int v3 = 0;
    // expected-error@-1 {{use of undeclared identifier 'rtyui'}}
}

void test() {}
}

namespace test3 {

void f() {
  int n = 10;
  int vla[n];

  [[clang::annotate("vlas are awful", sizeof(vla))]] int i = 0; // reject, the sizeof is not unevaluated
  // expected-error@-1 {{'clang::annotate' attribute requires parameter 1 to be a constant expression}}
  // expected-note@-2 {{subexpression not valid in a constant expression}}
  [[clang::annotate("_Generic selection expression should be fine", _Generic(n, int : 0, default : 1))]]
  int j = 0; // second arg should resolve to 0 fine
}
void designator();
[[clang::annotate("function designators?", designator)]] int k = 0; // Should work?

void self() {
  [[clang::annotate("function designators?", self)]] int k = 0;
}

}

namespace test4 {
constexpr int foldable_but_invalid() {
  int *A = new int(0);
// expected-note@-1 {{allocation performed here was not deallocated}}
  return *A;
}

[[clang::annotate("", foldable_but_invalid())]] void f1() {}
// expected-error@-1 {{'clang::annotate' attribute requires parameter 1 to be a constant expression}}

[[clang::annotate()]] void f2() {}
// expected-error@-1 {{'clang::annotate' attribute takes at least 1 argument}}

template <typename T> [[clang::annotate()]] void f2() {}
// expected-error@-1 {{'clang::annotate' attribute takes at least 1 argument}}
}

namespace test5 {
  void bir [[clang::annotate("B", (void)1)]] ();
}