<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 places implicitly declared C functions at compile unit scope"
   href="https://bugs.llvm.org/show_bug.cgi?id=33224">33224</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>clang places implicitly declared C functions at compile unit scope
          </td>
        </tr>

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

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

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </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>Frontend
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>momchil.velikov@arm.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=18537" name="attach_18537" title="testcase">attachment 18537</a> <a href="attachment.cgi?id=18537&action=edit" title="testcase">[details]</a></span>
testcase

Compiling the following testcase with `clang -std=c90 -c x.c`

<span class="quote">> int f() {
>        g();
>        return 0;
> }

>  int (*p)() = g;</span >

completes successfully.

The identifier `g` is not declared at the place, where it appears in the
context of the function call expression. In that case, the C90 Standard says
(6.3.3.2 Function calls):

<span class="quote">>     If the expression that precedes the parenthesized argument list in a function
>     call consists solely by an identifier, and if no declaration is visible for this
>     identifier, the identifier is implicitly declared as if, in the innermost block
>     containing the function call, the declaration

>     extern int identifier();

>     appeared.</span >

Therefore, the above program should be equivalent to:

<span class="quote">> int f() {
>        extern int g();
>        g();
>        return 0;
> }

>  int (*p)() = g;</span >

for which clang terminates with an error. The C90 Standard (6.1.2.1 Scopes of
identifiers), says:

<span class="quote">> If the declarator or type specifier that declared the identifier appears inside a block [...],
> the identifier has block scope, which terminates at the } that closes the associated block.</span >

so, this should be the correct behavior in both testcases.

However, clang places the implicitly declared function at translation
unit scope, which causes the identifier to be visible in the initializer
in the original testcase, in effect accepting an invalid program.</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>