lebedev.ri added a comment. In https://reviews.llvm.org/D33102#773296, @dblaikie wrote:
> I still feel like that's more testing than would be ideal (does the context > of the cast matter? Wether it's dereferenced, a struct member access, > assigned, initialized, etc - it doesn't look like it from the code, etc). Looking at the `CastsAwayConstness()` function in lib/Sema/SemaCast.cpp: https://github.com/llvm-mirror/clang/blob/432ed0e4a6d58f7dda8992a167aad43bc91f76c6/lib/Sema/SemaCast.cpp#L505-L510 You can see that it asserts that the pointer is one of three types. So i think it it is best to have maybe slightly overlapping test coverage here, rather than be surprised one day that such trivial cases no longer warn... > But sure. Could you also (manually, I guess) confirm that this matches GCC's > cast-qual behavior (insofar as the warning fires in the same situations). If > there are any deviations, let's chat about them. Sure. 1. Gcc produces the same //count// of the warnings: $ pwd llvm/tools/clang/test $ grep -o "expected-warning" Sema/warn-cast-qual.c | wc -l 14 $ gcc -x c -fsyntax-only -Wcast-qual -c Sema/warn-cast-qual.c 2>&1 | grep ": warning: " | wc -l 14 $ gcc -x c++ -fsyntax-only -Wcast-qual -c Sema/warn-cast-qual.c 2>&1 | grep ": warning: " | wc -l 14 $ grep -o "expected-warning" SemaCXX/warn-cast-qual.cpp | wc -l 39 $ gcc -x c++ -fsyntax-only -Wcast-qual -c SemaCXX/warn-cast-qual.cpp 2>&1 | grep ": warning: " | wc -l 39 2. I'm not quite sure how to non-manually compare the warnings, so i'll just show the gcc output on these three cases. Since the clang warnings are appended as comments at the end of the each line that should warn, visual comparison is possible: 2.1. $ gcc -x c -fsyntax-only -Wcast-qual -c Sema/warn-cast-qual.c Sema/warn-cast-qual.c: In function ‘foo’: Sema/warn-cast-qual.c:9:13: warning: cast discards ‘const’ qualifier from pointer target type [-Wcast-qual] char *y = (char *)ptr; // expected-warning {{cast from 'const char *' to 'char *' drops const qualifier}} ^ Sema/warn-cast-qual.c:10:15: warning: cast discards ‘const’ qualifier from pointer target type [-Wcast-qual] char **y1 = (char **)ptrptr; // expected-warning {{cast from 'const char *const' to 'char *' drops const qualifier}} ^ Sema/warn-cast-qual.c:11:21: warning: cast discards ‘const’ qualifier from pointer target type [-Wcast-qual] const char **y2 = (const char **)ptrptr; // expected-warning {{cast from 'const char *const *' to 'const char **' drops const qualifier}} ^ Sema/warn-cast-qual.c:14:14: warning: cast discards ‘const’ qualifier from pointer target type [-Wcast-qual] char *z1 = (char *)(const void *)ptr; // expected-warning {{cast from 'const void *' to 'char *' drops const qualifier}} ^ Sema/warn-cast-qual.c:17:16: warning: cast discards ‘volatile’ qualifier from pointer target type [-Wcast-qual] char *vol2 = (char *)vol; // expected-warning {{cast from 'volatile char *' to 'char *' drops volatile qualifier}} ^ Sema/warn-cast-qual.c:19:17: warning: cast discards ‘const volatile’ qualifier from pointer target type [-Wcast-qual] char *volc2 = (char *)volc; // expected-warning {{cast from 'const volatile char *' to 'char *' drops const and volatile qualifiers}} ^ Sema/warn-cast-qual.c:22:28: warning: to be safe all intermediate pointers in cast from ‘int **’ to ‘const int **’ must be ‘const’ qualified [-Wcast-qual] const int **intptrptrc = (const int **)intptrptr; // expected-warning {{cast from 'int **' to 'const int **' must have all intermediate pointers const qualified}} ^ Sema/warn-cast-qual.c:23:31: warning: to be safe all intermediate pointers in cast from ‘int **’ to ‘volatile int **’ must be ‘const’ qualified [-Wcast-qual] volatile int **intptrptrv = (volatile int **)intptrptr; // expected-warning {{cast from 'int **' to 'volatile int **' must have all intermediate pointers const qualified}} ^ Sema/warn-cast-qual.c:29:23: warning: cast discards ‘const’ qualifier from pointer target type [-Wcast-qual] char **charptrptr = (char **)charptrptrc; // expected-warning {{cast from 'const char *' to 'char *' drops const qualifier}} ^ Sema/warn-cast-qual.c:32:19: warning: cast discards ‘const’ qualifier from pointer target type [-Wcast-qual] char *charptr = (char *)constcharptr; // expected-warning {{cast from 'const char *' to 'char *' drops const qualifier}} ^ Sema/warn-cast-qual.c:33:31: warning: cast discards ‘const’ qualifier from pointer target type [-Wcast-qual] const char *constcharptr2 = (char *)constcharptr; // expected-warning {{cast from 'const char *' to 'char *' drops const qualifier}} ^ Sema/warn-cast-qual.c: In function ‘bar_0’: Sema/warn-cast-qual.c:45:4: warning: cast discards ‘const’ qualifier from pointer target type [-Wcast-qual] *(int *)(&S.a) = 0; // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ Sema/warn-cast-qual.c:46:4: warning: cast discards ‘const’ qualifier from pointer target type [-Wcast-qual] *(int *)(&S.b) = 0; // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ Sema/warn-cast-qual.c: In function ‘bar_1’: Sema/warn-cast-qual.c:58:4: warning: cast discards ‘const’ qualifier from pointer target type [-Wcast-qual] *(int *)(&S.a) = 0; // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ One thing to note: Sema/warn-cast-qual.c:23:31: warning: to be safe all intermediate pointers in cast from ‘int **’ to ‘volatile int **’ must be ‘const’ qualified [-Wcast-qual] volatile int **intptrptrv = (volatile int **)intptrptr; // expected-warning {{cast from 'int **' to 'volatile int **' must have all intermediate pointers const qualified}} ^ ^ both compilers talk about `const qualified`, even though the `volatile` is dropped. 2.2. $ gcc -x c++ -fsyntax-only -Wcast-qual -c Sema/warn-cast-qual.c Sema/warn-cast-qual.c: In function ‘void foo()’: Sema/warn-cast-qual.c:9:21: warning: cast from type ‘const char* const’ to type ‘char*’ casts away qualifiers [-Wcast-qual] char *y = (char *)ptr; // expected-warning {{cast from 'const char *' to 'char *' drops const qualifier}} ^~~ Sema/warn-cast-qual.c:10:24: warning: cast from type ‘const char* const*’ to type ‘char**’ casts away qualifiers [-Wcast-qual] char **y1 = (char **)ptrptr; // expected-warning {{cast from 'const char *const' to 'char *' drops const qualifier}} ^~~~~~ Sema/warn-cast-qual.c:11:36: warning: cast from type ‘const char* const*’ to type ‘const char**’ casts away qualifiers [-Wcast-qual] const char **y2 = (const char **)ptrptr; // expected-warning {{cast from 'const char *const *' to 'const char **' drops const qualifier}} ^~~~~~ Sema/warn-cast-qual.c:14:36: warning: cast from type ‘const void*’ to type ‘char*’ casts away qualifiers [-Wcast-qual] char *z1 = (char *)(const void *)ptr; // expected-warning {{cast from 'const void *' to 'char *' drops const qualifier}} ^~~ Sema/warn-cast-qual.c:17:24: warning: cast from type ‘volatile char*’ to type ‘char*’ casts away qualifiers [-Wcast-qual] char *vol2 = (char *)vol; // expected-warning {{cast from 'volatile char *' to 'char *' drops volatile qualifier}} ^~~ Sema/warn-cast-qual.c:19:25: warning: cast from type ‘const volatile char*’ to type ‘char*’ casts away qualifiers [-Wcast-qual] char *volc2 = (char *)volc; // expected-warning {{cast from 'const volatile char *' to 'char *' drops const and volatile qualifiers}} ^~~~ Sema/warn-cast-qual.c:22:42: warning: cast from type ‘int**’ to type ‘const int**’ casts away qualifiers [-Wcast-qual] const int **intptrptrc = (const int **)intptrptr; // expected-warning {{cast from 'int **' to 'const int **' must have all intermediate pointers const qualified}} ^~~~~~~~~ Sema/warn-cast-qual.c:23:48: warning: cast from type ‘int**’ to type ‘volatile int**’ casts away qualifiers [-Wcast-qual] volatile int **intptrptrv = (volatile int **)intptrptr; // expected-warning {{cast from 'int **' to 'volatile int **' must have all intermediate pointers const qualified}} ^~~~~~~~~ Sema/warn-cast-qual.c:29:32: warning: cast from type ‘const char**’ to type ‘char**’ casts away qualifiers [-Wcast-qual] char **charptrptr = (char **)charptrptrc; // expected-warning {{cast from 'const char *' to 'char *' drops const qualifier}} ^~~~~~~~~~~ Sema/warn-cast-qual.c:32:27: warning: cast from type ‘const char*’ to type ‘char*’ casts away qualifiers [-Wcast-qual] char *charptr = (char *)constcharptr; // expected-warning {{cast from 'const char *' to 'char *' drops const qualifier}} ^~~~~~~~~~~~ Sema/warn-cast-qual.c:33:39: warning: cast from type ‘const char*’ to type ‘char*’ casts away qualifiers [-Wcast-qual] const char *constcharptr2 = (char *)constcharptr; // expected-warning {{cast from 'const char *' to 'char *' drops const qualifier}} ^~~~~~~~~~~~ Sema/warn-cast-qual.c: In function ‘void bar_0()’: Sema/warn-cast-qual.c:45:16: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] *(int *)(&S.a) = 0; // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ Sema/warn-cast-qual.c:46:16: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] *(int *)(&S.b) = 0; // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ Sema/warn-cast-qual.c: In function ‘void bar_1()’: Sema/warn-cast-qual.c:58:16: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] *(int *)(&S.a) = 0; // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ 2.3. And here are the C++ reference warnings. As you can see, gcc warnings are rather broken i'd say... $ gcc -x c++ -fsyntax-only -Wcast-qual -c SemaCXX/warn-cast-qual.cpp SemaCXX/warn-cast-qual.cpp: In function ‘void foo_0()’: SemaCXX/warn-cast-qual.cpp:24:20: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] int &a2 = (int &)a; // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:25:26: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] const int &a3 = (int &)a; // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:26:35: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] int &a4 = (int &)((const int &)a); // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:27:28: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] int &a5 = (int &)((int &)a); // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:28:34: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] const int &a6 = (int &)((int &)a); // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:29:41: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] const int &a7 = (int &)((const int &)a); // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:30:40: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] const int &a8 = (const int &)((int &)a); // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp: In function ‘void foo_1()’: SemaCXX/warn-cast-qual.cpp:39:20: warning: cast from type ‘volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] int &a2 = (int &)a; // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}} ^ SemaCXX/warn-cast-qual.cpp:40:29: warning: cast from type ‘volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] volatile int &a3 = (int &)a; // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}} ^ SemaCXX/warn-cast-qual.cpp:41:38: warning: cast from type ‘volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] int &a4 = (int &)((volatile int &)a); // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}} ^ SemaCXX/warn-cast-qual.cpp:42:28: warning: cast from type ‘volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] int &a5 = (int &)((int &)a); // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}} ^ SemaCXX/warn-cast-qual.cpp:43:37: warning: cast from type ‘volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] volatile int &a6 = (int &)((int &)a); // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}} ^ SemaCXX/warn-cast-qual.cpp:44:47: warning: cast from type ‘volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] volatile int &a7 = (int &)((volatile int &)a); // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}} ^ SemaCXX/warn-cast-qual.cpp:45:46: warning: cast from type ‘volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] volatile int &a8 = (volatile int &)((int &)a); // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}} ^ SemaCXX/warn-cast-qual.cpp: In function ‘void foo_2()’: SemaCXX/warn-cast-qual.cpp:54:20: warning: cast from type ‘const volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] int &a2 = (int &)a; // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}} ^ SemaCXX/warn-cast-qual.cpp:55:35: warning: cast from type ‘const volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] const volatile int &a3 = (int &)a; // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}} ^ SemaCXX/warn-cast-qual.cpp:56:44: warning: cast from type ‘const volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] int &a4 = (int &)((const volatile int &)a); // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}} ^ SemaCXX/warn-cast-qual.cpp:57:28: warning: cast from type ‘const volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] int &a5 = (int &)((int &)a); // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}} ^ SemaCXX/warn-cast-qual.cpp:58:43: warning: cast from type ‘const volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] const volatile int &a6 = (int &)((int &)a); // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}} ^ SemaCXX/warn-cast-qual.cpp:59:59: warning: cast from type ‘const volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] const volatile int &a7 = (int &)((const volatile int &)a); // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}} ^ SemaCXX/warn-cast-qual.cpp:60:58: warning: cast from type ‘const volatile int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] const volatile int &a8 = (const volatile int &)((int &)a); // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}} ^ SemaCXX/warn-cast-qual.cpp: In function ‘void bar_0()’: SemaCXX/warn-cast-qual.cpp:67:38: warning: cast from type ‘const int**’ to type ‘int**’ casts away qualifiers [-Wcast-qual] int **a0 = (int **)((const int **)a); // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:68:31: warning: cast from type ‘const int**’ to type ‘int**’ casts away qualifiers [-Wcast-qual] int **a1 = (int **)((int **)a); // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:73:43: warning: cast from type ‘const int**’ to type ‘int**’ casts away qualifiers [-Wcast-qual] const int **a4 = (const int **)((int **)a); // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} expected-warning {{cast from 'int **' to 'const int **' must have all intermediate pointers const qualified to be safe}} ^ SemaCXX/warn-cast-qual.cpp:73:44: warning: cast from type ‘int**’ to type ‘const int**’ casts away qualifiers [-Wcast-qual] const int **a4 = (const int **)((int **)a); // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} expected-warning {{cast from 'int **' to 'const int **' must have all intermediate pointers const qualified to be safe}} ^ SemaCXX/warn-cast-qual.cpp: In function ‘void bar_1()’: SemaCXX/warn-cast-qual.cpp:81:38: warning: cast from type ‘const int**’ to type ‘int**’ casts away qualifiers [-Wcast-qual] int *&a0 = (int *&)((const int *&)a); // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:82:31: warning: cast from type ‘const int**’ to type ‘int**’ casts away qualifiers [-Wcast-qual] int *&a1 = (int *&)((int *&)a); // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:87:43: warning: cast from type ‘const int**’ to type ‘int**’ casts away qualifiers [-Wcast-qual] const int *&a4 = (const int *&)((int *&)a); // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} expected-warning {{cast from 'int *' to 'const int *&' must have all intermediate pointers const qualified to be safe}} ^ SemaCXX/warn-cast-qual.cpp:87:44: warning: cast from type ‘int**’ to type ‘const int**’ casts away qualifiers [-Wcast-qual] const int *&a4 = (const int *&)((int *&)a); // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} expected-warning {{cast from 'int *' to 'const int *&' must have all intermediate pointers const qualified to be safe}} ^ SemaCXX/warn-cast-qual.cpp: In function ‘void baz_0()’: SemaCXX/warn-cast-qual.cpp:100:9: warning: cast from type ‘const baz_0()::C*’ to type ‘baz_0()::C*’ casts away qualifiers [-Wcast-qual] ((C &)S).B(); // expected-warning {{cast from 'const C' to 'C &' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:101:9: warning: cast from type ‘const baz_0()::C*’ to type ‘baz_0()::C*’ casts away qualifiers [-Wcast-qual] ((C &)S).A(); // expected-warning {{cast from 'const C' to 'C &' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:103:10: warning: cast from type ‘const baz_0()::C*’ to type ‘baz_0()::C*’ casts away qualifiers [-Wcast-qual] ((C *)&S)->B(); // expected-warning {{cast from 'const C *' to 'C *' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:104:10: warning: cast from type ‘const baz_0()::C*’ to type ‘baz_0()::C*’ casts away qualifiers [-Wcast-qual] ((C *)&S)->A(); // expected-warning {{cast from 'const C *' to 'C *' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp: In function ‘void baz_1()’: SemaCXX/warn-cast-qual.cpp:119:16: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] (int &)(S.a) = 0; // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:122:18: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] *(int *)(&S.a) = 0; // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:128:16: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] (int &)(S.a) = 0; // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:129:16: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] (int &)(S.b) = 0; // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:131:18: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] *(int *)(&S.a) = 0; // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ SemaCXX/warn-cast-qual.cpp:132:18: warning: cast from type ‘const int*’ to type ‘int*’ casts away qualifiers [-Wcast-qual] *(int *)(&S.b) = 0; // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} ^ So to me it seems that for our clang's testcases, both compilers produce the compatible set of warnings... Repository: rL LLVM https://reviews.llvm.org/D33102 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits