[Bug c++/83258] Rejecting function pointer non-type template parameter without linkage

redi at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Mar 20 14:54:00 GMT 2018


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83258

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
With this patch:

--- a/gcc/cp/pt.c                                                               
+++ b/gcc/cp/pt.c                                                               
@@ -6259,7 +6259,8 @@ convert_nontype_argument_function (tree type, tree expr,  
     }                                                                          

   linkage = decl_linkage (fn_no_ptr);                                          
-  if (cxx_dialect >= cxx11 ? linkage == lk_none : linkage != lk_external)      
+  if ((cxx_dialect < cxx11 && linkage != lk_external)
+      || (cxx_dialect < cxx17 && linkage == lk_none))
     {
       if (complain & tf_error)
        {

We accept Barry's testcase in C++17 mode.

I think we also need this for some non-type arguments without linkage:


@@ -6979,7 +6980,8 @@ convert_nontype_argument (tree type, tree expr,
tsubst_flags_t complain)

          /* 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 ((cxx_dialect < cxx11 && linkage < lk_external)
+             || (cxx_dialect < cxx17 && linkage < lk_internal))
            {
              if (complain & tf_error)
                error ("%qE is not a valid template argument for type %qT "


but that second change causes a new ice-on-invalid for this in C++17 mode (but
seems to correctly compile it when VALID is defined):


template <typename T, const T &val> struct TestClass
{
  TestClass() : _val(val) { }
  T _val;
};

extern constexpr float e = 2.72;    // external linkage
static constexpr float pi = 3.14;   // internal linkage

int main()
{
#ifdef VALID
  static
#endif
  constexpr float one = 1; // no linkage

  TestClass<float, e> test1;

  TestClass<float, pi> test2;

  TestClass<float, one> test3;
}


linkage.cc: In constructor 'TestClass<T, val>::TestClass() [with T = float;
const T& val = one]':
linkage.cc:3:3: error: Local declaration from a different function
   TestClass() : _val(val) { }
   ^~~~~~~~~
one
linkage.cc:3:25: note: in statement
   TestClass() : _val(val) { }
                         ^
one.2_1 = one;
during GIMPLE pass: cfg
linkage.cc:3:3: internal compiler error: verify_gimple failed
   TestClass() : _val(val) { }
   ^~~~~~~~~
0xdfad0d verify_gimple_in_cfg(function*, bool)
        /home/jwakely/src/gcc/gcc/gcc/tree-cfg.c:5579
0xcc6956 execute_function_todo
        /home/jwakely/src/gcc/gcc/gcc/passes.c:1994
0xcc79d2 execute_todo
        /home/jwakely/src/gcc/gcc/gcc/passes.c:2048
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.


More information about the Gcc-bugs mailing list