Skip to content

Commit a0c6c7c

Browse files
author
msebor
committed
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@252976 138bc75d-0d04-0410-961f-82ee72b054a4
1 parent 86b743d commit a0c6c7c

File tree

11 files changed

+221
-38
lines changed

11 files changed

+221
-38
lines changed

gcc/ChangeLog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2017-09-18 Martin Sebor <[email protected]>
2+
3+
PR c/81854
4+
* cgraphunit.c (handle_alias_pairs): Reject aliases between functions
5+
of incompatible types.
6+
17
2017-09-19 Will Schmidt <[email protected]>
28

39
* config/rs6000/rs6000.c (rs6000_gimple_fold_builtin): Add handling

gcc/cgraphunit.c

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,66 @@ handle_alias_pairs (void)
13521352
if (TREE_CODE (p->decl) == FUNCTION_DECL
13531353
&& target_node && is_a <cgraph_node *> (target_node))
13541354
{
1355+
tree t1 = TREE_TYPE (p->decl);
1356+
tree t2 = TREE_TYPE (target_node->decl);
1357+
1358+
if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (p->decl)))
1359+
{
1360+
t2 = TREE_TYPE (t2);
1361+
if (POINTER_TYPE_P (t2))
1362+
{
1363+
t2 = TREE_TYPE (t2);
1364+
if (!FUNC_OR_METHOD_TYPE_P (t2))
1365+
{
1366+
if (warning_at (DECL_SOURCE_LOCATION (p->decl),
1367+
OPT_Wattributes,
1368+
"%q+D %<ifunc%> resolver should return "
1369+
"a function pointer",
1370+
p->decl))
1371+
inform (DECL_SOURCE_LOCATION (target_node->decl),
1372+
"resolver declaration here");
1373+
1374+
t2 = NULL_TREE;
1375+
}
1376+
}
1377+
else
1378+
{
1379+
/* Deal with static member function pointers. */
1380+
if (TREE_CODE (t2) == RECORD_TYPE
1381+
&& TYPE_FIELDS (t2)
1382+
&& TREE_CODE (TREE_TYPE (TYPE_FIELDS (t2))) == POINTER_TYPE
1383+
&& (TREE_CODE (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (t2))))
1384+
== METHOD_TYPE))
1385+
t2 = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (t2)));
1386+
else
1387+
{
1388+
error ("%q+D %<ifunc%> resolver must return a function "
1389+
"pointer",
1390+
p->decl);
1391+
inform (DECL_SOURCE_LOCATION (target_node->decl),
1392+
"resolver declaration here");
1393+
1394+
t2 = NULL_TREE;
1395+
}
1396+
}
1397+
}
1398+
1399+
if (t2
1400+
&& (!FUNC_OR_METHOD_TYPE_P (t2)
1401+
|| (prototype_p (t1)
1402+
&& prototype_p (t2)
1403+
&& !types_compatible_p (t1, t2))))
1404+
{
1405+
/* Warn for incompatibilities. Avoid warning for functions
1406+
without a prototype to make it possible to declare aliases
1407+
without knowing the exact type, as libstdc++ does. */
1408+
if (warning_at (DECL_SOURCE_LOCATION (p->decl), OPT_Wattributes,
1409+
"%q+D alias between functions of incompatible "
1410+
"types %qT and %qT", p->decl, t1, t2))
1411+
inform (DECL_SOURCE_LOCATION (target_node->decl),
1412+
"aliased declaration here");
1413+
}
1414+
13551415
cgraph_node *src_node = cgraph_node::get (p->decl);
13561416
if (src_node && src_node->definition)
13571417
src_node->reset ();
@@ -1366,10 +1426,11 @@ handle_alias_pairs (void)
13661426
}
13671427
else
13681428
{
1369-
error ("%q+D alias in between function and variable is not supported",
1429+
error ("%q+D alias between function and variable is not supported",
13701430
p->decl);
1371-
warning (0, "%q+D aliased declaration",
1372-
target_node->decl);
1431+
inform (DECL_SOURCE_LOCATION (target_node->decl),
1432+
"aliased declaration here");
1433+
13731434
alias_pairs->unordered_remove (i);
13741435
}
13751436
}

gcc/testsuite/ChangeLog

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
2017-09-18 Martin Sebor <[email protected]>
2+
3+
PR c/81854
4+
* gcc.dg/pr81854.c: New test.
5+
* g++.dg/ext/attr-ifunc-5.C: New test.
6+
* g++.dg/ext/attr-ifunc-1.C: Adjust.
7+
* g++.dg/ext/attr-ifunc-2.C: Same.
8+
* g++.dg/ext/attr-ifunc-3.C: Same.
9+
* g++.dg/ext/attr-ifunc-4.C: Same.
10+
* g++.old-deja/g++.abi/vtable2.C: Same.
11+
* gcc.dg/attr-ifunc-1.c: Same.
12+
113
2017-09-19 Will Schmidt <[email protected]>
214

315
* gcc.target/powerpc/fold-vec-ld-misc.c: New.

gcc/testsuite/g++.dg/ext/attr-ifunc-1.C

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,41 @@
22
/* { dg-require-ifunc "" } */
33
/* { dg-options "-Wno-pmf-conversions" } */
44

5-
#include <stdio.h>
6-
75
struct Klass
86
{
97
int implementation ();
108
int magic ();
11-
static void *resolver ();
9+
10+
typedef int (Klass::*MemFuncPtr)();
11+
12+
static MemFuncPtr resolver ();
1213
};
1314

15+
Klass::MemFuncPtr p = &Klass::implementation;
16+
1417
int Klass::implementation (void)
1518
{
16-
printf ("'ere I am JH\n");
17-
return 0;
19+
__builtin_printf ("'ere I am JH\n");
20+
return 1234;
1821
}
1922

20-
void *Klass::resolver (void)
23+
24+
Klass::MemFuncPtr Klass::resolver (void)
2125
{
22-
int (Klass::*pmf) () = &Klass::implementation;
23-
24-
return (void *)(int (*)(Klass *))(((Klass *)0)->*pmf);
26+
return &Klass::implementation;
2527
}
2628

29+
int f (void) __attribute__ ((ifunc ("foo")));
30+
31+
typedef int (F)(void);
32+
extern "C" F* foo () { return 0; }
33+
34+
2735
int Klass::magic (void) __attribute__ ((ifunc ("_ZN5Klass8resolverEv")));
2836

2937
int main ()
3038
{
3139
Klass obj;
32-
33-
return obj.magic () != 0;
40+
41+
return !(obj.magic () == 1234);
3442
}

gcc/testsuite/g++.dg/ext/attr-ifunc-2.C

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ struct Klass
88
{
99
int implementation ();
1010
int magic ();
11-
static void *resolver ();
11+
12+
typedef int (Klass::*MemFuncPtr)();
13+
14+
static MemFuncPtr resolver ();
1215
};
1316

1417
int Klass::implementation (void)
@@ -17,11 +20,9 @@ int Klass::implementation (void)
1720
return 0;
1821
}
1922

20-
void *Klass::resolver (void)
23+
Klass::memFuncPtr Klass::resolver (void)
2124
{
22-
int (Klass::*pmf) () = &Klass::implementation;
23-
24-
return (void *)(int (*)(Klass *))(((Klass *)0)->*pmf);
25+
return &Klass::implementation;
2526
}
2627

2728
int Klass::magic (void) __attribute__ ((ifunc ("_ZN5Klass8resolverEv")));
@@ -33,6 +34,6 @@ struct Klassier : Klass
3334
int main ()
3435
{
3536
Klassier obj;
36-
37+
3738
return obj.magic () != 0;
3839
}

gcc/testsuite/g++.dg/ext/attr-ifunc-3.C

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ struct Klass
88
{
99
int implementation ();
1010
int magic ();
11-
static void *resolver ();
11+
12+
typedef int (Klass::*MemFuncPtr)();
13+
14+
static MemFuncPtr resolver ();
1215
};
1316

1417
int Klass::implementation (void)
@@ -17,11 +20,9 @@ int Klass::implementation (void)
1720
return 0;
1821
}
1922

20-
void *Klass::resolver (void)
23+
Klass::MemFuncPtr Klass::resolver (void)
2124
{
22-
int (Klass::*pmf) () = &Klass::implementation;
23-
24-
return (void *)(int (*)(Klass *))(((Klass *)0)->*pmf);
25+
return &Klass::implementation;
2526
}
2627

2728
int Klass::magic (void) __attribute__ ((ifunc ("_ZN5Klass8resolverEv")));
@@ -34,6 +35,6 @@ int Foo (Klass &obj, int (Klass::*pmf) ())
3435
int main ()
3536
{
3637
Klass obj;
37-
38+
3839
return Foo (obj, &Klass::magic) != 0;
3940
}

gcc/testsuite/g++.dg/ext/attr-ifunc-4.C

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ struct Klassier : Klass
1313
{
1414
int implementation ();
1515
int magic ();
16-
static void *resolver ();
16+
17+
typedef int (Klass::*MemFuncPtr)();
18+
19+
static MemFuncPtr resolver ();
1720
};
1821

1922
int Klassier::implementation (void)
@@ -22,11 +25,9 @@ int Klassier::implementation (void)
2225
return 0;
2326
}
2427

25-
void *Klassier::resolver (void)
28+
Klassier::MemFuncPtr Klassier::resolver (void)
2629
{
27-
int (Klassier::*pmf) () = &Klassier::implementation;
28-
29-
return (void *)(int (*)(Klassier *))(((Klassier *)0)->*pmf);
30+
return &Klassier::implementation;
3031
}
3132

3233
int Klassier::magic (void) __attribute__ ((ifunc ("_ZN8Klassier8resolverEv")));
@@ -39,6 +40,6 @@ int __attribute__ ((weak)) Foo (Klass &base)
3940
int main ()
4041
{
4142
Klassier obj;
42-
43+
4344
return Foo (obj) != 0;
4445
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// PR c/81854 - weak alias of an incompatible symbol accepted
2+
// { dg-do compile }
3+
// { dg-require-ifunc "" } */
4+
5+
struct Klass
6+
{
7+
int implementation ();
8+
const char* magic ();
9+
10+
typedef int (Klass::*MemFuncPtr)();
11+
12+
static MemFuncPtr resolver ();
13+
};
14+
15+
int Klass::implementation (void)
16+
{
17+
return 0;
18+
}
19+
20+
const char* __attribute__ ((ifunc ("_ZN5Klass8resolverEv")))
21+
Klass::magic (); // { dg-warning "alias between functions of incompatible types" }
22+
23+
24+
25+
Klass::MemFuncPtr
26+
Klass::resolver (void) // { dg-message "aliased declaration here" }
27+
{
28+
return &Klass::implementation;
29+
}

gcc/testsuite/g++.old-deja/g++.abi/vtable2.C

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// { dg-do run }
2-
// { dg-options "-fno-strict-aliasing" }
2+
// { dg-options "-Wno-attributes -fno-strict-aliasing" }
33
// Origin: Mark Mitchell <[email protected]>
44

55
#if defined (__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100
@@ -126,7 +126,8 @@ void S4::s1 ()
126126
extern "C" {
127127
/* We can use weakref here without dg-require-weak, because we know
128128
the symbols are defined, so we don't actually issue the .weak
129-
directives. */
129+
directives. The references to the incompatible virtual S3::s3()
130+
and S4::s1() trigger -Wattributes. */
130131
static void S3_s3 () __attribute__((__weakref__ ("_ZN2S32s3Ev")));
131132
static void S4_s1 () __attribute__((__weakref__ ("_ZN2S42s1Ev")));
132133
}

gcc/testsuite/gcc.dg/attr-ifunc-1.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
/* { dg-require-ifunc "" } */
33
/* { dg-options "" } */
44

5-
#include <stdio.h>
5+
typedef int F (void);
66

77
static int implementation (void)
88
{
9-
printf ("'ere I am JH\n");
9+
__builtin_printf ("'ere I am JH\n");
1010
return 0;
1111
}
1212

13-
static void *resolver (void)
13+
static F* resolver (void)
1414
{
15-
return (void *)implementation;
15+
return implementation;
1616
}
1717

1818
extern int magic (void) __attribute__ ((ifunc ("resolver")));

0 commit comments

Comments
 (0)