public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: C++ PATCH for c++/44282 (ia32 calling convention attributes and mangling)
@ 2015-06-02  7:31 Uros Bizjak
  2015-06-02 11:07 ` Uros Bizjak
  0 siblings, 1 reply; 7+ messages in thread
From: Uros Bizjak @ 2015-06-02  7:31 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill

Hello!

>    PR c++/44282
>    gcc/cp/
>    * mangle.c (attr_strcmp): New.
>    (write_CV_qualifiers_for_type): Also write out attributes that
>    affect type identity.
>    (write_type): Strip all attributes after writing qualifiers.
>    libiberty/
>    * cp-demangle.c (cplus_demangle_type): Handle arguments to vendor
>    extended qualifier.

+++ b/gcc/testsuite/g++.dg/abi/mangle-regparm.C
@@ -0,0 +1,29 @@
+// { dg-do run { target i?86-*-* } }

This should read:

+// { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } }

The test wasn't actually run on x86_64-linux target. I'll commit the
following patch after regtest:

--cut here--
Index: mangle-regparm.C
===================================================================
--- mangle-regparm.C    (revision 224011)
+++ mangle-regparm.C    (working copy)
@@ -1,4 +1,4 @@
-// { dg-do run { target i?86-*-* } }
+// { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } }
// { dg-final { scan-assembler
"_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_" } }

typedef __SIZE_TYPE__ size_t;
--cut here--

Uros.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: C++ PATCH for c++/44282 (ia32 calling convention attributes and mangling)
  2015-06-02  7:31 C++ PATCH for c++/44282 (ia32 calling convention attributes and mangling) Uros Bizjak
@ 2015-06-02 11:07 ` Uros Bizjak
  2015-06-02 11:52   ` Uros Bizjak
  0 siblings, 1 reply; 7+ messages in thread
From: Uros Bizjak @ 2015-06-02 11:07 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill

On Tue, Jun 2, 2015 at 9:26 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> Hello!
>
>>    PR c++/44282
>>    gcc/cp/
>>    * mangle.c (attr_strcmp): New.
>>    (write_CV_qualifiers_for_type): Also write out attributes that
>>    affect type identity.
>>    (write_type): Strip all attributes after writing qualifiers.
>>    libiberty/
>>    * cp-demangle.c (cplus_demangle_type): Handle arguments to vendor
>>    extended qualifier.
>
> +++ b/gcc/testsuite/g++.dg/abi/mangle-regparm.C
> @@ -0,0 +1,29 @@
> +// { dg-do run { target i?86-*-* } }
>
> This should read:
>
> +// { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } }
>
> The test wasn't actually run on x86_64-linux target. I'll commit the
> following patch after regtest:

Unfortunately, something is wrong with the testcase itself:

FAIL: g++.dg/abi/mangle-regparm.C  -std=c++98 (test for excess errors)
WARNING: g++.dg/abi/mangle-regparm.C  -std=c++98 compilation failed to
produce executable
FAIL: g++.dg/abi/mangle-regparm.C  -std=c++11 (test for excess errors)
WARNING: g++.dg/abi/mangle-regparm.C  -std=c++11 compilation failed to
produce executable
FAIL: g++.dg/abi/mangle-regparm.C  -std=c++14 (test for excess errors)
WARNING: g++.dg/abi/mangle-regparm.C  -std=c++14 compilation failed to
produce executable

with the following error:

FAIL: g++.dg/abi/mangle-regparm.C  -std=c++98 (test for excess errors)
Excess errors:
/usr/bin/ld: /tmp/ccU8LttY.o: bad reloc symbol index (0x5b550 >= 0x12)
for offset 0x6c in section `.text'
/tmp/ccU8LttY.o: could not read symbols: Bad value

WARNING: g++.dg/abi/mangle-regparm.C  -std=c++98 compilation failed to
produce executable
g++.dg/abi/mangle-regparm.C  -std=c++98 : output file does not exist
UNRESOLVED: g++.dg/abi/mangle-regparm.C  -std=c++98  scan-assembler
_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_

Uros.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: C++ PATCH for c++/44282 (ia32 calling convention attributes and mangling)
  2015-06-02 11:07 ` Uros Bizjak
@ 2015-06-02 11:52   ` Uros Bizjak
  2015-06-02 13:11     ` Jason Merrill
  0 siblings, 1 reply; 7+ messages in thread
From: Uros Bizjak @ 2015-06-02 11:52 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jason Merrill

On Tue, Jun 2, 2015 at 1:03 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Tue, Jun 2, 2015 at 9:26 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> Hello!
>>
>>>    PR c++/44282
>>>    gcc/cp/
>>>    * mangle.c (attr_strcmp): New.
>>>    (write_CV_qualifiers_for_type): Also write out attributes that
>>>    affect type identity.
>>>    (write_type): Strip all attributes after writing qualifiers.
>>>    libiberty/
>>>    * cp-demangle.c (cplus_demangle_type): Handle arguments to vendor
>>>    extended qualifier.
>>
>> +++ b/gcc/testsuite/g++.dg/abi/mangle-regparm.C
>> @@ -0,0 +1,29 @@
>> +// { dg-do run { target i?86-*-* } }
>>
>> This should read:
>>
>> +// { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } }
>>
>> The test wasn't actually run on x86_64-linux target. I'll commit the
>> following patch after regtest:
>
> Unfortunately, something is wrong with the testcase itself:
>
> FAIL: g++.dg/abi/mangle-regparm.C  -std=c++98 (test for excess errors)
> WARNING: g++.dg/abi/mangle-regparm.C  -std=c++98 compilation failed to
> produce executable
> FAIL: g++.dg/abi/mangle-regparm.C  -std=c++11 (test for excess errors)
> WARNING: g++.dg/abi/mangle-regparm.C  -std=c++11 compilation failed to
> produce executable
> FAIL: g++.dg/abi/mangle-regparm.C  -std=c++14 (test for excess errors)
> WARNING: g++.dg/abi/mangle-regparm.C  -std=c++14 compilation failed to
> produce executable
>
> with the following error:
>
> FAIL: g++.dg/abi/mangle-regparm.C  -std=c++98 (test for excess errors)
> Excess errors:
> /usr/bin/ld: /tmp/ccU8LttY.o: bad reloc symbol index (0x5b550 >= 0x12)
> for offset 0x6c in section `.text'
> /tmp/ccU8LttY.o: could not read symbols: Bad value
>
> WARNING: g++.dg/abi/mangle-regparm.C  -std=c++98 compilation failed to
> produce executable
> g++.dg/abi/mangle-regparm.C  -std=c++98 : output file does not exist
> UNRESOLVED: g++.dg/abi/mangle-regparm.C  -std=c++98  scan-assembler
> _Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_

FYI, everything links and runs OK if .set is removed from the
following part of the asm:

.LFE4:
       .size   _Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_,
.-_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_
       .weak   _Z18IndirectExternCallIPFviiEiEvT_T0_S3_
       .set    _Z18IndirectExternCallIPFviiEiEvT_T0_S3_,_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_
       .section
.text._Z18IndirectExternCallIPFviiEiEvT_T0_S3_,"axG",@progbits,_Z18IndirectExternCallIPFviiEiEvT_T0_S3_,comdat
       .weak   _Z18IndirectExternCallIPFviiEiEvT_T0_S3_
       .type   _Z18IndirectExternCallIPFviiEiEvT_T0_S3_, @function
_Z18IndirectExternCallIPFviiEiEvT_T0_S3_:

Uros.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: C++ PATCH for c++/44282 (ia32 calling convention attributes and mangling)
  2015-06-02 11:52   ` Uros Bizjak
@ 2015-06-02 13:11     ` Jason Merrill
  2015-06-03 21:39       ` Jason Merrill
  0 siblings, 1 reply; 7+ messages in thread
From: Jason Merrill @ 2015-06-02 13:11 UTC (permalink / raw)
  To: Uros Bizjak, gcc-patches

On 06/02/2015 07:34 AM, Uros Bizjak wrote:
>> Unfortunately, something is wrong with the testcase itself:
>>
>> FAIL: g++.dg/abi/mangle-regparm.C  -std=c++98 (test for excess errors)
>> WARNING: g++.dg/abi/mangle-regparm.C  -std=c++98 compilation failed to
>> produce executable
>> FAIL: g++.dg/abi/mangle-regparm.C  -std=c++11 (test for excess errors)
>> WARNING: g++.dg/abi/mangle-regparm.C  -std=c++11 compilation failed to
>> produce executable
>> FAIL: g++.dg/abi/mangle-regparm.C  -std=c++14 (test for excess errors)
>> WARNING: g++.dg/abi/mangle-regparm.C  -std=c++14 compilation failed to
>> produce executable
>>
>> with the following error:
>>
>> FAIL: g++.dg/abi/mangle-regparm.C  -std=c++98 (test for excess errors)
>> Excess errors:
>> /usr/bin/ld: /tmp/ccU8LttY.o: bad reloc symbol index (0x5b550 >= 0x12)
>> for offset 0x6c in section `.text'
>> /tmp/ccU8LttY.o: could not read symbols: Bad value
>>
>> WARNING: g++.dg/abi/mangle-regparm.C  -std=c++98 compilation failed to
>> produce executable
>> g++.dg/abi/mangle-regparm.C  -std=c++98 : output file does not exist
>> UNRESOLVED: g++.dg/abi/mangle-regparm.C  -std=c++98  scan-assembler
>> _Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_
>
> FYI, everything links and runs OK if .set is removed from the
> following part of the asm:
>
> .LFE4:
>         .size   _Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_,
> .-_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_
>         .weak   _Z18IndirectExternCallIPFviiEiEvT_T0_S3_
>         .set    _Z18IndirectExternCallIPFviiEiEvT_T0_S3_,_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_
>         .section
> .text._Z18IndirectExternCallIPFviiEiEvT_T0_S3_,"axG",@progbits,_Z18IndirectExternCallIPFviiEiEvT_T0_S3_,comdat
>         .weak   _Z18IndirectExternCallIPFviiEiEvT_T0_S3_
>         .type   _Z18IndirectExternCallIPFviiEiEvT_T0_S3_, @function
> _Z18IndirectExternCallIPFviiEiEvT_T0_S3_:

Ugh, I thought I had dealt with that issue.  Looking...

Jason

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: C++ PATCH for c++/44282 (ia32 calling convention attributes and mangling)
  2015-06-02 13:11     ` Jason Merrill
@ 2015-06-03 21:39       ` Jason Merrill
  2015-09-14 17:41         ` Jason Merrill
  0 siblings, 1 reply; 7+ messages in thread
From: Jason Merrill @ 2015-06-03 21:39 UTC (permalink / raw)
  To: Uros Bizjak, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 119 bytes --]

On 06/02/2015 09:04 AM, Jason Merrill wrote:
> Ugh, I thought I had dealt with that issue.  Looking...

Fixed thus.




[-- Attachment #2: 44282-2.patch --]
[-- Type: text/x-patch, Size: 6062 bytes --]

commit 82343dca07986bd1db2759d2eca1cfd5b9728410
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Jun 2 13:24:11 2015 -0400

    	PR c++/44282
    	* mangle.c (mangle_decl): Always SET_IDENTIFIER_GLOBAL_VALUE.
    	(write_CV_qualifiers_for_type): Set G.need_abi_warning.
    	(decl_implicit_alias_p): Split out from maybe_remove_implicit_alias.
    	* cp-tree.h (DECL_REALLY_EXTERN): Handle null DECL_LANG_SPECIFIC.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9107fa6..dc595fe 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4101,7 +4101,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
   (DECL_LANG_SPECIFIC (NODE)->u.base.not_really_extern)
 
 #define DECL_REALLY_EXTERN(NODE) \
-  (DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE))
+  (DECL_EXTERNAL (NODE)				\
+   && (!DECL_LANG_SPECIFIC (NODE) || !DECL_NOT_REALLY_EXTERN (NODE)))
 
 /* A thunk is a stub function.
 
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 8fd06e3..cc5faf7 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2205,10 +2205,6 @@ write_CV_qualifiers_for_type (const tree type)
 
   /* Mangle attributes that affect type identity as extended qualifiers.
 
-     We mangle them onto the obstack, then copy the result into a string
-     vector and back up the obstack.  Once we've handled all of them we
-     sort them and write them out in order.
-
      We don't do this with classes and enums because their attributes
      are part of their definitions, not something added on.  */
 
@@ -2246,6 +2242,8 @@ write_CV_qualifiers_for_type (const tree type)
 	    }
 
 	  ++num_qualifiers;
+	  if (abi_version_crosses (9))
+	    G.need_abi_warning = true;
 	}
     }
 
@@ -3535,11 +3533,11 @@ get_mangled_id (tree decl)
   return targetm.mangle_decl_assembler_name (decl, id);
 }
 
-/* If DECL is a mangling alias, remove it from the symbol table and return
-   true; otherwise return false.  */
+/* If DECL is an implicit mangling alias, return its symtab node; otherwise
+   return NULL.  */
 
-bool
-maybe_remove_implicit_alias (tree decl)
+static symtab_node *
+decl_implicit_alias_p (tree decl)
 {
   if (DECL_P (decl) && DECL_ARTIFICIAL (decl)
       && DECL_IGNORED_P (decl)
@@ -3549,10 +3547,21 @@ maybe_remove_implicit_alias (tree decl)
     {
       symtab_node *n = symtab_node::get (decl);
       if (n && n->cpp_implicit_alias)
-	{
-	  n->remove();
-	  return true;
-	}
+	return n;
+    }
+  return NULL;
+}
+
+/* If DECL is a mangling alias, remove it from the symbol table and return
+   true; otherwise return false.  */
+
+bool
+maybe_remove_implicit_alias (tree decl)
+{
+  if (symtab_node *n = decl_implicit_alias_p (decl))
+    {
+      n->remove();
+      return true;
     }
   return false;
 }
@@ -3592,21 +3601,38 @@ mangle_decl (const tree decl)
     }
   SET_DECL_ASSEMBLER_NAME (decl, id);
 
-  if (G.need_abi_warning
+  if (id != DECL_NAME (decl)
+      && !DECL_REALLY_EXTERN (decl)
       /* Don't do this for a fake symbol we aren't going to emit anyway.  */
       && TREE_CODE (decl) != TYPE_DECL
       && !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
       && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
     {
+      bool set = false;
+
+      /* Check IDENTIFIER_GLOBAL_VALUE before setting to avoid redundant
+	 errors from multiple definitions.  */
+      tree d = IDENTIFIER_GLOBAL_VALUE (id);
+      if (!d || decl_implicit_alias_p (d))
+	{
+	  set = true;
+	  SET_IDENTIFIER_GLOBAL_VALUE (id, decl);
+	}
+
+      if (!G.need_abi_warning)
+	return;
+
       /* If the mangling will change in the future, emit an alias with the
 	 future mangled name for forward-compatibility.  */
       int save_ver;
       tree id2;
 
-      SET_IDENTIFIER_GLOBAL_VALUE (id, decl);
-      if (IDENTIFIER_GLOBAL_VALUE (id) != decl)
-	inform (DECL_SOURCE_LOCATION (decl), "a later -fabi-version= (or =0) "
-		"avoids this error with a change in mangling");
+      if (!set)
+	{
+	  SET_IDENTIFIER_GLOBAL_VALUE (id, decl);
+	  inform (DECL_SOURCE_LOCATION (decl), "a later -fabi-version= (or "
+		  "=0) avoids this error with a change in mangling");
+	}
 
       save_ver = flag_abi_version;
       flag_abi_version = flag_abi_compat_version;
diff --git a/gcc/testsuite/g++.dg/abi/mangle-regparm.C b/gcc/testsuite/g++.dg/abi/mangle-regparm.C
index e5d6f37..122d373 100644
--- a/gcc/testsuite/g++.dg/abi/mangle-regparm.C
+++ b/gcc/testsuite/g++.dg/abi/mangle-regparm.C
@@ -1,10 +1,11 @@
 // { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } }
+// { dg-options "-Wabi=8" }
 // { dg-final { scan-assembler "_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_" } }
 
 typedef __SIZE_TYPE__ size_t;
 
 template <typename F, typename T>
-void IndirectExternCall(F f, T t1, T t2) {
+void IndirectExternCall(F f, T t1, T t2) { // { dg-warning "mangled name" }
   typedef F (*WrapF)(F);
   f (t1, t2);
 }
diff --git a/gcc/testsuite/g++.dg/abi/mangle58.C b/gcc/testsuite/g++.dg/abi/mangle58.C
index f9aadc2..d2c90b4 100644
--- a/gcc/testsuite/g++.dg/abi/mangle58.C
+++ b/gcc/testsuite/g++.dg/abi/mangle58.C
@@ -6,13 +6,13 @@ struct B {
   template<typename T> static int cmp1(T a, T b);
   static int cmp2(char a, char b);
   // { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_X4cmp1EE" } }
-  template <typename T> static void f (A<T,cmp1> &);
+  template <typename T> static void f (A<T,cmp1> &) {}
   // { dg-final { scan-assembler "_ZN1B1gIcEEvR1AIT_XsrS_4cmp1EE" } }
-  template <typename T> static void g (A<T,B::cmp1> &);
+  template <typename T> static void g (A<T,B::cmp1> &) {}
   // { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_L_ZNS_4cmp2EccEE" } }
-  template <typename T> static void f (A<T,cmp2> &); // { dg-warning "mangle" }
+  template <typename T> static void f (A<T,cmp2> &) {} // { dg-warning "mangle" }
   // { dg-final { scan-assembler "_ZN1B1gIcEEvR1AIT_L_ZNS_4cmp2EccEE" } }
-  template <typename T> static void g (A<T,B::cmp2> &); // { dg-warning "mangle" }
+  template <typename T> static void g (A<T,B::cmp2> &) {} // { dg-warning "mangle" }
 };
 
 void g()

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: C++ PATCH for c++/44282 (ia32 calling convention attributes and mangling)
  2015-06-03 21:39       ` Jason Merrill
@ 2015-09-14 17:41         ` Jason Merrill
  0 siblings, 0 replies; 7+ messages in thread
From: Jason Merrill @ 2015-09-14 17:41 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 164 bytes --]

It occurred to me that we weren't warning about this with -Wabi and a 
lower -fabi-version.  This patch fixes that.

Tested x86_64-pc-linux-gnu, applying to trunk.

[-- Attachment #2: 44282-3.patch --]
[-- Type: text/x-patch, Size: 3023 bytes --]

commit e924f74640ecd18240fb514f99b0d5b5ceeeffb7
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Sep 2 16:32:15 2015 -0400

    	PR c++/44282
    
    	* mangle.c (write_CV_qualifiers_for_type): Also warn about regparm
    	mangling with lower -fabi-version.

diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 342cb93..2640d52 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2196,7 +2196,7 @@ write_CV_qualifiers_for_type (const tree type)
      We don't do this with classes and enums because their attributes
      are part of their definitions, not something added on.  */
 
-  if (abi_version_at_least (10) && !OVERLOAD_TYPE_P (type))
+  if (!OVERLOAD_TYPE_P (type))
     {
       auto_vec<tree> vec;
       for (tree a = TYPE_ATTRIBUTES (type); a; a = TREE_CHAIN (a))
@@ -2207,31 +2207,34 @@ write_CV_qualifiers_for_type (const tree type)
 	      && !is_attribute_p ("abi_tag", name))
 	    vec.safe_push (a);
 	}
-      vec.qsort (attr_strcmp);
-      while (!vec.is_empty())
+      if (abi_version_crosses (10) && !vec.is_empty ())
+	G.need_abi_warning = true;
+      if (abi_version_at_least (10))
 	{
-	  tree a = vec.pop();
-	  const attribute_spec *as
-	    = lookup_attribute_spec (get_attribute_name (a));
-
-	  write_char ('U');
-	  write_unsigned_number (strlen (as->name));
-	  write_string (as->name);
-	  if (TREE_VALUE (a))
+	  vec.qsort (attr_strcmp);
+	  while (!vec.is_empty())
 	    {
-	      write_char ('I');
-	      for (tree args = TREE_VALUE (a); args;
-		   args = TREE_CHAIN (args))
+	      tree a = vec.pop();
+	      const attribute_spec *as
+		= lookup_attribute_spec (get_attribute_name (a));
+
+	      write_char ('U');
+	      write_unsigned_number (strlen (as->name));
+	      write_string (as->name);
+	      if (TREE_VALUE (a))
 		{
-		  tree arg = TREE_VALUE (args);
-		  write_template_arg (arg);
+		  write_char ('I');
+		  for (tree args = TREE_VALUE (a); args;
+		       args = TREE_CHAIN (args))
+		    {
+		      tree arg = TREE_VALUE (args);
+		      write_template_arg (arg);
+		    }
+		  write_char ('E');
 		}
-	      write_char ('E');
+
+	      ++num_qualifiers;
 	    }
-
-	  ++num_qualifiers;
-	  if (abi_version_crosses (10))
-	    G.need_abi_warning = true;
 	}
     }
 
diff --git a/gcc/testsuite/g++.dg/abi/mangle-regparm1a.C b/gcc/testsuite/g++.dg/abi/mangle-regparm1a.C
new file mode 100644
index 0000000..bfa6c9b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle-regparm1a.C
@@ -0,0 +1,21 @@
+// { dg-do run { target { { i?86-*-* x86_64-*-* } && ia32 } } }
+// { dg-options "-fabi-version=8 -Wabi -save-temps" }
+// { dg-final { scan-assembler "_Z18IndirectExternCallIPFviiEiEvT_T0_S3_" } }
+
+template <typename F, typename T>
+void IndirectExternCall(F f, T t1, T t2) { // { dg-warning "mangled name" }
+  typedef F (*WrapF)(F);
+  f (t1, t2);
+}
+
+__attribute__((regparm(3), stdcall))
+void regparm_func (int i, int j)
+{
+  if (i != 24 || j != 42)
+    __builtin_abort();
+}
+
+int main()
+{
+  IndirectExternCall (regparm_func, 24, 42);
+}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* C++ PATCH for c++/44282 (ia32 calling convention attributes and mangling)
@ 2015-06-02  2:55 Jason Merrill
  0 siblings, 0 replies; 7+ messages in thread
From: Jason Merrill @ 2015-06-02  2:55 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 435 bytes --]

A recent change broke bootstrap on ia32 because code intended to strip 
non-type-identity attributes from template arguments was also stripping 
type-identity attributes such as the ia32 calling convention attributes. 
   When I fixed that it reminded me of this bug: we weren't mangling the 
function pointer type differently based on the calling convention.  This 
patch fixes that.

Tested x86_64-pc-linux-gnu, applying to trunk.



[-- Attachment #2: 44282.patch --]
[-- Type: text/x-patch, Size: 6474 bytes --]

commit 0707fcaee20275a8955ab5741df70831c8e9e350
Author: Jason Merrill <jason@redhat.com>
Date:   Sat Apr 25 07:45:02 2015 -0400

    	PR c++/44282
    gcc/cp/
    	* mangle.c (attr_strcmp): New.
    	(write_CV_qualifiers_for_type): Also write out attributes that
    	affect type identity.
    	(write_type): Strip all attributes after writing qualifiers.
    libiberty/
    	* cp-demangle.c (cplus_demangle_type): Handle arguments to vendor
    	extended qualifier.

diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index e9eb511..748306b 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -894,7 +894,7 @@ c_common_post_options (const char **pfilename)
   /* Change flag_abi_version to be the actual current ABI level for the
      benefit of c_cpp_builtins.  */
   if (flag_abi_version == 0)
-    flag_abi_version = 8;
+    flag_abi_version = 9;
 
   /* Set C++ standard to C++98 if not specified on the command line.  */
   if (c_dialect_cxx () && cxx_dialect == cxx_unset)
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 647ec70..8151179 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -75,6 +75,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ipa-ref.h"
 #include "cgraph.h"
 #include "wide-int.h"
+#include "attribs.h"
 
 /* Debugging support.  */
 
@@ -1916,11 +1917,15 @@ write_type (tree type)
        candidates.  */
     {
       tree t = TYPE_MAIN_VARIANT (type);
+      if (TYPE_ATTRIBUTES (t) && !OVERLOAD_TYPE_P (t))
+	t = cp_build_type_attribute_variant (t, NULL_TREE);
+      gcc_assert (t != type);
       if (TREE_CODE (t) == FUNCTION_TYPE
 	  || TREE_CODE (t) == METHOD_TYPE)
 	{
 	  t = build_ref_qualified_type (t, type_memfn_rqual (type));
-	  if (abi_version_at_least (8))
+	  if (abi_version_at_least (8)
+	      || type == TYPE_MAIN_VARIANT (type))
 	    /* Avoid adding the unqualified function type as a substitution.  */
 	    write_function_type (t);
 	  else
@@ -2168,6 +2173,20 @@ write_type (tree type)
     add_substitution (type);
 }
 
+/* qsort callback for sorting a vector of attribute entries.  */
+
+static int
+attr_strcmp (const void *p1, const void *p2)
+{
+  tree a1 = *(const tree*)p1;
+  tree a2 = *(const tree*)p2;
+
+  const attribute_spec *as1 = lookup_attribute_spec (get_attribute_name (a1));
+  const attribute_spec *as2 = lookup_attribute_spec (get_attribute_name (a2));
+
+  return strcmp (as1->name, as2->name);
+}
+
 /* Non-terminal <CV-qualifiers> for type nodes.  Returns the number of
    CV-qualifiers written for TYPE.
 
@@ -2182,9 +2201,55 @@ write_CV_qualifiers_for_type (const tree type)
 
        "In cases where multiple order-insensitive qualifiers are
        present, they should be ordered 'K' (closest to the base type),
-       'V', 'r', and 'U' (farthest from the base type) ..."
+       'V', 'r', and 'U' (farthest from the base type) ..."  */
 
-     Note that we do not use cp_type_quals below; given "const
+  /* Mangle attributes that affect type identity as extended qualifiers.
+
+     We mangle them onto the obstack, then copy the result into a string
+     vector and back up the obstack.  Once we've handled all of them we
+     sort them and write them out in order.
+
+     We don't do this with classes and enums because their attributes
+     are part of their definitions, not something added on.  */
+
+  if (abi_version_at_least (9) && !OVERLOAD_TYPE_P (type))
+    {
+      auto_vec<tree> vec;
+      for (tree a = TYPE_ATTRIBUTES (type); a; a = TREE_CHAIN (a))
+	{
+	  tree name = get_attribute_name (a);
+	  const attribute_spec *as = lookup_attribute_spec (name);
+	  if (as && as->affects_type_identity
+	      && !is_attribute_p ("abi_tag", name))
+	    vec.safe_push (a);
+	}
+      vec.qsort (attr_strcmp);
+      while (!vec.is_empty())
+	{
+	  tree a = vec.pop();
+	  const attribute_spec *as
+	    = lookup_attribute_spec (get_attribute_name (a));
+
+	  write_char ('U');
+	  write_unsigned_number (strlen (as->name));
+	  write_string (as->name);
+	  if (TREE_VALUE (a))
+	    {
+	      write_char ('I');
+	      for (tree args = TREE_VALUE (a); args;
+		   args = TREE_CHAIN (args))
+		{
+		  tree arg = TREE_VALUE (args);
+		  write_template_arg (arg);
+		}
+	      write_char ('E');
+	    }
+
+	  ++num_qualifiers;
+	}
+    }
+
+  /* Note that we do not use cp_type_quals below; given "const
      int[3]", the "const" is emitted with the "int", not with the
      array.  */
   cp_cv_quals quals = TYPE_QUALS (type);
diff --git a/gcc/testsuite/g++.dg/abi/mangle-regparm.C b/gcc/testsuite/g++.dg/abi/mangle-regparm.C
new file mode 100644
index 0000000..7d4121b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle-regparm.C
@@ -0,0 +1,29 @@
+// { dg-do run { target i?86-*-* } }
+// { dg-final { scan-assembler "_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_" } }
+
+typedef __SIZE_TYPE__ size_t;
+
+template <typename F, typename T>
+void IndirectExternCall(F f, T t1, T t2) {
+  typedef F (*WrapF)(F);
+  f (t1, t2);
+}
+
+__attribute__((regparm(3), stdcall))
+void regparm_func (int i, int j)
+{
+  if (i != 24 || j != 42)
+    __builtin_abort();
+}
+
+void normal_func (int i, int j)
+{
+  if (i != 24 || j != 42)
+    __builtin_abort();
+}
+
+int main()
+{
+  IndirectExternCall (regparm_func, 24, 42);
+  IndirectExternCall (normal_func, 24, 42);
+}
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index 77c2cee..2988b6b 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -2470,6 +2470,9 @@ cplus_demangle_type (struct d_info *di)
     case 'U':
       d_advance (di, 1);
       ret = d_source_name (di);
+      if (d_peek_char (di) == 'I')
+	ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
+			   d_template_args (di));
       ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
 			 cplus_demangle_type (di), ret);
       break;
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index a030685..6ea64ae 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -4356,3 +4356,6 @@ _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
 --format=gnu-v3
 _Z1fSsB3fooS_
 f(std::string[abi:foo], std::string[abi:foo])
+--format=gnu-v3
+_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_
+void IndirectExternCall<void ( regparm<3> stdcall*)(int, int), int>(void ( regparm<3> stdcall*)(int, int), int, void ( regparm<3> stdcall*)(int, int))


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-09-14 17:37 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-02  7:31 C++ PATCH for c++/44282 (ia32 calling convention attributes and mangling) Uros Bizjak
2015-06-02 11:07 ` Uros Bizjak
2015-06-02 11:52   ` Uros Bizjak
2015-06-02 13:11     ` Jason Merrill
2015-06-03 21:39       ` Jason Merrill
2015-09-14 17:41         ` Jason Merrill
  -- strict thread matches above, loose matches on Subject: below --
2015-06-02  2:55 Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).