<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 - Incorrect formatting with C++11 attributes"
   href="https://bugs.llvm.org/show_bug.cgi?id=35903">35903</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Incorrect formatting with C++11 attributes
          </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>Linux
          </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>Formatter
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>artemiev.mikhail@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>djasper@google.com, klimek@google.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Consider the following test file:

$ cat ~/tmp/1.cpp
// attribute before entity - space inside brackets
[[ noreturn ]] void f1() {
   int a = 42;
}

// attribute before entity - no space inside brackets
[[noreturn]] void f2() {
   int a = 42;
}

// attribute after entity - space inside brackets
void f3 [[ noreturn ]] () {
   int a = 42;
}

// attribute after entity - no space inside brackets
void f4 [[noreturn]] () {
   int a = 42;
}

int main() {
   // attribute after entity - space inside brackets
   int a [[ gnu::unused ]] = 0;
   // attribute after entity - no space inside brackets
   int b [[gnu::unused]] = 1;
   // attribute before entity - space inside brackets
   [[ gnu::unused ]] int c = 2;
   // attribute before entity - no space inside brackets
   [[gnu::unused]] int d = 3;
   return 0;
}

Formatting it with the default LLVM style produces the following:

$ bin/clang-format --style=llvm ~/tmp/1.cpp
// attribute before entity - space inside brackets
[[noreturn]] void f1() { int a = 42; }

    // attribute before entity - no space inside brackets
    [[noreturn]] void f2() {
  int a = 42;
}

// attribute after entity - space inside brackets
void f3[[noreturn]]() { int a = 42; }

// attribute after entity - no space inside brackets
void f4[[noreturn]]() { int a = 42; }

int main() {
  // attribute after entity - space inside brackets
  int a[[gnu::unused]] = 0;
  // attribute after entity - no space inside brackets
  int b[[gnu::unused]] = 1;
  // attribute before entity - space inside brackets
  [[gnu::unused]] int c = 2;
  // attribute before entity - no space inside brackets
  [[gnu::unused]] int d = 3;
  return 0;
}

Issues:
1. When an attribute is placed after an entity, the formatter removes the space
between the identifier and the attribute.
2. Something went wrong with the f2 formatting.

With the following settings some other issues can be seen:

$ bin/clang-format --style="{BasedOnStyle: llvm, SpacesInSquareBrackets: true,
AlwaysBreakAfterReturnType: TopLevelDefinitions}" ~/tmp/1.cpp
// attribute before entity - space inside brackets
[[noreturn]] void
f1() { int a = 42; }

    // attribute before entity - no space inside brackets
    [ [noreturn] ] void f2() {
  int a = 42;
}

// attribute after entity - space inside brackets
void f3[ [noreturn] ]() { int a = 42; }

// attribute after entity - no space inside brackets
void f4[ [noreturn] ]() { int a = 42; }

int
main() {
  // attribute after entity - space inside brackets
  int a[ [gnu::unused] ] = 0;
  // attribute after entity - no space inside brackets
  int b[ [gnu::unused] ] = 1;
  // attribute before entity - space inside brackets
  [[gnu::unused]] int c = 2;
  // attribute before entity - no space inside brackets
  [[gnu::unused]] int d = 3;
  return 0;
}

Issues:
3. With 'SpacesInSquareBrackets: true', the attribute becomes '[ [attribute] ]'
4. When an attribute is placed after an entity, the
'AlwaysBreakAfterReturnType' has no effect (cf. functions f3, f4)

This test file was tried on a freshly built clang from trunk.</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>