[LLVMbugs] [Bug 18495] New: Unexpected template recursion limit hit for partially-specialized member template

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Wed Jan 15 14:37:29 PST 2014


http://llvm.org/bugs/show_bug.cgi?id=18495

            Bug ID: 18495
           Summary: Unexpected template recursion limit hit for
                    partially-specialized member template
           Product: clang
           Version: 3.3
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++11
          Assignee: unassignedclangbugs at nondot.org
          Reporter: lhyatt at gmail.com
                CC: dgregor at apple.com, llvmbugs at cs.uiuc.edu
    Classification: Unclassified

===========================
template<typename S, typename... T> struct X {
    template<bool stop = (sizeof...(T) >= 10), typename = void>
    struct Next {
        typedef typename X<S, T..., void>::type type;
    };
    typedef typename Next<>::type type;
};

template<typename S, typename... T>
template<typename U>
struct X<S, T...>::Next<true, U> {
    typedef S type;
};

static_assert(sizeof(X<double>::type) == sizeof(double), "");
===========================

I believe this should be a valid program, the template recursion should stop
after 10 instantiations when the partial specialization comes into play and be
OK. clang 3.3 recurses indefinitely until it hits whatever limit you give it.
g++ 4.7 works as expected. clang also works fine if I switch to make the
non-recursing Next<true> the primary template, and the recursing Next<false>
the partial specialization defined outside the class:

(works fine):
===========================
template<typename S, typename... T> struct X {
    template<bool stop = (sizeof...(T) >= 10), typename = void>
    struct Next {
        typedef S type;
    };
    typedef typename Next<>::type type;
};

template<typename S, typename... T>
template<typename U>
struct X<S, T...>::Next<false, U> {
    typedef typename X<S, T..., void>::type type;
};

static_assert(sizeof(X<double>::type) == sizeof(double), "");
===========================

So I guess it's a question of whether clang is incorrect in instantiating the
primary template that causes the indefinite recursion rather than the partial
specialization that applies, or g++ is incorrect in failing to do so...

-- 
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/20140115/6cbccbb8/attachment.html>


More information about the llvm-bugs mailing list