Commit 4774d267 by Jason Merrill Committed by Jason Merrill

re PR c++/50372 ([C++0x] pointers to static functions should be valid template parameters)

	PR c++/50372
	* pt.c (convert_nontype_argument_function): Allow decls with
	internal linkage in C++11.
	(convert_nontype_argument): Likewise.

From-SVN: r181280
parent 5e3929ed
2011-11-10 Jason Merrill <jason@redhat.com>
PR c++/50372
* pt.c (convert_nontype_argument_function): Allow decls with
internal linkage in C++11.
(convert_nontype_argument): Likewise.
PR c++/50973
* decl2.c (mark_used): Defer synthesis of virtual functions.
* method.c (use_thunk): Make sure the target function has
......
......@@ -5324,6 +5324,7 @@ convert_nontype_argument_function (tree type, tree expr)
{
tree fns = expr;
tree fn, fn_no_ptr;
linkage_kind linkage;
fn = instantiate_type (type, fns, tf_none);
if (fn == error_mark_node)
......@@ -5340,12 +5341,19 @@ convert_nontype_argument_function (tree type, tree expr)
A template-argument for a non-type, non-template template-parameter
shall be one of:
[...]
-- the address of an object or function with external linkage. */
if (!DECL_EXTERNAL_LINKAGE_P (fn_no_ptr))
-- the address of an object or function with external [C++11: or
internal] linkage. */
linkage = decl_linkage (fn_no_ptr);
if (cxx_dialect >= cxx0x ? linkage == lk_none : linkage != lk_external)
{
error ("%qE is not a valid template argument for type %qT "
"because function %qD has not external linkage",
expr, type, fn_no_ptr);
if (cxx_dialect >= cxx0x)
error ("%qE is not a valid template argument for type %qT "
"because %qD has no linkage",
expr, type, fn_no_ptr);
else
error ("%qE is not a valid template argument for type %qT "
"because %qD does not have external linkage",
expr, type, fn_no_ptr);
return NULL_TREE;
}
......@@ -5838,13 +5846,20 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
expr, type, decl);
return NULL_TREE;
}
else if (!DECL_EXTERNAL_LINKAGE_P (decl))
else if (cxx_dialect < cxx0x && !DECL_EXTERNAL_LINKAGE_P (decl))
{
error ("%qE is not a valid template argument of type %qT "
"because %qD does not have external linkage",
expr, type, decl);
return NULL_TREE;
}
else if (cxx_dialect >= cxx0x && decl_linkage (decl) == lk_none)
{
error ("%qE is not a valid template argument of type %qT "
"because %qD has no linkage",
expr, type, decl);
return NULL_TREE;
}
}
expr = decay_conversion (expr);
......
2011-11-10 Jason Merrill <jason@redhat.com>
* g++.dg/template/linkage1.C: New.
* g++.dg/ext/visibility/anon8.C: Adjust for C++11.
* g++.old-deja/g++.other/linkage4.C: Likewise.
PR c++/50973
* g++.dg/cpp0x/defaulted33.C: New.
......
......@@ -26,10 +26,8 @@ int main ()
static void fn2 () {}
};
call<&B1::fn1> ();
call<&B2::fn2> (); // { dg-error "not external linkage|no matching" }
// { dg-message "candidate" "candidate note" { target *-*-* } 29 }
call<&B2::fn2> (); // { dg-error "linkage|no matching" }
call<&fn3> ();
call<&B1::fn4> ();
call<&fn5> (); // { dg-error "not external linkage|no matching" }
// { dg-message "candidate" "candidate note" { target *-*-* } 33 }
call<&fn5> (); // { dg-error "linkage|no matching" "" { target c++98 } }
}
......@@ -2,4 +2,4 @@
template <const int*> class Helper { };
const int foo = 0;
typedef Helper<&foo> HelperType; // { dg-error "linkage|type" }
typedef Helper<&foo> HelperType; // { dg-error "linkage|type" "" { target c++98 } }
// PR c++/50372
// Test that a template instantiation has the same linkage as its argument.
// { dg-final { scan-assembler "(weak|glob)\[^\n\]*_Z3fooIXadL_Z13external_funcvEEEvv" } }
// { dg-final { scan-assembler-not "(weak|glob)\[^\n\]*_Z3fooIXadL_ZL11static_funcvEEEvv" } }
template<void (*fptr)(void)>
void foo() { }
static void static_func() {}
void external_func() { }
void test()
{
#if __cplusplus > 199711L
foo<&static_func>();
#endif
foo<&external_func>();
}
......@@ -8,4 +8,4 @@ void f () {}
// Check that the strlen declaration here is given internal linkage by
// using it as a non-type template argument, and expecting an error.
template void f<strlen>(); // { dg-error "" } no matching template
template void f<strlen>(); // { dg-error "" "" { target c++98 } } no matching template
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment