[LLVMbugs] [Bug 14154] New: Constant expression with function pointer cannot be used as non-type template argument
bugzilla-daemon at llvm.org
bugzilla-daemon at llvm.org
Tue Oct 23 05:04:37 PDT 2012
http://llvm.org/bugs/show_bug.cgi?id=14154
Bug #: 14154
Summary: Constant expression with function pointer cannot be
used as non-type template argument
Product: clang
Version: trunk
Platform: Macintosh
OS/Version: MacOS X
Status: NEW
Severity: normal
Priority: P
Component: C++11
AssignedTo: unassignedclangbugs at nondot.org
ReportedBy: jonathan.sauer at gmx.de
CC: dgregor at apple.com, llvmbugs at cs.uiuc.edu
Classification: Unclassified
The following program fails to compile with clang r166410:
// Identity function
template <typename T>
constexpr T identity(T t) { return t; }
// Some template
template <typename T, T t>
struct Foo { };
// Overloaded function. Getting its address requires explicit type
// conversion (13.4p1)
static void bar() {}
static void bar(int) {}
using BarPtr = void(*)();
// Show that "identity((BarPtr) &bar)" is a compile-time constant
// expression
static constexpr BarPtr BAR = identity((BarPtr) &bar);
int main()
{
Foo<int, identity(1)> a; // A: Compiles
Foo<BarPtr, &bar> b; // B: Compiles
Foo<BarPtr, (BarPtr) &bar> c; // C: Does not compile
Foo<BarPtr, identity((BarPtr) &bar)> d; // D: Does not compile
}
This results in:
% ~/LLVM/build/Release+Asserts/bin/clang++ -std=c++11 -stdlib=libc++ clang.cpp
clang.cpp:24:17: error: non-type template argument does not refer to any
declaration
Foo<BarPtr, (BarPtr) &bar> c; // C: Does not compile
^~~~~~~~~~~~~
clang.cpp:6:25: note: template parameter is declared here
template <typename T, T t>
^
clang.cpp:25:17: error: non-type template argument does not refer to any
declaration
Foo<BarPtr, identity((BarPtr) &bar)> d; // D: Does not compile
^~~~~~~~~~~~~~~~~~~~~~~
clang.cpp:6:25: note: template parameter is declared here
template <typename T, T t>
^
2 errors generated.
It seems that clang rejects a function pointer as a non-type template parameter
when this function pointer is not used stand-alone, but as part of a bigger
constant expression, which here is either the explicit type cast to select the
correct overload in case C (c.f. 13.4p1 and 5.4), or the call to a constexpr
function in case D. This only seems to happen with function pointers, not with
integral constant expressions, as case A compiles successfully.
According to 14.3.2p1, "a template-argument for a non-type, non-template
template-parameter shall be one of: [...] a constant expression (5.19) that
designates the address of an object with static storage duration and external
or internal linkage or a function with external or internal linkage".
According to 5.19p2, a constant expression can contain constexpr function as
long as some restrictions are met (which they are, as the definition of "BAR"
compiles).
(I am aware that a workaround for case C is to leave out the explicit type
cast, because in that case the correct overload of "bar" is selected via the
type of the non-type template parameter as shown in case B.)
This is possibly related to the (fixed) Bug 9700.
--
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
More information about the llvm-bugs
mailing list