<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 - Pedantically warning on attributes used as extensions"
   href="https://bugs.llvm.org/show_bug.cgi?id=50046">50046</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Pedantically warning on attributes used as extensions
          </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>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>barry.revzin@gmail.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 code, which tries to detect the ability to use
[[nodiscard]] and then uses it:

#ifndef __has_cpp_attribute
#  define HAS_ATTRIBUTE(x) 0
#else
#  define HAS_ATTRIBUTE(x) __has_cpp_attribute(x) > 0
#endif

#if HAS_ATTRIBUTE(nodiscard)
#  define NODISCARD [[nodiscard]]
#else
#  define NODISCARD
#endif

struct NODISCARD Result { };

With clang (on any version I've tested), if I compile this with -std=c++14
-pedantic, I get a warning:

<source>:13:8: warning: use of the 'nodiscard' attribute is a C++17 extension
[-Wc++17-extensions]
struct NODISCARD Result { };
       ^
<source>:8:23: note: expanded from macro 'NODISCARD'
#  define NODISCARD [[nodiscard]]
                      ^

But if __has_cpp_attribute(nodiscard) is not the right way to detect nodiscard,
what would be?

One alternative might be to use __cplusplus somehow to check to see if the
attribute is *really* available. That is, do this:

#  define HAS_ATTRIBUTE(x) __has_cpp_attribute(x) > 0 && __has_cpp_attribute(x)
<span class="quote">> 0 && __cplusplus >= __has_cpp_attribute(x)</span >

This has the benefit of silencing the pedantic warning.

But it also has the consequence of actually not using [[nodiscard]] even when
it's available. For instance, on clang trunk 11.0.0, when compiling with
-std=c++17, __cplusplus is 201703 but __has_cpp_attribute(nodiscard) is 201907.
As a result, my Result here would not be [[nodiscard]] - a false negative.
clang 11.0 --std=c++20 would successfully mark Result as [[nodiscard]], but gcc
10.2 --std=c++20 would not (because that release does not yet increase
__cplusplus).

Is there a way to programmatically detect the availability of an attribute in a
way that would not be warned? Maybe that means __has_cpp_attribute(nodiscard)
should be 0 if compiling as --std=c++14 or --std=c++11 with -pedantic and
without -Wno-c++17-extensions? Otherwise, the only solution I think would be to
do what nlohmann/json did (<a href="https://github.com/nlohmann/json/issues/1535">https://github.com/nlohmann/json/issues/1535</a>) and do
something like this:

#if __has_cpp_attribute(nodiscard)
    #if defined(__clang__) && !defined(JSON_HAS_CPP_17) // issue #1535
        #define JSON_NODISCARD
    #else
        #define JSON_NODISCARD [[nodiscard]]
    #endif
#endif

But this kind of explicit compiler-based configuration was what we were hoping
to avoid with feature-test macros (and also means that clang users that are not
compiling with -pedantic still don't get nodiscard).</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>