<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 - switch implicit block should not be there in -std=c89"
   href="https://bugs.llvm.org/show_bug.cgi?id=48079">48079</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>switch implicit block should not be there in -std=c89
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>11.0
          </td>
        </tr>

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

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>normal
          </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>cuoq@trust-in-soft.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>Consider the following:

int X;

int main(void) {
  switch (sizeof(struct s { char a;}))   
  case 1: X = sizeof (struct s { float b;});
  return 0;
}

This is a correct C99 program, because in C99 and later standards, the switch
implicitly defines a block for its substatement (clause 6.8.4:3 in C17):

A selection statement is a block whose scope is a strict subset of the scope of
its enclosing block. Each
associated substatement is also a block whose scope is a strict subset of the
scope of the selection
statement.

No such clause exists in the C89 standard, and accordingly, the text above is
not a valid C89 program, because the struct s is defined twice in the same
scope.

GCC 10.2 correctly accepts the program when invoked with “gcc -std=c99” and
kindly rejects it when invoked with “gcc -std=c89”. Compiler Explorer link:
<a href="https://gcc.godbolt.org/z/P6qevb">https://gcc.godbolt.org/z/P6qevb</a>

However, Clang 11.0 accepts the program when invoked with “clang -std=c89“.
Compiler Explorer link: <a href="https://gcc.godbolt.org/z/jeKfMs">https://gcc.godbolt.org/z/jeKfMs</a>

It is possible that C89 says that this program is UB (the relevant clause
appears to be 3.5.2.3 Tags but I am not an expert at C89 and its
interpretations), in which case Clang's behavior would be acceptable. But
please note that Clang generally aims at kindly rejecting such programs instead
of silently doing something meaningless, as seen when compiling this program,
which is rejected for this very reason:

int X;

int main(void) {
  switch (sizeof(struct s { char a;}))   
  case 1:;
  X = sizeof (struct s { float b;});
  return 0;
}

Compiler Explorer link: <a href="https://gcc.godbolt.org/z/9eqds9">https://gcc.godbolt.org/z/9eqds9</a>

It is therefore still possible to consider this Clang behavior when compiling
C89 code as a Quality of Implementation issue.</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>