Bug 20189 - assignment error in inline function
Summary: assignment error in inline function
Status: RESOLVED DUPLICATE of bug 13049
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.3.4
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-02-24 13:54 UTC by Dirk Clemens
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Dirk Clemens 2005-02-24 13:54:46 UTC
This error was similar to bug #20185,
but now it is a C-Programm and not C++


// Postet by dirk@cle-mens.de
// Compiler Error found:
//	gcc (GCC) 3.3.4 (pre 3.3.5 20040809)
//	under SuSE Linux kernel 2.6.8-24.10-default (i386)
//
// This Bug is a little bit different in relation to bug #20184
//
// If this littel programm is compiled with the option -O2
// the assignment in the inline function was wrong.
// If I remove the 'inline' of any of both functions the result is correct.
//
// Compiled with: gcc -Wall error.cpp
//		-> OK, last line of printout: 0000000000000001
//
// Compiled with: gcc -Wall -O2 error.cpp
//		-> ERROR, last line of printout: 080482c500000001
//
// Compiled with: gcc -Wall -O2 error.cpp
//  but without 'inline' for GenData() and/or GetData()
//		-> OK, last line of printout: 0000000000000001
//

#include <stdlib.h>
#include <stdio.h>

typedef unsigned int uint32;
typedef unsigned long long uint64;

struct data
{
    uint32 lo;
    uint32 hi;
};

inline struct data * GenData ( struct data * d, uint32 num )
{
    d->lo = num; d->hi = -(num<0);
    return d;
}

inline uint64 GetData ( const struct data * d )
{
    return *(uint64*)&d->lo;
}

int main ( int argc, char ** argv )
{ 
    printf("sizeof(uint32)=%d\n",sizeof(uint32));
    printf("sizeof(uint64)=%d\n",sizeof(uint64));
    printf("sizeof(data)=  %d\n",sizeof(struct data));

    uint32 tab[] = { 1,1,1,1,1 };
    uint32 *p = tab;

    struct data D;
    printf("D=%p lo=%p hi=%p\n",&D,&D.lo,&D.hi);

    uint64 u64 = GetData(GenData(&D,*p++));
    printf("%016llx\n",u64);

    return 0;
}
Comment 1 Andrew Pinski 2005-02-24 14:04:34 UTC
Invalid you are violating C90/C99 aliasing rules.
Comment 2 Dirk Clemens 2005-02-26 10:35:27 UTC
(In reply to comment #1)
> Invalid you are violating C90/C99 aliasing rules.

Ok. But where is the compiler warning?

The dokumentation of gcc says: (man gcc)
-Wstrict-aliasing
 This option is only active when -fstrict-aliasing is active.  It
 warns about code which might break the strict aliasing rules that
 the compiler is using for optimization. The warning does not
 catch all cases, but does attempt to catch the more common pit&#8208;
 falls. It is included in -Wall.

But the compiler don't give any warning!
And this is a compiler error in category warnings.

P.S.: I have minimized the Programm that shows this error:

#include <stdlib.h>
#include <stdio.h>

typedef unsigned int uint32;
typedef unsigned long long uint64;

struct data
{
    uint32 lo;
    uint32 hi;
};

inline uint64 GetData ( const struct data * d )
{
    const uint64 *p = (uint64*)d; // <<<<<<<<<<<<<<<<<<<<
    return *p;
}

int main( int argc, char ** argv )
{
    struct data D = {1,2};
    uint64 u64 = GetData(&D);
    printf("%016llx\n",u64);
    return 0;
}
Comment 3 Andrew Pinski 2005-02-26 14:26:41 UTC
Because that would be PR 13049.

*** This bug has been marked as a duplicate of 13049 ***