summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaCXX/function-redecl.cpp
blob: 4a5638f84e59fd7879c40c79e9a5f587d4a07431 (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
// RUN: %clang_cc1 -fsyntax-only -verify %s
int foo(int);

namespace N {
  void f1() {
    void foo(int); // okay
  }

  // FIXME: we shouldn't even need this declaration to detect errors
  // below.
  void foo(int); // expected-note{{previous declaration is here}}

  void f2() {
    int foo(int); // expected-error{{functions that differ only in their return type cannot be overloaded}}

    {
      int foo;
      {
        // FIXME: should diagnose this because it's incompatible with
        // N::foo. However, name lookup isn't properly "skipping" the
        // "int foo" above.
        float foo(int); 
      }
    }
  }
}

class A {
 void typocorrection(); // expected-note {{'typocorrection' declared here}}
};

void A::Notypocorrection() { // expected-error {{out-of-line definition of 'Notypocorrection' does not match any declaration in 'A'; did you mean 'typocorrection'}}
}


namespace test0 {
  void dummy() {
    void Bar(); // expected-note {{'Bar' declared here}}
    class A {
      friend void bar(); // expected-error {{no matching function 'bar' found in local scope; did you mean 'Bar'}}
    };
  }
}


class B {
 void typocorrection(const int); // expected-note {{'typocorrection' declared here}}
 void typocorrection(double);
};

void B::Notypocorrection(int) { // expected-error {{out-of-line definition of 'Notypocorrection' does not match any declaration in 'B'; did you mean 'typocorrection'}}
}

struct X { int f(); };
struct Y : public X {};
int Y::f() { return 3; } // expected-error {{out-of-line definition of 'f' does not match any declaration in 'Y'}}

namespace test1 {
struct Foo {
  class Inner { };
};
}

class Bar {
  void f(test1::Foo::Inner foo) const; // expected-note {{member declaration does not match because it is const qualified}}
};

using test1::Foo;

void Bar::f(Foo::Inner foo) { // expected-error {{out-of-line definition of 'f' does not match any declaration in 'Bar'}}
  (void)foo;
}

class Crash {
 public:
  void GetCart(int count) const;
};
// This out-of-line definition was fine...
void Crash::cart(int count) const {} // expected-error {{out-of-line definition of 'cart' does not match any declaration in 'Crash'}}
// ...while this one crashed clang
void Crash::chart(int count) const {} // expected-error {{out-of-line definition of 'chart' does not match any declaration in 'Crash'}}

class TestConst {
 public:
  int getit() const; // expected-note {{member declaration does not match because it is const qualified}}
  void setit(int); // expected-note {{member declaration does not match because it is not const qualified}}
};

int TestConst::getit() { // expected-error {{out-of-line definition of 'getit' does not match any declaration in 'TestConst'}}
  return 1;
}

void TestConst::setit(int) const { // expected-error {{out-of-line definition of 'setit' does not match any declaration in 'TestConst'}}
}

struct J { int typo() const; };
int J::typo_() { return 3; } // expected-error {{out-of-line definition of 'typo_' does not match any declaration in 'J'}}

// Ensure we correct the redecl of Foo::isGood to Bar::Foo::isGood and not
// Foo::IsGood even though Foo::IsGood is technically a closer match since it
// already has a body. Also make sure Foo::beEvil is corrected to Foo::BeEvil
// since it is a closer match than Bar::Foo::beEvil and neither have a body.
namespace redecl_typo {
namespace Foo {
  bool IsGood() { return false; }
  void BeEvil(); // expected-note {{'BeEvil' declared here}}
}
namespace Bar {
  namespace Foo {
    bool isGood(); // expected-note {{'Bar::Foo::isGood' declared here}}
    void beEvil();
  }
}
bool Foo::isGood() { // expected-error {{out-of-line definition of 'isGood' does not match any declaration in namespace 'redecl_typo::Foo'; did you mean 'Bar::Foo::isGood'?}}
  return true;
}
void Foo::beEvil() {} // expected-error {{out-of-line definition of 'beEvil' does not match any declaration in namespace 'redecl_typo::Foo'; did you mean 'BeEvil'?}}
}

namespace test2 {
  extern "C" {
    void f() {
      void test2_g(int); // expected-note {{previous declaration is here}}
    }
  }
}
int test2_g(int); // expected-error {{functions that differ only in their return type cannot be overloaded}}

namespace test3 {
  extern "C" {
    void f() {
      extern int test3_x; // expected-note {{previous definition is here}}
    }
  }
}
float test3_x; // expected-error {{redefinition of 'test3_x' with a different type: 'float' vs 'int'}}
OpenPOWER on IntegriCloud