| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s | ||
|
|
||
| const int global = 5; // expected-note{{variable 'global' declared const here}} | ||
| void test1() { | ||
| global = 2; // expected-error{{cannot assign to variable 'global' with const-qualified type 'const int'}} | ||
| } | ||
|
|
||
| void test2 () { | ||
| const int local = 5; // expected-note{{variable 'local' declared const here}} | ||
| local = 0; // expected-error{{cannot assign to variable 'local' with const-qualified type 'const int'}} | ||
| } | ||
|
|
||
| void test2 (const int parameter) { // expected-note{{variable 'parameter' declared const here}} | ||
| parameter = 2; // expected-error{{cannot assign to variable 'parameter' with const-qualified type 'const int'}} | ||
| } | ||
|
|
||
| class test3 { | ||
| int field; | ||
| const int const_field = 1; // expected-note 2{{non-static data member 'const_field' declared const here}} | ||
| static const int static_const_field = 1; // expected-note 2{{variable 'static_const_field' declared const here}} | ||
| void test() { | ||
| const_field = 4; // expected-error{{cannot assign to non-static data member 'const_field' with const-qualified type 'const int'}} | ||
| static_const_field = 4; // expected-error{{cannot assign to variable 'static_const_field' with const-qualified type 'const int'}} | ||
| } | ||
| void test_const() const { // expected-note 2{{member function 'test3::test_const' is declared const here}} | ||
| field = 4; // expected-error{{cannot assign to non-static data member within const member function 'test_const'}} | ||
| const_field = 4 ; // expected-error{{cannot assign to non-static data member 'const_field' with const-qualified type 'const int'}} | ||
| static_const_field = 4; // expected-error{{cannot assign to variable 'static_const_field' with const-qualified type 'const int'}} | ||
| } | ||
| }; | ||
|
|
||
| const int &return_const_ref(); // expected-note{{function 'return_const_ref' which returns const-qualified type 'const int &' declared here}} | ||
|
|
||
| void test4() { | ||
| return_const_ref() = 10; // expected-error{{cannot assign to return value because function 'return_const_ref' returns a const value}} | ||
| } | ||
|
|
||
| struct S5 { | ||
| int field; | ||
| const int const_field = 4; // expected-note {{non-static data member 'const_field' declared const here}} | ||
| }; | ||
|
|
||
| void test5() { | ||
| S5 s5; | ||
| s5.field = 5; | ||
| s5.const_field = 5; // expected-error{{cannot assign to non-static data member 'const_field' with const-qualified type 'const int'}} | ||
| } | ||
|
|
||
| struct U1 { | ||
| int a = 5; | ||
| }; | ||
|
|
||
| struct U2 { | ||
| U1 u1; | ||
| }; | ||
|
|
||
| struct U3 { | ||
| const U2 u2 = U2(); // expected-note{{non-static data member 'u2' declared const here}} | ||
| }; | ||
|
|
||
| struct U4 { | ||
| U3 u3; | ||
| }; | ||
|
|
||
| void test6() { | ||
| U4 u4; | ||
| u4.u3.u2.u1.a = 5; // expected-error{{cannot assign to non-static data member 'u2' with const-qualified type 'const U2'}} | ||
| } | ||
|
|
||
| struct A { | ||
| int z; | ||
| }; | ||
| struct B { | ||
| A a; | ||
| }; | ||
| struct C { | ||
| B b; | ||
| C(); | ||
| }; | ||
| const C &getc(); // expected-note{{function 'getc' which returns const-qualified type 'const C &' declared here}} | ||
| void test7() { | ||
| const C c; // expected-note{{variable 'c' declared const here}} | ||
| c.b.a.z = 5; // expected-error{{cannot assign to variable 'c' with const-qualified type 'const C'}} | ||
|
|
||
| getc().b.a.z = 5; // expected-error{{cannot assign to return value because function 'getc' returns a const value}} | ||
| } | ||
|
|
||
| struct D { const int n; }; // expected-note 2{{non-static data member 'n' declared const here}} | ||
| struct E { D *const d = 0; }; | ||
| void test8() { | ||
| extern D *const d; | ||
| d->n = 0; // expected-error{{cannot assign to non-static data member 'n' with const-qualified type 'const int'}} | ||
|
|
||
| E e; | ||
| e.d->n = 0; // expected-error{{cannot assign to non-static data member 'n' with const-qualified type 'const int'}} | ||
| } | ||
|
|
||
| struct F { int n; }; | ||
| struct G { const F *f; }; // expected-note{{non-static data member 'f' declared const here}} | ||
| void test10() { | ||
| const F *f; // expected-note{{variable 'f' declared const here}} | ||
| f->n = 0; // expected-error{{cannot assign to variable 'f' with const-qualified type 'const F *'}} | ||
|
|
||
| G g; | ||
| g.f->n = 0; // expected-error{{cannot assign to non-static data member 'f' with const-qualified type 'const F *'}} | ||
| } | ||
|
|
||
| void test11( | ||
| const int x, // expected-note{{variable 'x' declared const here}} | ||
| const int& y // expected-note{{variable 'y' declared const here}} | ||
| ) { | ||
| x = 5; // expected-error{{cannot assign to variable 'x' with const-qualified type 'const int'}} | ||
| y = 5; // expected-error{{cannot assign to variable 'y' with const-qualified type 'const int &'}} | ||
| } | ||
|
|
||
| struct H { | ||
| const int a = 0; // expected-note{{non-static data member 'a' declared const here}} | ||
| const int &b = a; // expected-note{{non-static data member 'b' declared const here}} | ||
| }; | ||
|
|
||
| void test12(H h) { | ||
| h.a = 1; // expected-error {{cannot assign to non-static data member 'a' with const-qualified type 'const int'}} | ||
| h.b = 2; // expected-error {{cannot assign to non-static data member 'b' with const-qualified type 'const int &'}} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,252 @@ | ||
| // RUN: not %clang_cc1 -fsyntax-only -std=c++11 %s 2>&1 | FileCheck %s | ||
|
|
||
| struct E { | ||
| int num; | ||
| const int Cnum = 0; | ||
| mutable int Mnum; | ||
| static int Snum; | ||
| const static int CSnum; | ||
| }; | ||
|
|
||
| struct D { | ||
| E e; | ||
| const E Ce; | ||
| mutable E Me; | ||
| static E Se; | ||
| const static E CSe; | ||
| E &getE() const; | ||
| const E &getCE() const; | ||
| }; | ||
|
|
||
| struct C { | ||
| D d; | ||
| const D Cd; | ||
| mutable D Md; | ||
| static D Sd; | ||
| const static D CSd; | ||
| D &getD() const; | ||
| const D &getCD() const; | ||
| }; | ||
|
|
||
| struct B { | ||
| C c; | ||
| const C Cc; | ||
| mutable C Mc; | ||
| static C Sc; | ||
| const static C CSc; | ||
| C &getC() const; | ||
| static C &getSC(); | ||
| const C &getCC() const; | ||
| static const C &getSCC(); | ||
| }; | ||
|
|
||
| struct A { | ||
| B b; | ||
| const B Cb; | ||
| mutable B Mb; | ||
| static B Sb; | ||
| const static B CSb; | ||
| B &getB() const; | ||
| static B &getSB(); | ||
| const B &getCB() const; | ||
| static const B &getSCB(); | ||
| }; | ||
|
|
||
| A& getA(); | ||
|
|
||
| // Valid assignment | ||
| void test1(A a, const A Ca) { | ||
| a.b.c.d.e.num = 5; | ||
| a.b.c.d.e.Mnum = 5; | ||
| Ca.b.c.d.e.Mnum = 5; | ||
| a.b.c.d.e.Snum = 5; | ||
| Ca.b.c.d.e.Snum = 5; | ||
| Ca.b.c.Md.e.num = 5; | ||
| Ca.Mb.Cc.d.e.Mnum = 5; | ||
| Ca.Mb.getC().d.e.num = 5; | ||
| Ca.getSB().c.d.e.num = 5; | ||
| a.getSCB().c.d.Me.num = 5; | ||
| Ca.Cb.Cc.Cd.Ce.Snum = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK-NOT: note: | ||
| } | ||
|
|
||
| // One note | ||
| void test2(A a, const A Ca) { | ||
| Ca.b.c.d.e.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Ca' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Ca' | ||
| // CHECK-NOT: note: | ||
|
|
||
| a.Cb.c.d.e.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Cb' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Cb' | ||
| // CHECK-NOT: note: | ||
|
|
||
| a.b.c.Cd.e.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Cd' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Cd' | ||
| // CHECK-NOT: note: | ||
|
|
||
| a.b.c.d.e.CSnum = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'CSnum' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'CSnum' | ||
| // CHECK-NOT: note: | ||
|
|
||
| a.b.c.d.e.Cnum = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Cnum' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Cnum' | ||
| // CHECK-NOT: note: | ||
|
|
||
| a.getCB().c.d.e.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'getCB' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'getCB' | ||
| // CHECK-NOT: note: | ||
|
|
||
| a.getSCB().c.d.e.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'getSCB' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'getSCB' | ||
| // CHECK-NOT: note: | ||
| } | ||
|
|
||
| // Two notes | ||
| void test3(A a, const A Ca) { | ||
|
|
||
| a.getSCB().Cc.d.e.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Cc' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Cc' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'getSCB' | ||
| // CHECK-NOT: note: | ||
|
|
||
| Ca.b.c.Cd.e.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Cd' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Cd' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Ca' | ||
| // CHECK-NOT: note: | ||
|
|
||
| a.getCB().c.Cd.e.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Cd' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Cd' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'getCB' | ||
| // CHECK-NOT: note: | ||
|
|
||
| a.b.getCC().d.e.Cnum = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Cnum' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Cnum' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'getCC' | ||
| // CHECK-NOT: note: | ||
|
|
||
| a.b.c.Cd.Ce.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Ce' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Ce' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Cd' | ||
| // CHECK-NOT: note: | ||
|
|
||
| a.b.CSc.Cd.e.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Cd' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Cd' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'CSc' | ||
| // CHECK-NOT: note: | ||
|
|
||
| a.CSb.c.Cd.e.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Cd' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Cd' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'CSb' | ||
| // CHECK-NOT: note: | ||
| } | ||
|
|
||
| // No errors | ||
| void test4(const A Ca) { | ||
| // Mutable cases | ||
| Ca.Mb.c.d.e.num = 5; | ||
| Ca.CSb.Mc.d.e.num = 5; | ||
| Ca.getCB().Mc.d.e.num = 5; | ||
| Ca.getSCB().Mc.d.e.num = 5; | ||
|
|
||
| // Returning non-const reference | ||
| Ca.getB().c.d.e.num = 5; | ||
| Ca.CSb.getC().d.e.num = 5; | ||
| Ca.getCB().getC().d.e.num = 5; | ||
| Ca.getSCB().getC().d.e.num = 5; | ||
|
|
||
| // Returning non-const reference | ||
| Ca.getSB().c.d.e.num = 5; | ||
| Ca.CSb.getSC().d.e.num = 5; | ||
| Ca.getCB().getSC().d.e.num = 5; | ||
| Ca.getSCB().getSC().d.e.num = 5; | ||
|
|
||
| // Static member | ||
| Ca.Sb.c.d.e.num = 5; | ||
| Ca.CSb.Sc.d.e.num = 5; | ||
| Ca.getCB().Sc.d.e.num = 5; | ||
| Ca.getSCB().Sc.d.e.num = 5; | ||
|
|
||
| // CHECK-NOT: error: | ||
| // CHECK-NOT: note: | ||
| } | ||
|
|
||
| // Only display notes for relavent cases. | ||
| void test5(const A Ca) { | ||
| Ca.Mb.c.d.Ce.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Ce' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Ce' | ||
| // CHECK-NOT: note: | ||
|
|
||
| Ca.getB().c.d.Ce.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Ce' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Ce' | ||
| // CHECK-NOT: note: | ||
|
|
||
| Ca.getSB().c.d.Ce.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Ce' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Ce' | ||
| // CHECK-NOT: note: | ||
|
|
||
| Ca.Sb.c.d.Ce.num = 5; | ||
| // CHECK-NOT: error: | ||
| // CHECK: error:{{.*}} 'Ce' | ||
| // CHECK-NOT: note: | ||
| // CHECK: note:{{.*}} 'Ce' | ||
| // CHECK-NOT: note: | ||
| } |