const-cast.cpp revision 9dd88c7a8d2b666c5648d248d1a25606115dc5ef
1// RUN: clang -fsyntax-only -verify %s
2
3// See if aliasing can confuse this baby.
4typedef char c;
5typedef c *cp;
6typedef cp *cpp;
7typedef cpp *cppp;
8typedef cppp &cpppr;
9typedef const cppp &cpppcr;
10typedef const char cc;
11typedef cc *ccp;
12typedef volatile ccp ccvp;
13typedef ccvp *ccvpp;
14typedef const volatile ccvpp ccvpcvp;
15typedef ccvpcvp *ccvpcvpp;
16typedef int iar[100];
17typedef iar &iarr;
18typedef int (*f)(int);
19
20char ***good_const_cast_test(ccvpcvpp var)
21{
22  // Cast away deep consts and volatiles.
23  char ***var2 = const_cast<cppp>(var);
24  char ***const &var3 = var2;
25  // Const reference to reference.
26  char ***&var4 = const_cast<cpppr>(var3);
27  // Drop reference. Intentionally without qualifier change.
28  char *** var5 = const_cast<cppp>(var4);
29  const int ar[100] = {0};
30  int (&rar)[100] = const_cast<iarr>(ar); // expected-error {{const_cast from 'int const [100]' to 'iarr' is not allowed}}
31  // Array decay. Intentionally without qualifier change.
32  int *pi = const_cast<int*>(ar);
33  f fp = 0;
34  // Don't misidentify fn** as a function pointer.
35  f *fpp = const_cast<f*>(&fp);
36  return var4;
37}
38
39short *bad_const_cast_test(char const *volatile *const volatile *var)
40{
41  // Different pointer levels.
42  char **var2 = const_cast<char**>(var); // expected-error {{const_cast from 'char const *volatile *const volatile *' to 'char **' is not allowed}}
43  // Different final type.
44  short ***var3 = const_cast<short***>(var); // expected-error {{const_cast from 'char const *volatile *const volatile *' to 'short ***' is not allowed}}
45  // Rvalue to reference.
46  char ***&var4 = const_cast<cpppr>(&var2); // expected-error {{const_cast from rvalue to reference type 'cpppr'}}
47  // Non-pointer.
48  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}}
49  const int *ar[100] = {0};
50  // Not even lenient g++ accepts this.
51  int *(*rar)[100] = const_cast<int *(*)[100]>(&ar); // expected-error {{const_cast from 'int const *(*)[100]' to 'int *(*)[100]' is not allowed}}
52  f fp1 = 0;
53  // Function pointers.
54  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}}
55  return **var3;
56}
57