Bug 103954 - GCC did not generate correct code for template function with O2
Summary: GCC did not generate correct code for template function with O2
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.2.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-01-09 15:54 UTC by Ming Zhi
Modified: 2022-01-10 01:00 UTC (History)
0 users

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


Attachments
gcc version, command line option, .ii file and a detailed issue description (413.31 KB, application/gzip)
2022-01-09 15:54 UTC, Ming Zhi
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ming Zhi 2022-01-09 15:54:27 UTC
Created attachment 52147 [details]
gcc version, command line option, .ii file and a detailed issue description

I have encountered an optimization issue with O2 option.

A variable is expected to change after a function call. but the compiler did not generate the function correctly, more precisely the function is an inline function, which calls a template function, but the code for the inner template function was not generated.

The compiler seems to assume the variable keep unchanged through the call, and optimized out the template function body.

This issue happens only with O2 option. O0 and O1 are OK.
Comment 1 Andrew Pinski 2022-01-09 16:22:24 UTC

enum EnumSeriProto : guint32
{
    seriNone = 0,
    seriRidl = 1,
    seriPython = 2,
    seriJava = 3,
    seriInvalid = 4
};

....


        EnumSeriProto dwSeriProto = seriNone;
        ret = GetSeriProto( pResp, dwSeriProto );

...
    return oCfg.GetIntProp(
        propSeriProto, ( guint32& )dwSeriProto );
...
    gint32 GetIntProp( gint32 iProp, guint32& val ) const
    {
        return GetPrimProp( iProp, val );
    }
...
    template< typename PrimType, ... >
    gint32 GetPrimProp(
        gint32 iProp, PrimType& val ) const
    {
        gint32 ret = 0;
        if( m_pConstCfg == nullptr )
            return -
# 1212 "/usr/local/include/rpcf/configdb.h" 3 4
                   14
# 1212 "/usr/local/include/rpcf/configdb.h"
                         ;

        auto pdb2 = static_cast< const CConfigDb2* const >( m_pConstCfg );
        do{
            const Variant* p =
                pdb2->GetPropertyPtr( iProp );
            if( p == nullptr )
            {
                ret = -
# 1220 "/usr/local/include/rpcf/configdb.h" 3 4
                      2
# 1220 "/usr/local/include/rpcf/configdb.h"
                            ;
                break;
            }
            val = *p;

        }while( 0 );

        return ret;
    }


enum types don't alias the underlaying type and therefore this code is undefined at runtime.
Use Either a memcpy (or an union) inside GetSeriProto or use -fno-strict-aliasing.
Comment 2 Ming Zhi 2022-01-10 01:00:25 UTC
thanks for your great answer! I did not know the effect of strict aliasing till today. It looks I need to update my knowledge base about c++ right now.

Get Outlook for Android<https://aka.ms/AAb9ysg>
________________________________
From: pinskia at gcc dot gnu.org <gcc-bugzilla@gcc.gnu.org>
Sent: Monday, January 10, 2022 12:22:24 AM
To: woodhead99@gmail.com <woodhead99@gmail.com>
Subject: [Bug c++/103954] GCC did not generate correct code for template function with O2

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103954

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |INVALID
             Status|UNCONFIRMED                 |RESOLVED

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---


enum EnumSeriProto : guint32
{
    seriNone = 0,
    seriRidl = 1,
    seriPython = 2,
    seriJava = 3,
    seriInvalid = 4
};

....


        EnumSeriProto dwSeriProto = seriNone;
        ret = GetSeriProto( pResp, dwSeriProto );

...
    return oCfg.GetIntProp(
        propSeriProto, ( guint32& )dwSeriProto );
...
    gint32 GetIntProp( gint32 iProp, guint32& val ) const
    {
        return GetPrimProp( iProp, val );
    }
...
    template< typename PrimType, ... >
    gint32 GetPrimProp(
        gint32 iProp, PrimType& val ) const
    {
        gint32 ret = 0;
        if( m_pConstCfg == nullptr )
            return -
# 1212 "/usr/local/include/rpcf/configdb.h" 3 4
                   14
# 1212 "/usr/local/include/rpcf/configdb.h"
                         ;

        auto pdb2 = static_cast< const CConfigDb2* const >( m_pConstCfg );
        do{
            const Variant* p =
                pdb2->GetPropertyPtr( iProp );
            if( p == nullptr )
            {
                ret = -
# 1220 "/usr/local/include/rpcf/configdb.h" 3 4
                      2
# 1220 "/usr/local/include/rpcf/configdb.h"
                            ;
                break;
            }
            val = *p;

        }while( 0 );

        return ret;
    }


enum types don't alias the underlaying type and therefore this code is
undefined at runtime.
Use Either a memcpy (or an union) inside GetSeriProto or use
-fno-strict-aliasing.

--
You are receiving this mail because:
You reported the bug.