Project

General

Profile

Actions

Bug #7187

open

using signbit with optimisation > -O1 gives dereferencing type-punned pointer will break strict-aliasing rules

Added by Richard PALO almost 8 years ago. Updated almost 8 years ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
-
Start date:
2016-07-17
Due date:
% Done:

0%

Estimated time:
Difficulty:
Medium
Tags:
needs-triage
Gerrit CR:
External Bug:

Description

simple test program picked from libgo in gcc5.4:

richard@omnis:/home/richard/src/tsignbit$ cat tsignbit.c
#include <stdio.h>
#include <math.h>

void
runtime_printfloat(double v)
{
    if(isinf(v)) {
        if(signbit(v)) {
            printf("-Inf\n");
        } else {
            printf("+Inf\n");
        }
    }
    return;
}

problem demonstrated with gcc4.8 from omnios, but is similar with all gcc tested:

richard@omnis:/home/richard/src/tsignbit$ /opt/gcc-4.8.1/bin/gcc -std=gnu99  -Wall -c tsignbit.c 
richard@omnis:/home/richard/src/tsignbit$ /opt/gcc-4.8.1/bin/gcc -std=gnu99  -Wall -c tsignbit.c -O1
richard@omnis:/home/richard/src/tsignbit$ /opt/gcc-4.8.1/bin/gcc -std=gnu99  -Wall -c tsignbit.c -O2
tsignbit.c: In function ‘runtime_printfloat’:
tsignbit.c:8:3: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
   if(signbit(v)) {
   ^

there must be a better way than the resulting code (extracted from -save-temps):

void
runtime_printfloat(double v)
{
 if(__builtin_isinf(v)) {
  if(__extension__( { __typeof(v) __x_s = (v); (sizeof (__x_s) == sizeof (float) ? (int) (*(unsigned *) &__x_s >> 31) : sizeof (__x_s) == sizeof (double) ? (int) (((unsigned *) &__x_s)[1] >> 31) : (int) (((unsigned short *) &__x_s)[4] >> 15)); })) {
   printf("-Inf\n");
  } else {
   printf("+Inf\n");
  }
 }
 return;
}

Actions

Also available in: Atom PDF