<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Clang pointer to VLA conversions disallowed in C++ mode."
   href="https://bugs.llvm.org/show_bug.cgi?id=46259">46259</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Clang pointer to VLA conversions disallowed in C++ mode.
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>erich.keane@intel.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, dgregor@apple.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>See <a href="https://godbolt.org/z/dBvJLK">https://godbolt.org/z/dBvJLK</a>


void foo(void *a, int x) {
    int (*VLA) [x] = (int(*)[x]) a;
    VLA = (int(*)[x]) a;
}

<source>:4:11: error: cannot initialize a variable of type 'int (*)[x]' with an
rvalue of type 'int (*)[x]'

    int (*VLA) [x] = (int(*)[x]) a;

          ^          ~~~~~~~~~~~~~

<source>:5:11: error: incompatible pointer types assigning to 'int (*)[x]' from
'int (*)[x]'

    VLA = (int(*)[x]) a;

          ^~~~~~~~~~~~~

2 errors generated.

Compiler returned: 1



The two types listed in both error message (despite syntactically and textually
identical) are actually pointers to different types, thus conversions aren't
allowed.  In C mode the IsPointerConversion goes through typesAreConvertible
and mergeTypes and decides they are the compatible.  However, the rules in C++
disallow these compatible conversions.

GCC allows these, and it seems to me that these two types should be allowed as
they are effectively the 'same' type despite being represented as different
types in our AST.

SO, to fix this I think we either need to 

a: better canonicalize VLA types based on their represented types/bounds,
though this wouldn't fix the situation where the value of 'x' above could
change between them, so it would accept some incompatible types (where hte
value of "x" changed between the two), and disallow others.


b: Simply treat these as 'same-type' as a condition in isPointerConversion. I
think we can just do a minimal reproduction of mergeTypes to recursively check
ONLY VLA and element types.  C mode ALSO allows fixed-size arrays on either
side of the conversion, so we may consider making this work for all array
types?</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>