From 8e43da810d60823d33cee7a863e80c6a5b7f2941 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 18 Aug 2015 17:29:01 -0400 Subject: [PATCH] DR 1155 DR 1155 * pt.c (convert_nontype_argument): Allow internal linkage in C++11 and up. From-SVN: r226992 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/pt.c | 8 +++++--- gcc/testsuite/g++.dg/cpp0x/nontype1.C | 9 +++++++++ gcc/testsuite/g++.old-deja/g++.oliva/template4.C | 2 +- 4 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/nontype1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0bf33c8eb6a..2c2cb6d5535 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2015-08-18 Jason Merrill + + DR 1155 + * pt.c (convert_nontype_argument): Allow internal linkage in C++11 + and up. + 2015-08-17 Paolo Carlini PR c++/67216 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b84bda47fd1..eaafaeff569 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6469,16 +6469,18 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { if (complain & tf_error) error ("%qE is not a valid template argument for type %qT " - "because it is not an object with external linkage", + "because it is not an object with linkage", expr, type); return NULL_TREE; } - if (!DECL_EXTERNAL_LINKAGE_P (expr)) + /* DR 1155 allows internal linkage in C++11 and up. */ + linkage_kind linkage = decl_linkage (expr); + if (linkage < (cxx_dialect >= cxx11 ? lk_internal : lk_external)) { if (complain & tf_error) error ("%qE is not a valid template argument for type %qT " - "because object %qD has not external linkage", + "because object %qD does not have linkage", expr, type, expr); return NULL_TREE; } diff --git a/gcc/testsuite/g++.dg/cpp0x/nontype1.C b/gcc/testsuite/g++.dg/cpp0x/nontype1.C new file mode 100644 index 00000000000..29dff363974 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/nontype1.C @@ -0,0 +1,9 @@ +// { dg-do compile { target c++11 } } + +struct L { constexpr operator int() const { return 0; } }; +constexpr L LVar{}; + +template int *f() { return 0; } +template char *f(); + +auto r = f(); // { dg-error "ambiguous" } diff --git a/gcc/testsuite/g++.old-deja/g++.oliva/template4.C b/gcc/testsuite/g++.old-deja/g++.oliva/template4.C index 2268fde400e..ef607f604a2 100644 --- a/gcc/testsuite/g++.old-deja/g++.oliva/template4.C +++ b/gcc/testsuite/g++.old-deja/g++.oliva/template4.C @@ -11,7 +11,7 @@ int a = 1; X x; // ok, a has external linkage const int b = 2; -X y; // { dg-error "" } const b has internal linkage +X y; // { dg-error "" "" { target c++98_only } } const b has internal linkage extern const int c; X z; // ok, c has external linkage -- 2.30.2