title: GCC: accuracy of strict aliasing warnings
body: <p>I'm trying to check some of my code for strict aliasing violations, but it
  looks like I've missed something while trying to understand the strict aliasing
  rule.</p>
  
  <p>Imagine the following code:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  int main( void )
  {
      unsigned long l;
  
      l = 0;
  
      *( ( unsigned short * )&amp;l ) = 1;
  
      printf( "%lu\n", l );
  
      return 0;
  }
  </code></pre>
  
  <p>Classic and basic example. With GCC 4.9 (<code>-Wall -fstrict-aliasing -Wstrict-aliasing -O3</code>), it actually reports the error:</p>
  
  <pre><code> dereferencing type-punned pointer will break strict-aliasing rules
  </code></pre>
  
  <p>But the following compiles fine:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  int main( void )
  {
      unsigned long    l;
      unsigned short * sp;
  
      l       = 0;
      sp      = ( unsigned short * )&amp;l;
      *( sp ) = 1;
  
      printf( "%lu\n", l );
  
      return 0;
  }
  </code></pre>
  
  <p>In my understanding, the second example also violates the struct aliasing rule.<br>
  So why does it compile? Is it an accuracy issue in GCC, or have I missed
  something with strict aliasing?</p>
  
  <p>I also found the following topic: <strong><a href="https://stackoverflow.com/questions/3817474/why-are-no-strict-aliasing-warnings-generated-for-this-code">Why are no strict-aliasing warnings generated for this code?</a></strong></p>
  
  <p>Compiling with <code>-Wstrict-aliasing=2</code> or <code>-Wstrict-aliasing=3</code> makes no difference.<br>
  But <code>-Wstrict-aliasing=1</code> does report the error on the second example.</p>
  
  <p>GCC documentation says level 1 is the least accurate, and can produce a lot
  of false positives, while level 3 is the most accurate...</p>
  
  <p>So what's happening here? An issue with my own understanding or an issue with GCC?</p>
  
  <p><strong>Bonus question</strong></p>
  
  <p>I usually prefer Clang/LLVM over GCC for my projects, but it seems Clang
  doesn't issue any warning about strict aliasing.<br>
  Does anyone knows why?<br>
  Is it because it is not able to detect violations, or because it does not follow
  the rule when generating code?</p>