title: What exactly does GCC's -Wpsabi option do? What are the implications of supressing it?
body: <h3>Background</h3>
  
  <p>In the last year I was using the nlohmann json library<sup>[1]</sup> and was cross-compiling on x86_64 using GCC 5.x <code>arm-linux-gnueabi-*</code> with no warnings. When I updated GCC to a newer version, GCC would generate pages of cryptic diagnostic notes. For example, here is one of the notes</p>
  
  <pre><code>In file included from /usr/arm-linux-gnueabi/include/c++/7/vector:69:0,
               from include/json.hpp:58,
               from src/write_hsi.cpp:23:
  /usr/arm-linux-gnueabi/include/c++/7/bits/vector.tcc: In member function ‘void std::vector&lt;_Tp, _Alloc&gt;::_M_realloc_insert(std::vector&lt;_Tp, _Alloc&gt;::iterator, _Args&amp;&amp; ...) [with _Args = {nlohmann::basic_json&lt;std::map, std::vector, std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;, bool, long long int, long long unsigned int, double, std::allocator, nlohmann::adl_serializer&gt;}; _Tp = nlohmann::basic_json&lt;&gt;; _Alloc = std::allocator&lt;nlohmann::basic_json&lt;&gt; &gt;]’:
  /usr/arm-linux-gnueabi/include/c++/7/bits/vector.tcc:394:7: note: parameter passing for argument of type ‘std::vector&lt;nlohmann::basic_json&lt;&gt;, std::allocator&lt;nlohmann::basic_json&lt;&gt; &gt; &gt;::iterator {aka __gnu_cxx::__normal_iterator&lt;nlohmann::basic_json&lt;&gt;*, std::vector&lt;nlohmann::basic_json&lt;&gt;, std::allocator&lt;nlohmann::basic_json&lt;&gt; &gt; &gt; &gt;}’ changed in GCC 7.1
     vector&lt;_Tp, _Alloc&gt;::
     ^~~~~~~~~~~~~~~~~~~
  /usr/arm-linux-gnueabi/include/c++/7/bits/vector.tcc: In member function ‘nlohmann::basic_json&lt;ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer&gt; nlohmann::basic_json&lt;ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer&gt;::parser::parse_internal(bool) [with ObjectType = std::map; ArrayType = std::vector; StringType = std::__cxx11::basic_string&lt;char&gt;; BooleanType = bool; NumberIntegerType = long long int; NumberUnsignedType = long long unsigned int; NumberFloatType = double; AllocatorType = std::allocator; JSONSerializer = nlohmann::adl_serializer]’:
  /usr/arm-linux-gnueabi/include/c++/7/bits/vector.tcc:105:21: note: parameter passing for argument of type ‘__gnu_cxx::__normal_iterator&lt;nlohmann::basic_json&lt;&gt;*, std::vector&lt;nlohmann::basic_json&lt;&gt;, std::allocator&lt;nlohmann::basic_json&lt;&gt; &gt; &gt; &gt;’ changed in GCC 7.1
  _M_realloc_insert(end(), std::forward&lt;_Args&gt;(__args)...);
  ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  </code></pre>
  
  <p>It was easy to find a solution, namely by adding <code>-Wno-psabi</code> to the compiler options. In fact, that was the fix implemented in the library.<sup>[2]</sup></p>
  
  <p>I understand the basics of Application Binary Interfaces (ABIs) and processor-specific ABIs (psABIs). For reference, this answer<sup>[11]</sup> gives a quick overview of ABIs:</p>
  
  <blockquote>
    <p>An ABI (<em><strong>Application Binary Interface</strong></em>) is a standard that defines a mapping between low-level concepts in high-level languages and the abilities of a specific hardware/OS platform's machine code. That includes things like:</p>
    
    <ul>
    <li>how C/C++/Fortran/... <strong>data types</strong> are laid out in memory (data sizes / alignments)</li>
    <li>how nested <strong>function calls</strong> work (where and how the information on how to return to a function's caller is stored, where in the CPU registers and/or in memory function arguments are passed)</li>
    <li>how <strong>program startup / initialization</strong> works (what data format an "executable" has, how the code / data is loaded from there, how DLLs work ...)</li>
    </ul>
    
    <p>The answers to these are:</p>
    
    <ul>
    <li><em>language-specific</em> (hence you've got a C ABI, C++ ABI, Fortran ABI, Pascal ABI, ... even the Java bytecode spec, although targeting a "virtual" processor instead of real hardware, is an ABI),</li>
    <li><em>operating-system specific</em> (MS Windows and Linux on the same hardware use a different ABI),</li>
    <li><em>hardware/CPU-specific</em> (the ARM and x86 ABIs are different).</li>
    <li><em>evolving over (long) time</em> (existing ABIs have often been updated / rev'ed so that new CPU features could be made use of, like, say, specifying how the x86 SSE registers are to be used by apps was of course only possible once CPUs <em>had</em> these regs, therefore existing ABIs needed to be clarified).</li>
    </ul>
  </blockquote>
  
  <p>So the ABI is the overarching component, and one of its components (the "hardware/CPU-specific" details) is the psABI.</p>
  
  <h3>My Issue</h3>
  
  <p>The problem I am having is</p>
  
  <ol>
  <li>I don't like universally disabling warnings without understanding the implications.</li>
  <li>The advice "use <code>-Wno-psabi</code> to make the notes go away" seems to be pretty common advice for these types of diagnostic notes that "suddenly appear" after a compiler upgrade.<sup>[2]</sup><sup>[3]</sup><sup>[4]</sup> Even the one of the GCC developers suggest doing this.<sup>[5]</sup></li>
  <li>Neither <code>-Wpsabi</code> nor <code>-Wno-psabi</code> are documented<sup>[6]</sup> in the GCC manual.<sup>[7]</sup></li>
  </ol>
  
  <p>As a result I am not really sure what exactly <code>-Wno-psabi</code> will and will not affect. A related option <code>-Wabi</code> <em>is</em> documented:<sup>[8]</sup></p>
  
  <blockquote>
    <p><code>-Wabi (C, Objective-C, C++ and Objective-C++ only)</code></p>
    
    <p>Warn when G++ it generates code that is probably not compatible with the vendor-neutral C++ ABI...</p>
    
    <p>It also warns about psABI-related changes. The known psABI changes at this point include: </p>
    
    <ul>
    <li>For SysV/x86-64, unions with long double members are passed in memory as specified in psABI. For example: </li>
    </ul>
    
    <p><code>union U {</code>
    <code>long double ld;</code>
    <code>int i;</code>
    <code>};</code></p>
    
    <p><code>union U</code> is always passed in memory.</p>
  </blockquote>
  
  <p>My understanding of this all is</p>
  
  <ol>
  <li><code>-Wabi</code> will generate warnings when there is a psABI change.</li>
  <li>GCC 7 fixed an ABI bug<sup>[9]</sup> introduced in GCC 5 that affects ARM targets.
  
  <ul>
  <li>In the release notes it is stated "this is an ABI change."<sup>[10]</sup></li>
  <li>For some reason the release notes state that the related diagnostic notes are generated when using the undocumented <code>-Wpsabi</code>, not the documented <code>-Wabi</code>.</li>
  <li>This ABI change is not mentioned in the manual.</li>
  </ul></li>
  <li>Putting together "this is an ABI change" and "use <code>-Wpsabi</code>", it appears to me this is <em>specifically</em> a psABI change, not a different kind of ABI change. (In reality it is a change in GCC's implementation of the psABI, not the psABI itself)</li>
  </ol>
  
  <p>I know that documentation isn't always up to date, especially for something that is a known undocumented option. But my concern is that "use <code>-Wno-psabi</code>" seems to be the standard response for several different kinds of these cryptic diagnostic notes. But, in my basic understanding of ABIs, isn't an ABI change a big deal? Shouldn't I be concerned about an ABI change, rather than just making the message go away? Between the undocumented stuff and some of the finer details of ABI vs psABI, I'm not really sure...</p>
  
  <p>For example, if I add <code>-Wno-psabi</code> to my makefile to make those notes go away, what if there is another ABI change in the future that <em>does</em> affect my project? Have I effectively silenced future warnings or notes that may be important?</p>
  
  <p>Also, even though we are told "if you recompile all the code, there is nothing to worry about,"<sup>[5]</sup> what exactly is "all the code"? Is that my source code? glibc? Any other system-wide shared library I might be using?</p>
  
  <h3>References</h3>
  
  <ol>
  <li><a href="https://github.com/nlohmann/json" rel="noreferrer">https://github.com/nlohmann/json</a></li>
  <li><a href="https://github.com/nlohmann/json/issues/658" rel="noreferrer">https://github.com/nlohmann/json/issues/658</a></li>
  <li><a href="https://stackoverflow.com/a/48149400">https://stackoverflow.com/a/48149400</a></li>
  <li><a href="https://stackoverflow.com/a/13915796/10270632">https://stackoverflow.com/a/13915796/10270632</a></li>
  <li><a href="https://gcc.gnu.org/ml/gcc/2017-05/msg00073.html" rel="noreferrer">https://gcc.gnu.org/ml/gcc/2017-05/msg00073.html</a></li>
  <li><a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81831" rel="noreferrer">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81831</a></li>
  <li><a href="https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc" rel="noreferrer">https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc</a></li>
  <li><a href="https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/C_002b_002b-Dialect-Options.html" rel="noreferrer">https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/C_002b_002b-Dialect-Options.html</a></li>
  <li><a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77728" rel="noreferrer">https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77728</a></li>
  <li><a href="https://gcc.gnu.org/gcc-7/changes.html" rel="noreferrer">https://gcc.gnu.org/gcc-7/changes.html</a></li>
  <li><a href="https://stackoverflow.com/a/8063350">https://stackoverflow.com/a/8063350</a></li>
  </ol>