summaryrefslogtreecommitdiffstats
path: root/build/clang-plugin/tests/TestNonTrivialTypeInFfi.cpp
blob: e491122b991a2b73a75b32b8e44f7450684017e4 (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
// clang warns for some of these on its own, but we're not testing that, plus
// some of them (TrivialT<int>) is a false positive (clang doesn't realize the
// type is fully specialized below).
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"

struct Opaque;
struct Trivial {
  int foo;
  char bar;
  Opaque* baz;
};

template <typename T>
struct TrivialT {
  int foo;
  char bar;
  T* baz;
};

struct NonTrivial {
  ~NonTrivial() {
  }

  Opaque* ptr;
};

template <typename T>
struct NonTrivialT {
  ~NonTrivialT() {
    delete ptr;
  }

  T* ptr;
};

struct TransitivelyNonTrivial {
  NonTrivial nontrivial;
};

extern "C" void Foo();
extern "C" Trivial Foo1();
extern "C" NonTrivial Foo2(); // expected-error {{Type 'NonTrivial' must not be used as return type of extern "C" function}} expected-note {{Please consider using a pointer or reference instead}}
extern "C" NonTrivialT<int> Foo3(); // expected-error {{Type 'NonTrivialT<int>' must not be used as return type of extern "C" function}} expected-note {{Please consider using a pointer or reference, or explicitly instantiating the template instead}}
extern "C" NonTrivialT<float> Foo4(); // expected-error {{Type 'NonTrivialT<float>' must not be used as return type of extern "C" function}} expected-note {{Please consider using a pointer or reference, or explicitly instantiating the template instead}}

extern "C" NonTrivial* Foo5();

extern "C" TrivialT<int> Foo6();
extern "C" TrivialT<float> Foo7(); // expected-error {{Type 'TrivialT<float>' must not be used as return type of extern "C" function}} expected-note {{Please consider using a pointer or reference, or explicitly instantiating the template instead}}
extern "C" Trivial* Foo8();

extern "C" void Foo9(Trivial);
extern "C" void Foo10(NonTrivial); // expected-error {{Type 'NonTrivial' must not be used as parameter to extern "C" function}} expected-note {{Please consider using a pointer or reference instead}}
extern "C" void Foo11(NonTrivial*);
extern "C" void Foo12(NonTrivialT<int>); // expected-error {{Type 'NonTrivialT<int>' must not be used as parameter to extern "C" function}} expected-note {{Please consider using a pointer or reference, or explicitly instantiating the template instead}}
extern "C" void Foo13(TrivialT<int>);
extern "C" void Foo14(TrivialT<float>); // expected-error {{Type 'TrivialT<float>' must not be used as parameter to extern "C" function}} expected-note {{Please consider using a pointer or reference, or explicitly instantiating the template instead}}

extern "C" TransitivelyNonTrivial Foo15(); // expected-error {{Type 'TransitivelyNonTrivial' must not be used as return type of extern "C" function}} expected-note {{Please consider using a pointer or reference instead}}
extern "C" void Foo16(TransitivelyNonTrivial); // expected-error {{Type 'TransitivelyNonTrivial' must not be used as parameter to extern "C" function}} expected-note {{Please consider using a pointer or reference instead}}

template struct TrivialT<int>;

#pragma GCC diagnostic pop