Bug 47488 - sorry, unimplemented: string literal in function template signature
Summary: sorry, unimplemented: string literal in function template signature
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: 9.0
Assignee: Jason Merrill
URL:
Keywords: ABI, patch, rejects-valid
Depends on:
Blocks:
 
Reported: 2011-01-27 10:11 UTC by Kohei Takahashi
Modified: 2019-04-04 23:13 UTC (History)
10 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.6.0, 4.8.5, 4.9.4, 5.4.0, 6.4.0, 7.3.0, 8.3.0
Last reconfirmed: 2019-03-27 00:00:00


Attachments
test code (111 bytes, text/plain)
2011-01-27 10:11 UTC, Kohei Takahashi
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Kohei Takahashi 2011-01-27 10:11:43 UTC
Created attachment 23139 [details]
test code

compiler output:
$ g++-4.5 -std=c++0x testcase.cpp
testcase.cpp: In instantiation of 'decltype (int f(T(), "")) g(const T&) [with T = int, decltype (f(T(), "")) = int]':
testcase.cpp:9:11:   instantiated from here
testcase.cpp:5:26: internal compiler error: in write_template_arg_literal, at cp/mangle.c:2687
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

tested version:
4.4.4-14ubuntu5 - Crash
4.5.1 - Crash
4.5.2 - Crash
4.5.6 20110127 - Crash
Comment 1 Jonathan Wakely 2011-01-27 10:56:52 UTC
This c++98 variation using sizeof instead of decltype gives an ICE in the same place:

template < typename T >
int f( const T &, const char * );

template<int> struct N { };

template < typename T >
N<sizeof( f( T(), "" ) )> g( const T &t );

void h()
{
    g( 0 );
}


This is a regression since 4.1 which doesn't ICE:

testcase.cpp: In function 'void h()':
testcase.cpp:11: sorry, unimplemented: call_expr cannot be mangled due to a defect in the C++ ABI
Comment 2 Jonathan Wakely 2011-01-27 11:09:50 UTC
For this variation where f<T> is not deduced, 4.4 says "sorry, unimplemented" but doesn't ICE, 4.5 and 4.6 ICE in the same place:

template < typename T >
int f( const char * );

template<int> struct N { };

template < typename T >
N<sizeof( f<T>( "" ) )> g( const T &t );

void h()
{
    g( 0 );
}
Comment 3 H.J. Lu 2011-01-27 20:17:06 UTC
(In reply to comment #2)
> For this variation where f<T> is not deduced, 4.4 says "sorry, unimplemented"
> but doesn't ICE, 4.5 and 4.6 ICE in the same place:
> 
> template < typename T >
> int f( const char * );
> 
> template<int> struct N { };
> 
> template < typename T >
> N<sizeof( f<T>( "" ) )> g( const T &t );
> 
> void h()
> {
>     g( 0 );
> }

It is caused by revision 140120:

http://gcc.gnu.org/ml/gcc-cvs/2008-09/msg00279.html
Comment 4 H.J. Lu 2011-01-27 20:19:23 UTC
(In reply to comment #1)
> This c++98 variation using sizeof instead of decltype gives an ICE in the same
> place:
> 
> template < typename T >
> int f( const T &, const char * );
> 
> template<int> struct N { };
> 
> template < typename T >
> N<sizeof( f( T(), "" ) )> g( const T &t );
> 
> void h()
> {
>     g( 0 );
> }
> 
> 

It is also caused by revision 140120:

http://gcc.gnu.org/ml/gcc-cvs/2008-09/msg00279.html
Comment 5 Jason Merrill 2011-03-08 17:06:20 UTC
So, the basic problem is that we still don't know how to mangle string constants, it just changed from a sorry to an ICE.  There was a mangling proposed on the ABI list, but while looking at it I realized that it isn't sufficient--it produces a multiply defined symbol for

template <typename T> constexpr T f(const T* p) { return p[0]; }
template<int> struct N { };
template <typename T> void g(T, N<f((const T*)"1")>) { }
template <typename T> void g(T, N<f((const T*)"2")>) { }

int main()
{
  g('1', N<'1'>());
  g('2', N<'2'>());
}
Comment 6 Jason Merrill 2011-03-08 17:30:54 UTC
Author: jason
Date: Tue Mar  8 17:30:46 2011
New Revision: 170783

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170783
Log:
	PR c++/47488
	* mangle.c (write_template_arg_literal) [STRING_CST]: Sorry.

Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/mangle.c
Comment 7 Jason Merrill 2011-03-08 17:31:11 UTC
I've checked in a patch to restore the sorry, but we still need to implement a mangling.
Comment 8 Jason Merrill 2011-03-08 17:39:16 UTC
Author: jason
Date: Tue Mar  8 17:39:10 2011
New Revision: 170785

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170785
Log:
	PR c++/47488
	* mangle.c (write_template_arg_literal) [STRING_CST]: Sorry.

Modified:
    branches/gcc-4_4-branch/gcc/cp/ChangeLog
    branches/gcc-4_4-branch/gcc/cp/mangle.c
Comment 9 Jason Merrill 2011-03-08 17:40:33 UTC
Author: jason
Date: Tue Mar  8 17:40:27 2011
New Revision: 170786

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170786
Log:
	PR c++/47488
	* mangle.c (write_template_arg_literal) [STRING_CST]: Sorry.

Modified:
    branches/gcc-4_5-branch/gcc/cp/ChangeLog
    branches/gcc-4_5-branch/gcc/cp/mangle.c
Comment 10 Jakub Jelinek 2011-03-25 19:52:12 UTC
GCC 4.6.0 is being released, adjusting target milestone.
Comment 11 Jeremiah Willcock 2013-11-05 22:02:05 UTC
This problem still exists as of GCC 4.9.0 snapshot 20131013, with the same test case failing.
Comment 12 sergey.ignatchenko 2018-02-11 13:25:04 UTC
FWIW, the same test case still fails under GCC 7.2.0. Moreover, I ran into something-very-similar when playing with constexpr-function-of-string-literal-as-a-template-parameter; IMO, with advent of C++17 and constexpr functions this bug started to be significantly more important - please consider raising priority. 

Oh, and it does compile under Clang (at least Apple Clang 9.0.0).
Comment 13 Jonathan Wakely 2019-03-27 10:44:06 UTC
Clang edn EDG both accept the examples in comment 1 and comment 2, producing the same symbols.

For comment 1 they emit _Z1gIiE1NIXszcl1fcvT__ELA1_KcEEEERKS1_
For comment 2 they emit _Z1gIiE1NIXszcl1fIT_ELA1_KcEEEERKS1_

They both reject comment 5.

Clang says:

c5.cc:4:28: error: definition with same mangled name '_Z1gIcEvT_1NIXcl1fcvPKS0_LA2_KcEEEE' as another definition
template <typename T> void g(T, N<f((const T*)"2")>) { }
                           ^
c5.cc:3:28: note: previous definition is here
template <typename T> void g(T, N<f((const T*)"1")>) { }
                           ^
1 error generated.

And EDG says:

eccp: diagnostics generated from compilation of c5.int.c:
c5.cc:4:96: error: conflicting types for ‘_Z1gIcEvT_1NIXcl1fcvPKS0_LA2_KcEEEE’
 template <typename T> void g(T, N<f((const T*)"2")>) { }
                                                                                                ^                                  
c5.cc:3:96: note: previous declaration of ‘_Z1gIcEvT_1NIXcl1fcvPKS0_LA2_KcEEEE’ was here
 template <typename T> void g(T, N<f((const T*)"1")>) { }
                                                                                                ^                                  
c5.cc: In function ‘main’:
c5.cc:8:49: error: incompatible type for argument 2 of ‘_Z1gIcEvT_1NIXcl1fcvPKS0_LA2_KcEEEE’
   g('1', N<'1'>());
                                                 ^          
c5.cc:4:138: note: expected ‘struct _Z1NILi50EE’ but argument is of type ‘struct _Z1NILi49EE’
 template <typename T> void g(T, N<f((const T*)"2")>) { }
                                                                                                                                          ^                 
c5.cc: At top level:
c5.cc:4:89: error: conflicting types for ‘_Z1gIcEvT_1NIXcl1fcvPKS0_LA2_KcEEEE’
 template <typename T> void g(T, N<f((const T*)"2")>) { }
                                                                                         ^                                  
c5.cc:3:89: note: previous definition of ‘_Z1gIcEvT_1NIXcl1fcvPKS0_LA2_KcEEEE’ was here
 template <typename T> void g(T, N<f((const T*)"1")>) { }
                                                                                         ^                                  
eccp: end of diagnostics from compilation of c5.int.c
eccp: gcc compilation of c5.int.c returned an exit status of 1
Comment 14 Martin Sebor 2019-04-03 15:12:53 UTC
Patch: https://gcc.gnu.org/ml/gcc-patches/2019-04/msg00000.html
Comment 15 Martin Sebor 2019-04-04 23:10:54 UTC
Author: msebor
Date: Thu Apr  4 23:10:23 2019
New Revision: 270155

URL: https://gcc.gnu.org/viewcvs?rev=270155&root=gcc&view=rev
Log:
PR c++/89974 - ICE on a definition of a non-type specialization on a struct object with pointer to member function
PR c++/89878 - same specializations on a zero-initialized struct object as a non-type parameter treated as distinct
PR c++/89833 - sorry, unimplemented: string literal in function template signature
PR c++/47488 - sorry, unimplemented: string literal in function template signature

gcc/cp/ChangeLog:

	PR c++/89974
	PR c++/89878
	PR c++/89833
	PR c++/47488
	* decl.c (reshape_init_array_1): Strip trailing zero-initializers
	from arrays of trivial type and known size.
	* mangle.c (write_expression): Convert braced initializer lists
	to STRING_CSTs.
	(write_expression): Trim trailing zero-initializers from arrays
	of trivial type.
	(write_template_arg_literal): Mangle strings the same as braced
	initializer lists.

gcc/testsuite/ChangeLog:

	PR c++/89974
	PR c++/89878
	PR c++/89833
	PR c++/47488
	* gcc/testsuite/g++.dg/abi/mangle69.C: New test.
	* gcc/testsuite/g++.dg/abi/mangle70.C: New test.
	* gcc/testsuite/g++.dg/abi/mangle71.C: New test.
	* gcc/testsuite/g++.dg/abi/mangle72.C: New test.
	* gcc/testsuite/g++.dg/cpp0x/constexpr-array19.C: New test.
	* gcc/testsuite/g++.dg/cpp2a/nontype-class15.C: New test.
	* gcc/testsuite/g++.dg/cpp2a/nontype-class16.C: New test.
	* gcc/testsuite/g++.dg/init/array51.C: New test.


Added:
    trunk/gcc/testsuite/g++.dg/abi/mangle69.C
    trunk/gcc/testsuite/g++.dg/abi/mangle70.C
    trunk/gcc/testsuite/g++.dg/abi/mangle71.C
    trunk/gcc/testsuite/g++.dg/abi/mangle72.C
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-array19.C
    trunk/gcc/testsuite/g++.dg/cpp2a/nontype-class15.C
    trunk/gcc/testsuite/g++.dg/cpp2a/nontype-class16.C
    trunk/gcc/testsuite/g++.dg/init/array51.C
    trunk/gcc/testsuite/g++.dg/template/nontype29.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/decl.c
    trunk/gcc/cp/mangle.c
    trunk/gcc/testsuite/ChangeLog
Comment 16 Martin Sebor 2019-04-04 23:13:20 UTC
Fixed in GCC 9.