Bug 81854 - weak alias of an incompatible symbol accepted
Summary: weak alias of an incompatible symbol accepted
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: ---
Assignee: Martin Sebor
URL:
Keywords: accepts-invalid, patch
Depends on:
Blocks: 82435
  Show dependency treegraph
 
Reported: 2017-08-15 22:23 UTC by Martin Sebor
Modified: 2017-10-05 10:12 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-08-18 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2017-08-15 22:23:08 UTC
GCC helpfully rejects function declarations that alias a variable but fails to complain about similarly incorrect declarations that alias functions with an incompatible type.

$ cat b.c && gcc -O2 -Wall -Wextra -Wpedantic b.c
const char* __attribute__ ((weak, alias ("foo")))
bar (void);   // error (good)

int foo;

const char* __attribute__ ((weak, alias ("foobar")))
baz (void);   // accepted (bad)

void foobar (int *p) { *p = 0; }
b.c:2:1: error: ‘bar’ alias in between function and variable is not supported
 bar (void);   // error (good)
 ^~~
b.c:4:5: warning: ‘foo’ aliased declaration
 int foo;
     ^~~
Comment 1 Martin Sebor 2017-08-15 22:25:20 UTC
The following (otherwise untested) patch detects the problem in the test case.

diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 6072c56..635170a 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1350,11 +1350,24 @@ handle_alias_pairs (void)
       if (TREE_CODE (p->decl) == FUNCTION_DECL
           && target_node && is_a <cgraph_node *> (target_node))
        {
-         cgraph_node *src_node = cgraph_node::get (p->decl);
-         if (src_node && src_node->definition)
-           src_node->reset ();
-         cgraph_node::create_alias (p->decl, target_node->decl);
-         alias_pairs->unordered_remove (i);
+         tree t1 = TREE_TYPE (p->decl);
+         tree t2 = TREE_TYPE (target_node->decl);
+         if (!gimple_canonical_types_compatible_p (t1, t2, false))
+           {
+             error ("%q+D alias between functions of incompatible types",
+                    p->decl);
+             warning (0, "%q+D aliased declaration",
+                      target_node->decl);
+             alias_pairs->unordered_remove (i);
+           }
+         else
+           {
+             cgraph_node *src_node = cgraph_node::get (p->decl);
+             if (src_node && src_node->definition)
+               src_node->reset ();
+             cgraph_node::create_alias (p->decl, target_node->decl);
+             alias_pairs->unordered_remove (i);
+           }
        }
       else if (VAR_P (p->decl)
               && target_node && is_a <varpool_node *> (target_node))
Comment 2 Martin Sebor 2017-08-18 03:23:46 UTC
Patch posted for review:
https://gcc.gnu.org/ml/gcc-patches/2017-08/msg01103.html
Comment 3 Martin Sebor 2017-08-20 21:32:12 UTC
Author: msebor
Date: Sun Aug 20 21:31:39 2017
New Revision: 251211

URL: https://gcc.gnu.org/viewcvs?rev=251211&root=gcc&view=rev
Log:
libstdc++/ChangeLog:

	PR c/81854
	* src/c++98/compatibility.cc (_GLIBCXX_3_4_SYMVER): Declare alias
	target as a C++ function with no prototype.
	(_GLIBCXX_3_4_5_SYMVER): Ditto.

Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/src/c++98/compatibility.cc
Comment 4 Aldy Hernandez 2017-09-13 17:12:35 UTC
Author: aldyh
Date: Wed Sep 13 17:12:03 2017
New Revision: 252495

URL: https://gcc.gnu.org/viewcvs?rev=252495&root=gcc&view=rev
Log:
libstdc++/ChangeLog:

	PR c/81854
	* src/c++98/compatibility.cc (_GLIBCXX_3_4_SYMVER): Declare alias
	target as a C++ function with no prototype.
	(_GLIBCXX_3_4_5_SYMVER): Ditto.

Modified:
    branches/range-gen2/libstdc++-v3/ChangeLog
    branches/range-gen2/libstdc++-v3/src/c++98/compatibility.cc
Comment 5 Martin Sebor 2017-09-19 14:28:03 UTC
Author: msebor
Date: Tue Sep 19 14:27:32 2017
New Revision: 252976

URL: https://gcc.gnu.org/viewcvs?rev=252976&root=gcc&view=rev
Log:
PR c/81854 - weak alias of an incompatible symbol accepted

gcc/ChangeLog:

	PR c/81854
	* cgraphunit.c (handle_alias_pairs): Reject aliases between functions
	of incompatible types.

gcc/testsuite/ChangeLog:

	PR c/81854
	* gcc.dg/pr81854.c: New test.
	* g++.dg/ext/attr-ifunc-5.C: New test.
	* g++.dg/ext/attr-ifunc-1.C: Adjust.
	* g++.dg/ext/attr-ifunc-2.C: Same.
	* g++.dg/ext/attr-ifunc-3.C: Same.
	* g++.dg/ext/attr-ifunc-4.C: Same.
	* g++.old-deja/g++.abi/vtable2.C: Same.
	* gcc.dg/attr-ifunc-1.c: Same.

Added:
    trunk/gcc/testsuite/g++.dg/ext/attr-ifunc-5.C
    trunk/gcc/testsuite/gcc.dg/pr81854.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/cgraphunit.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/ext/attr-ifunc-1.C
    trunk/gcc/testsuite/g++.dg/ext/attr-ifunc-2.C
    trunk/gcc/testsuite/g++.dg/ext/attr-ifunc-3.C
    trunk/gcc/testsuite/g++.dg/ext/attr-ifunc-4.C
    trunk/gcc/testsuite/g++.old-deja/g++.abi/vtable2.C
    trunk/gcc/testsuite/gcc.dg/attr-ifunc-1.c
Comment 6 Martin Sebor 2017-09-19 14:33:34 UTC
Fixed in r252976.
Comment 7 Dominique d'Humieres 2017-09-20 12:39:19 UTC
The test gcc.dg/pr81854.c fails on darwin

/opt/gcc/_clean/gcc/testsuite/gcc.dg/pr81854.c:30:1: error: ifunc is not supported in this configuration
 f3 (void);          /* { dg-error ".ifunc. resolver must return a function pointer" } */

I think a line

/* { dg-require-ifunc "" } */

is missing.
Comment 8 Martin Sebor 2017-09-20 22:17:36 UTC
(In reply to Dominique d'Humieres from comment #7)

Thanks for the heads up!  There's an additional problem in target-supports.exp that needs fixing for the ifunc support to be correctly detected, and a few more type problems in the attr-ifunc-*.c tests that were hidden by the target-supports.exp failure.  I'm about to commit a fix for all of them.
Comment 9 Martin Sebor 2017-09-20 22:20:24 UTC
Author: msebor
Date: Wed Sep 20 22:19:53 2017
New Revision: 253037

URL: https://gcc.gnu.org/viewcvs?rev=253037&root=gcc&view=rev
Log:
Fix testsuite fallout from r252976.

gcc/testsuite/ChangeLog:

	PR c/81854
	* gcc.dg/attr-ifunc-1.c: Correct type errors.
	* gcc.dg/attr-ifunc-2.c: Ditto.
	* gcc.dg/attr-ifunc-3.c: Ditto.
	* gcc.dg/attr-ifunc-4.c: Ditto.
	* gcc.dg/attr-ifunc-5.c: Ditto.
	* gcc.dg/pr81854.c: Require ifunc support.
	* gcc/testsuite/lib/target-supports.exp: Correct type error.


Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.dg/attr-ifunc-1.c
    trunk/gcc/testsuite/gcc.dg/attr-ifunc-2.c
    trunk/gcc/testsuite/gcc.dg/attr-ifunc-3.c
    trunk/gcc/testsuite/gcc.dg/attr-ifunc-4.c
    trunk/gcc/testsuite/gcc.dg/attr-ifunc-5.c
    trunk/gcc/testsuite/gcc.dg/pr81854.c
    trunk/gcc/testsuite/lib/target-supports.exp
Comment 10 Martin Sebor 2017-09-20 22:47:21 UTC
Author: msebor
Date: Wed Sep 20 22:46:49 2017
New Revision: 253041

URL: https://gcc.gnu.org/viewcvs?rev=253041&root=gcc&view=rev
Log:
Fix C++ testsuite fallout from r252976.

gcc/testsuite/ChangeLog:

	PR c/81854
	* g++.dg/ext/attr-ifunc-2.C: Correct type errors.
	* g++.dg/ext/attr-ifunc-4.C: Ditto.
	* lib/target-supports.exp: Adjust for C++.

Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/ext/attr-ifunc-2.C
    trunk/gcc/testsuite/g++.dg/ext/attr-ifunc-4.C
    trunk/gcc/testsuite/lib/target-supports.exp
Comment 11 Uroš Bizjak 2017-09-21 10:15:50 UTC
gcc.target/i386/pr80732.c fails with:

pr80732.c:46:8: warning: ‘f2’ ‘ifunc’ resolver should return a function pointer [-Wattributes]
 double f2(double a, double b, double c) __attribute__((ifunc("f2_resolve")));
        ^~
pr80732.c:37:14: note: resolver declaration here
 static void *f2_resolve(void)
              ^~~~~~~~~~
Comment 12 Martin Sebor 2017-09-22 16:31:08 UTC
Author: msebor
Date: Fri Sep 22 16:30:35 2017
New Revision: 253100

URL: https://gcc.gnu.org/viewcvs?rev=253100&root=gcc&view=rev
Log:
Fix testsuite fallout from r252976.

gcc/testsuite/ChangeLog:

	PR c/81854
	* gcc.target/i386/pr80732.c: Correct a type error.

Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gcc.target/i386/pr80732.c
Comment 13 uros 2017-09-25 14:59:50 UTC
Author: uros
Date: Mon Sep 25 14:59:19 2017
New Revision: 253153

URL: https://gcc.gnu.org/viewcvs?rev=253153&root=gcc&view=rev
Log:
	PR c/81854
	* src/c++98/complex_io.cc (_GLIBCXX_LDBL_COMPAT): Declare alias
	target as a C++ function with no prototype.


Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/src/c++98/complex_io.cc
Comment 14 Tamar Christina 2017-09-26 10:21:29 UTC
Hi Martin,

the changed tests seem to be failing on arm-none-linux-gnueabihf:

FAIL: g++.dg/ext/attr-ifunc-1.C  -std=gnu++11 execution test
FAIL: g++.dg/ext/attr-ifunc-1.C  -std=gnu++14 execution test
FAIL: g++.dg/ext/attr-ifunc-1.C  -std=gnu++98 execution test
FAIL: g++.dg/ext/attr-ifunc-2.C  -std=gnu++11 execution test
FAIL: g++.dg/ext/attr-ifunc-2.C  -std=gnu++14 execution test
FAIL: g++.dg/ext/attr-ifunc-2.C  -std=gnu++98 execution test
FAIL: g++.dg/ext/attr-ifunc-3.C  -std=gnu++11 execution test
FAIL: g++.dg/ext/attr-ifunc-3.C  -std=gnu++14 execution test
FAIL: g++.dg/ext/attr-ifunc-3.C  -std=gnu++98 execution test
FAIL: g++.dg/ext/attr-ifunc-4.C  -std=gnu++11 execution test
FAIL: g++.dg/ext/attr-ifunc-4.C  -std=gnu++14 execution test
FAIL: g++.dg/ext/attr-ifunc-4.C  -std=gnu++98 execution test

running in gdb I get 

Starting program: /home/tnfchris/gcc-fsf/attr-ifunc-1.exe 

Program received signal SIGSEGV, Segmentation fault.
0x00010540 in Klass::resolver () at gcc/testsuite/g++.dg/ext/attr-ifunc-1.C:26
26	  return &Klass::implementation;
(gdb) bt
#0  0x00010540 in Klass::resolver () at gcc/testsuite/g++.dg/ext/attr-ifunc-1.C:26
#1  0xf77cfc86 in elf_machine_rel (skip_ifunc=<optimized out>, reloc_addr_arg=0x2101c, version=<optimized out>, sym=0x101fc, reloc=0x103e0, map=0xf77f0968) at ../sysdeps/arm/dl-machine.h:523
#2  elf_dynamic_do_Rel (skip_ifunc=<optimized out>, lazy=<optimized out>, nrelative=<optimized out>, relsize=<optimized out>, reladdr=<optimized out>, map=0xf77f0968) at do-rel.h:137
#3  _dl_relocate_object (scope=<optimized out>, reloc_mode=<optimized out>, consider_profiling=<optimized out>, consider_profiling@entry=0) at dl-reloc.c:258
#4  0xf77ca1f6 in dl_main (phdr=<optimized out>, phnum=<optimized out>, user_entry=<optimized out>, auxv=<optimized out>) at rtld.c:2185
#5  0xf77d76c8 in _dl_sysdep_start (start_argptr=start_argptr@entry=0xfffef671, dl_main=0xf77c86e1 <dl_main>) at ../elf/dl-sysdep.c:253
#6  0xf77c8222 in _dl_start_final (arg=0xfffef671) at rtld.c:414
#7  _dl_start (arg=0xfffef671) at rtld.c:520
#8  0xf77c7b50 in _start () from /lib/ld-linux-armhf.so.3


It seems to be segfaulting on the return address

=> 0x10538 <Klass::resolver()>:	movw	r3, #1317	; 0x525
   0x1053c <Klass::resolver()+4>:	movt	r3, #1
   0x10540 <Klass::resolver()+8>:	str	r3, [r0, #0]

it goes wrong at the store, since r0 doesn't seem to contain a valid address

(gdb) x $r0
0x37b0d6:	Cannot access memory at address 0x37b0d6

Any ideas what's going on here?
Comment 15 Martin Sebor 2017-09-26 14:47:35 UTC
Yes, the recent changes to the C++ tests are wrong.  The failures are being tracked under bug 82301.  I have a patch out for review to fix both the tests and the implementation of the warning to resolve the problem (https://gcc.gnu.org/ml/gcc-patches/2017-09/msg01603.html).
Comment 16 Tamar Christina 2017-09-26 15:13:20 UTC
Thanks Martin!, I'll follow the other ticket.
Comment 17 Martin Sebor 2017-10-02 23:57:50 UTC
Author: msebor
Date: Mon Oct  2 23:57:19 2017
New Revision: 253372

URL: https://gcc.gnu.org/viewcvs?rev=253372&root=gcc&view=rev
Log:
Clean up more fallout from r252976.

libatomic/ChangeLog:
2017-10-02  Martin Sebor  <msebor@redhat.com>

	PR c/81854
	* acinclude.m4 (LIBAT_CHECK_IFUNC): Have ifunc resolver return
	a function pointer rather than void* to avoid GCC 8 warnings.
	* configure: Regenerate.
	* libatomic_i.h: Declare ifunc resolvers to return function
	pointers rather than void*.

Modified:
    trunk/libatomic/ChangeLog
    trunk/libatomic/acinclude.m4
    trunk/libatomic/configure
    trunk/libatomic/libatomic_i.h