svga: Fix a strict-aliasing violation in shader dumper
authorEdward O'Callaghan <funfunctor@folklore1984.net>
Tue, 6 Dec 2016 00:28:56 +0000 (11:28 +1100)
committerEdward O'Callaghan <funfunctor@folklore1984.net>
Wed, 21 Dec 2016 04:00:21 +0000 (15:00 +1100)
As per the C spec, it is illegal to alias pointers to different
types. This results in undefined behaviour after optimization
passes, resulting in very subtle bugs that happen only on a
full moon..

Use a memcpy() as a well defined coercion between the isomorphic
bit-field interpretations of memory.

V.2: Use C99 compat STATIC_ASSERT() over C11 static_assert().

Signed-off-by: Edward O'Callaghan <funfunctor@folklore1984.net>
Reviewed-by: Charmaine Lee <charmainel@vmware.com>
src/gallium/drivers/svga/svgadump/svga_shader_dump.c

index 4ee1bf2c353bb04f9c7fa03a4c1e0aee53fac2b2..46126a5460de43039888cc6e86862499579b6d27 100644 (file)
@@ -30,6 +30,9 @@
  * @author Michal Krol <michal@vmware.com>
  */
 
+#include <assert.h>
+#include <string.h>
+
 #include "svga_shader.h"
 #include "svga_shader_dump.h"
 #include "svga_shader_op.h"
@@ -413,6 +416,11 @@ dump_dstreg(struct sh_dstreg dstreg,
 
 static void dump_srcreg( struct sh_srcreg srcreg, struct sh_srcreg *indreg, const struct dump_info *di )
 {
+   struct sh_reg srcreg_sh = {0};
+   /* bit-fields carefully aligned, ensure they stay that way. */
+   STATIC_ASSERT(sizeof(struct sh_reg) == sizeof(struct sh_srcreg));
+   memcpy(&srcreg_sh, &srcreg, sizeof(srcreg_sh));
+
    switch (srcreg.modifier) {
    case SVGA3DSRCMOD_NEG:
    case SVGA3DSRCMOD_BIASNEG:
@@ -427,7 +435,7 @@ static void dump_srcreg( struct sh_srcreg srcreg, struct sh_srcreg *indreg, cons
    case SVGA3DSRCMOD_NOT:
       _debug_printf( "!" );
    }
-   dump_reg( *(struct sh_reg *) &srcreg, indreg, di );
+   dump_reg(srcreg_sh, indreg, di );
    switch (srcreg.modifier) {
    case SVGA3DSRCMOD_NONE:
    case SVGA3DSRCMOD_NEG: