blob: 0c334bf9faa51fa807e43039405cfdb5ef2bfa9e [file] [log] [blame]
Douglas Gregor2f639b92008-10-24 15:36:09 +00001// RUN: clang -fsyntax-only -verify %s
2
Sebastian Redlf20269b2009-01-26 22:19:12 +00003struct A {};
4
Douglas Gregor2f639b92008-10-24 15:36:09 +00005// See if aliasing can confuse this baby.
6typedef char c;
7typedef c *cp;
8typedef cp *cpp;
9typedef cpp *cppp;
10typedef cppp &cpppr;
11typedef const cppp &cpppcr;
12typedef const char cc;
13typedef cc *ccp;
14typedef volatile ccp ccvp;
15typedef ccvp *ccvpp;
16typedef const volatile ccvpp ccvpcvp;
17typedef ccvpcvp *ccvpcvpp;
18typedef int iar[100];
19typedef iar &iarr;
20typedef int (*f)(int);
21
22char ***good_const_cast_test(ccvpcvpp var)
23{
24 // Cast away deep consts and volatiles.
25 char ***var2 = const_cast<cppp>(var);
Sebastian Redl2a72f7b2008-10-29 19:45:21 +000026 char ***const &var3 = var2;
Douglas Gregor2f639b92008-10-24 15:36:09 +000027 // Const reference to reference.
28 char ***&var4 = const_cast<cpppr>(var3);
29 // Drop reference. Intentionally without qualifier change.
30 char *** var5 = const_cast<cppp>(var4);
31 const int ar[100] = {0};
Douglas Gregor3eb1c542008-12-17 16:19:15 +000032 int (&rar)[100] = const_cast<iarr>(ar); // expected-error {{const_cast from 'int const [100]' to 'iarr' is not allowed}}
Douglas Gregor2f639b92008-10-24 15:36:09 +000033 // Array decay. Intentionally without qualifier change.
34 int *pi = const_cast<int*>(ar);
35 f fp = 0;
36 // Don't misidentify fn** as a function pointer.
37 f *fpp = const_cast<f*>(&fp);
Sebastian Redlf20269b2009-01-26 22:19:12 +000038 int const A::* const A::*icapcap = 0;
39 int A::* A::* iapap = const_cast<int A::* A::*>(icapcap);
40
Douglas Gregor2f639b92008-10-24 15:36:09 +000041 return var4;
42}
43
44short *bad_const_cast_test(char const *volatile *const volatile *var)
45{
46 // Different pointer levels.
47 char **var2 = const_cast<char**>(var); // expected-error {{const_cast from 'char const *volatile *const volatile *' to 'char **' is not allowed}}
48 // Different final type.
49 short ***var3 = const_cast<short***>(var); // expected-error {{const_cast from 'char const *volatile *const volatile *' to 'short ***' is not allowed}}
50 // Rvalue to reference.
51 char ***&var4 = const_cast<cpppr>(&var2); // expected-error {{const_cast from rvalue to reference type 'cpppr'}}
52 // Non-pointer.
53 char v = const_cast<char>(**var2); // expected-error {{const_cast to 'char', which is not a reference, pointer-to-object, or pointer-to-data-member}}
54 const int *ar[100] = {0};
55 // Not even lenient g++ accepts this.
56 int *(*rar)[100] = const_cast<int *(*)[100]>(&ar); // expected-error {{const_cast from 'int const *(*)[100]' to 'int *(*)[100]' is not allowed}}
57 f fp1 = 0;
58 // Function pointers.
59 f fp2 = const_cast<f>(fp1); // expected-error {{const_cast to 'f', which is not a reference, pointer-to-object, or pointer-to-data-member}}
Sebastian Redlf20269b2009-01-26 22:19:12 +000060 void (A::*mfn)() = 0;
61 (void)const_cast<void (A::*)()>(mfn); // expected-error {{const_cast to 'void (struct A::*)(void)', which is not a reference, pointer-to-object, or pointer-to-data-member}}
Douglas Gregor2f639b92008-10-24 15:36:09 +000062 return **var3;
63}