<div dir="ltr">Yeah, looks like the UB is baked in pretty deep here, so it's not reasonable to try to fix it just because of this.<br><br>I'd probably suggest trying making that cast in PointerUnion.h into a reinterpret cast? Would that suffice to address the const issues? Otherwise a const_cast + reinterpret_cast?<br><br><br></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Jun 12, 2017 at 10:35 AM Roman Lebedev <<a href="mailto:lebedev.ri@gmail.com">lebedev.ri@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Mon, Jun 12, 2017 at 8:16 PM, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:<br>
><br>
><br>
> On Mon, Jun 12, 2017 at 10:10 AM Roman Lebedev via Phabricator<br>
> <<a href="mailto:reviews@reviews.llvm.org" target="_blank">reviews@reviews.llvm.org</a>> wrote:<br>
>><br>
>> lebedev.ri added a comment.<br>
>><br>
>> So i'm trying to analyze that stage2 warning.<br>
><br>
><br>
> Could you link to the buildbot failure to see the original LLVM project code<br>
> triggering this situation?<br>
<a href="http://lab.llvm.org:8011/builders/clang-with-lto-ubuntu/builds/3249" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/builders/clang-with-lto-ubuntu/builds/3249</a><br>
<a href="http://lab.llvm.org:8011/builders/clang-with-lto-ubuntu/builds/3249/steps/build-stage2-LLVMgold.so/logs/stdio" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/builders/clang-with-lto-ubuntu/builds/3249/steps/build-stage2-LLVMgold.so/logs/stdio</a><br>
<br>
FAILED: /home/buildbot/Buildbot/Slave1a/clang-with-lto-ubuntu/install/stage1/bin/clang++<br>
  -DGTEST_HAS_RTTI=0 -DLLVM_BUILD_GLOBAL_ISEL -D_DEBUG -D_GNU_SOURCE<br>
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS<br>
-Ilib/CodeGen/AsmPrinter<br>
-I/home/buildbot/Buildbot/Slave1a/clang-with-lto-ubuntu/llvm.src/lib/CodeGen/AsmPrinter<br>
-Iinclude -I/home/buildbot/Buildbot/Slave1a/clang-with-lto-ubuntu/llvm.src/include<br>
-fPIC -fvisibility-inlines-hidden -Werror -Werror=date-time -std=c++11<br>
-Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual<br>
-Wmissing-field-initializers -pedantic -Wno-long-long<br>
-Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor<br>
-Wstring-conversion -fcolor-diagnostics -ffunction-sections<br>
-fdata-sections -O3    -UNDEBUG  -fno-exceptions -fno-rtti -MMD -MT<br>
lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/CodeViewDebug.cpp.o<br>
-MF lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/CodeViewDebug.cpp.o.d<br>
-o lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/CodeViewDebug.cpp.o<br>
-c /home/buildbot/Buildbot/Slave1a/clang-with-lto-ubuntu/llvm.src/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp<br>
In file included from<br>
/home/buildbot/Buildbot/Slave1a/clang-with-lto-ubuntu/llvm.src/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp:14:<br>
In file included from<br>
/home/buildbot/Buildbot/Slave1a/clang-with-lto-ubuntu/llvm.src/lib/CodeGen/AsmPrinter/CodeViewDebug.h:17:<br>
In file included from<br>
/home/buildbot/Buildbot/Slave1a/clang-with-lto-ubuntu/llvm.src/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h:15:<br>
In file included from<br>
/home/buildbot/Buildbot/Slave1a/clang-with-lto-ubuntu/llvm.src/include/llvm/IR/DebugInfoMetadata.h:26:<br>
In file included from<br>
/home/buildbot/Buildbot/Slave1a/clang-with-lto-ubuntu/llvm.src/include/llvm/IR/Metadata.h:23:<br>
/home/buildbot/Buildbot/Slave1a/clang-with-lto-ubuntu/llvm.src/include/llvm/ADT/PointerUnion.h:161:19:<br>
error: cast from 'void **' to 'const llvm::DISubprogram **' must have<br>
all intermediate pointers const qualified to be safe<br>
[-Werror,-Wcast-qual]<br>
    return (PT1 *)Val.getAddrOfPointer();<br>
                  ^<br>
/home/buildbot/Buildbot/Slave1a/clang-with-lto-ubuntu/llvm.src/include/llvm/ADT/TinyPtrVector.h:177:18:<br>
note: in instantiation of member function 'llvm::PointerUnion<const<br>
llvm::DISubprogram *, llvm::SmallVector<const llvm::DISubprogram *, 4><br>
*>::getAddrOfPtr1' requested here<br>
      return Val.getAddrOfPtr1();<br>
                 ^<br>
/home/buildbot/Buildbot/Slave1a/clang-with-lto-ubuntu/llvm.src/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp:1885:33:<br>
note: in instantiation of member function 'llvm::TinyPtrVector<const<br>
llvm::DISubprogram *>::begin' requested here<br>
    for (const DISubprogram *SP : MethodItr.second) {<br>
                                ^<br>
<br>
<br>
>><br>
>> The testcase //seems// to be: (autogenerated all the variants)<br>
>><br>
>>   void test_nop() {<br>
>>     unsigned char **ptr1 = 0;<br>
>>     void **ptr2 = (void **)ptr1;<br>
>>   }<br>
>>   void test_bad() {<br>
>>     unsigned char **ptr1 = 0;<br>
>>     const void **ptr2 = (const void **)ptr1; // expected-warning {{cast<br>
>> from 'unsigned char **' to 'const void **' must have all intermediate<br>
>> pointers const qualified to be safe}}<br>
>>   }<br>
>>   void test_good0() {<br>
>>     unsigned char **ptr1 = 0;<br>
>>     void *const *ptr2 = (void *const *)ptr1;<br>
>>   }<br>
>>   void test_good1() {<br>
>>     unsigned char **ptr1 = 0;<br>
>>     const void *const *ptr2 = (const void *const *)ptr1;<br>
>>   }<br>
>>   void test_good2() {<br>
>>     unsigned char *const *ptr1 = 0;<br>
>>     void *const *ptr2 = (void *const *)ptr1;<br>
>>   }<br>
>>   void test_good3() {<br>
>>     unsigned char *const *ptr1 = 0;<br>
>>     const void *const *ptr2 = (const void *const *)ptr1;<br>
>>   }<br>
>>   void test_good4() {<br>
>>     const unsigned char **ptr1 = 0;<br>
>>     const void **ptr2 = (const void **)ptr1;<br>
>>   }<br>
>>   void test_good5() {<br>
>>     const unsigned char **ptr1 = 0;<br>
>>     const void *const *ptr2 = (const void *const *)ptr1;<br>
>>   }<br>
>>   void test_good6() {<br>
>>     const unsigned char *const *ptr1 = 0;<br>
>>     const void *const *ptr2 = (const void *const *)ptr1;<br>
>>   }<br>
>><br>
>> GCC does not warn about such code at all, clang in C mode does warn about<br>
>> only one combination:<br>
>><br>
>>   $ gcc -c /tmp/test.c -Wcast-qual<br>
>>   $ echo $?<br>
>>   0<br>
>>   $ clang -c /tmp/test.c -Wcast-qual<br>
>>   /tmp/test.c:7:38: warning: cast from 'unsigned char **' to 'const void<br>
>> **' must have all intermediate pointers const qualified to be safe<br>
>> [-Wcast-qual]<br>
>>     const void **ptr2 = (const void **)ptr1; // expected-warning {{cast<br>
>> from 'unsigned char **' to 'const void **' must have all intermediate<br>
>> pointers const qualified to be safe}}<br>
>>                                        ^<br>
>>   1 warning generated.<br>
>><br>
>> David, you reviewed the original `-Wcast-qual` patch, does all that ^ make<br>
>> sense?<br>
><br>
><br>
> That seems like a reasonable warning, do you agree?<br>
I think all that makes sense. I just want to have a second opinion,<br>
especially about rest of these cases where it does not fire.<br>
<br>
> But maybe it's best to put it under another flag name so it doesn't collide<br>
> with GCC.<br>
<br>
> But really - *shrug* I'd probably leave it under the same flag, fix the LLVM<br>
> project code that causes it, and carry on.<br>
I hope that will be the solution.<br>
<br>
>><br>
>><br>
>> F3429854: gen.cpp <<a href="https://reviews.llvm.org/F3429854" rel="noreferrer" target="_blank">https://reviews.llvm.org/F3429854</a>><br>
>><br>
>><br>
>> Repository:<br>
>>   rL LLVM<br>
>><br>
>> <a href="https://reviews.llvm.org/D33102" rel="noreferrer" target="_blank">https://reviews.llvm.org/D33102</a><br>
>><br>
>><br>
>><br>
><br>
</blockquote></div>