title: Condition inclusion through has-include-expression and has-attribute-expression behaves differently
body: <pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt;
  
  #define Abc likely
  # if __has_cpp_attribute(Abc)
  #define Pn 0
  #endif 
  
  #if __has_cpp_attribute(likely)
  #ifndef Pn
  #define Pn 1
  #endif
  #endif
  int main(){
     std::cout&lt;&lt; Pn;
  }
  </code></pre>
  <p>For this <a href="https://godbolt.org/z/bK8sTejdY" rel="noreferrer">example</a>, GCC prints <code>0</code> while Clang prints <code>1</code>. According to [cpp.cond] p5</p>
  <blockquote>
  <p>Each has-attribute-expression is replaced by a non-zero pp-number matching the form of an integer-literal if the implementation supports an attribute with the name specified by interpreting the pp-tokens, <strong>after macro expansion</strong>, as an attribute-token, and by 0 otherwise. The program is ill-formed if the pp-tokens do not match the form of an attribute-token.</p>
  </blockquote>
  <p>So, the directive <code># if __has_cpp_attribute(Abc)</code> should behave the same as <code>#if __has_cpp_attribute(likely)</code>. GCC has the right behavior. Again, consider this example</p>
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt;
  #define Head &lt;iostream&gt;
  # if __has_include(Head)
  #define Pn 0
  #endif 
  
  #ifndef Pn
  #define Pn 1
  #endif
  int main(){
     std::cout&lt;&lt; Pn;
  }
  </code></pre>
  <p>In this <a href="https://godbolt.org/z/z3jjTMY7Y" rel="noreferrer">example</a>, both compilers print <code>0</code>. However, according to [cpp.cond] p4</p>
  <blockquote>
  <p>The header or source file identified by the parenthesized preprocessing token sequence in each contained has-include-expression is searched for as if that preprocessing token sequence were the pp-tokens in a #include directive, <strong>except that no further macro expansion is performed</strong>. If such a directive would not satisfy the syntactic requirements of a #include directive, the program is ill-formed. The has-include-expression evaluates to 1 if the search for the source file succeeds, and to 0 if the search fails.</p>
  </blockquote>
  <p>Note the bold wording, which means <code>Head</code> won't be replaced by <code>&lt;iostream&gt;</code>, there is no such a source file. Hence, <code>Pn</code> should be <code>1</code> instead. Could it be considered a bug of GCC and Clang?</p>