[LLVMbugs] [Bug 24048] New: Unexpected result for a type counter using templates with function local types in Clang

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon Jul 6 16:56:18 PDT 2015


https://llvm.org/bugs/show_bug.cgi?id=24048

            Bug ID: 24048
           Summary: Unexpected result for a type counter using templates
                    with function local types in Clang
           Product: clang
           Version: 3.6
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++11
          Assignee: unassignedclangbugs at nondot.org
          Reporter: prismatic.project at gmail.com
                CC: dgregor at apple.com, llvmbugs at cs.uiuc.edu
    Classification: Unclassified

I wrote a class template that increments a static counter integer based on the
template parameters. Clang produces differing output based on whether or not
the template parameters are global or function local types. The output with
function local types seems wrong. GCC and MSVC do not produce this behavior.

The code was compiled with:
clang++ -std=c++11 -O2 -Wall -pedantic -pthread main.cpp && ./a.out

// == Code == //

#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <cstdlib>
#include <typeinfo>

using uint = unsigned int;

template<typename SK,typename T>
struct Component
{
    static uint const index;
};

template<typename SK>
class ComponentCount
{
    template<typename CSK,typename CT>
    friend struct Component;

private:
    template<typename T>
    static uint next() {
        return ComponentCount<SK>::get_counter();
    }

    static uint get_counter()
    {
        static uint counter = 0;
        return counter++;
    }
};

template<typename SK,typename T>
uint const Component<SK,T>::index(ComponentCount<SK>::template next<T>());

// global scope
struct X {};
struct Y {};

int main()
{
    // function scope
    struct Z{};

    uint x0 = Component<X,int>::index;
    uint x1 = Component<X,double>::index;
    uint x2 = Component<X,double>::index;
    uint x3 = Component<X,std::string>::index;
    uint x4 = Component<X,int>::index;
    uint x5 = Component<X,int>::index;

    std::cout << x0 << ", " << x1 << ", " << x2 << ", "
              << x3 << ", " << x4 << ", " << x5 << std::endl;

    uint y0 = Component<Y,int>::index;
    uint y1 = Component<Y,double>::index;
    uint y2 = Component<Y,double>::index;
    uint y3 = Component<Y,std::string>::index;
    uint y4 = Component<Y,int>::index;
    uint y5 = Component<Y,int>::index;

    std::cout << y0 << ", " << y1 << ", " << y2 << ", "
              << y3 << ", " << y4 << ", " << y5 << std::endl;

    uint z0 = Component<Z,int>::index;
    uint z1 = Component<Z,double>::index;
    uint z2 = Component<Z,double>::index;
    uint z3 = Component<Z,std::string>::index;
    uint z4 = Component<Z,int>::index;
    uint z5 = Component<Z,int>::index;

    std::cout << z0 << ", " << z1 << ", " << z2 << ", "
              << z3 << ", " << z4 << ", " << z5 << std::endl;

    return 0;
}

// == Expected output == //

Each of the three cout statements should print out:
0, 1, 1, 2, 0, 0

When compiled with clang, the last statement (using the function local type
'Z') prints out:
5, 2, 2, 3, 5, 5

A reference example that can be run in-browser can be found here (link may not
be permanent)

http://coliru.stacked-crooked.com/a/7fcb989ae6eab476

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150706/f0a68747/attachment.html>


More information about the llvm-bugs mailing list