Bug 89878 - same specializations on a zero-initialized struct object as a non-type parameter treated as distinct
Summary: same specializations on a zero-initialized struct object as a non-type parame...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: 9.0
Assignee: Martin Sebor
URL:
Keywords: ABI, accepts-invalid, patch, rejects-valid
Depends on:
Blocks:
 
Reported: 2019-03-28 23:48 UTC by Martin Sebor
Modified: 2019-04-04 23:16 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-04-03 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2019-03-28 23:48:03 UTC
While testing a patch for bug 89833 I noticed that the C++ 2a test case below is accepted even though it redefines the same function f() three times, each time taking an argument of the same type: B<A()>, with the only difference between them being the form of initialization of the non-type parameter.  The mangling of each of the functions is also distinct when it should be the same.

$ cat u.C && gcc -c -Wall -Wextra -std=c++2a u.C && nm u.o
struct A { int a[3]; };

template <A> struct B { };

void f (B<A{ }>) { }
void f (B<A{ 0 }>) { }
void f (B<A{ 0, 0 }>) { }
void f (B<A{ 0, 0, 0 }>) { }
0000000000000000 T _Z1f1BIXtl1AEEE
0000000000000010 T _Z1f1BIXtl1AtlA3_iLi0EEEEE
0000000000000020 T _Z1f1BIXtl1AtlA3_iLi0ELi0EEEEE
0000000000000030 T _Z1f1BIXtl1AtlA3_iLi0ELi0ELi0EEEEE
Comment 1 Martin Sebor 2019-03-31 21:36:51 UTC
The converse of accepting multiple definitions of the same symbol is that valid redeclarations of the same symbol are rejected as shown in the test case below:

$ cat z.C && gcc -c -Wall -std=c++2a z.C
struct A1 { char c[5]; };

template <A1> struct B { };

typedef B<A1{ { 'A' } }>              A_A____;
typedef B<A1{ { 'A', 0 } }>           A_AZ___;
typedef B<A1{ { 'A', 0, 0 } }>        A_AZZ__;
typedef B<A1{ { 'A', 0, 0, 0 } }>     A_AZZZ_;
typedef B<A1{ { 'A', 0, 0, 0, 0 } }>  A_AZZZZ;

extern A_A____ same_type_B_A1_A;
extern A_AZ___ same_type_B_A1_A;
extern A_AZZ__ same_type_B_A1_A;
extern A_AZZZ_ same_type_B_A1_A;
extern A_AZZZZ same_type_B_A1_A;
z.C:12:16: error: conflicting declaration ‘A_AZ___ same_type_B_A1_A’
   12 | extern A_AZ___ same_type_B_A1_A;
      |                ^~~~~~~~~~~~~~~~
z.C:11:16: note: previous declaration as ‘A_A____ same_type_B_A1_A’
   11 | extern A_A____ same_type_B_A1_A;
      |                ^~~~~~~~~~~~~~~~
z.C:13:16: error: conflicting declaration ‘A_AZZ__ same_type_B_A1_A’
   13 | extern A_AZZ__ same_type_B_A1_A;
      |                ^~~~~~~~~~~~~~~~
z.C:11:16: note: previous declaration as ‘A_A____ same_type_B_A1_A’
   11 | extern A_A____ same_type_B_A1_A;
      |                ^~~~~~~~~~~~~~~~
z.C:14:16: error: conflicting declaration ‘A_AZZZ_ same_type_B_A1_A’
   14 | extern A_AZZZ_ same_type_B_A1_A;
      |                ^~~~~~~~~~~~~~~~
z.C:11:16: note: previous declaration as ‘A_A____ same_type_B_A1_A’
   11 | extern A_A____ same_type_B_A1_A;
      |                ^~~~~~~~~~~~~~~~
z.C:15:16: error: conflicting declaration ‘A_AZZZZ same_type_B_A1_A’
   15 | extern A_AZZZZ same_type_B_A1_A;
      |                ^~~~~~~~~~~~~~~~
z.C:11:16: note: previous declaration as ‘A_A____ same_type_B_A1_A’
   11 | extern A_A____ same_type_B_A1_A;
      |                ^~~~~~~~~~~~~~~~
Comment 2 Martin Sebor 2019-04-03 15:16:32 UTC
Patch: https://gcc.gnu.org/ml/gcc-patches/2019-04/msg00000.html
Comment 3 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 4 Martin Sebor 2019-04-04 23:16:15 UTC
Fixed in r270155.