Compare TREE_ADDRESSABLE and TYPE_MODE when ODR checking types.

PR lto/91576
	* ipa-devirt.c (odr_types_equivalent_p): Compare TREE_ADDRESSABLE and
	TYPE_MODE.

	* testsuite/g++.dg/lto/odr-8_0.C: New testcase.
	* testsuite/g++.dg/lto/odr-8_1.C: New testcase.
This commit is contained in:
Jan Hubicka 2020-01-14 21:45:03 +01:00
parent 757bf1dff5
commit 288c5324bf
5 changed files with 52 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2020-01-14 Jan Hubicka <hubicka@ucw.cz>
PR lto/91576
* ipa-devirt.c (odr_types_equivalent_p): Compare TREE_ADDRESSABLE and
TYPE_MODE.
2020-01-14 David Malcolm <dmalcolm@redhat.com>
* Makefile.in (lang_opt_files): Add analyzer.opt.

View File

@ -1544,6 +1544,27 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
return false;
}
if (TREE_ADDRESSABLE (t1) != TREE_ADDRESSABLE (t2)
&& COMPLETE_TYPE_P (t1) && COMPLETE_TYPE_P (t2))
{
warn_odr (t1, t2, NULL, NULL, warn, warned,
G_("one type needs to be constructed while other not"));
gcc_checking_assert (RECORD_OR_UNION_TYPE_P (t1));
return false;
}
/* There is no really good user facing warning for this.
Either the original reason for modes being different is lost during
streaming or we should catch earlier warnings. We however must detect
the mismatch to avoid type verifier from cmplaining on mismatched
types between type and canonical type. See PR91576. */
if (TYPE_MODE (t1) != TYPE_MODE (t2)
&& COMPLETE_TYPE_P (t1) && COMPLETE_TYPE_P (t2))
{
warn_odr (t1, t2, NULL, NULL, warn, warned,
G_("memory layout mismatch"));
return false;
}
gcc_assert (!TYPE_SIZE_UNIT (t1) || !TYPE_SIZE_UNIT (t2)
|| operand_equal_p (TYPE_SIZE_UNIT (t1),
TYPE_SIZE_UNIT (t2), 0));

View File

@ -1,3 +1,9 @@
2020-01-14 Jan Hubicka <hubicka@ucw.cz>
PR lto/91576
* testsuite/g++.dg/lto/odr-8_0.C: New testcase.
* testsuite/g++.dg/lto/odr-8_1.C: New testcase.
2020-01-14 David Malcolm <dmalcolm@redhat.com>
* gcc.dg/analyzer/CVE-2005-1689-minimal.c: New test.

View File

@ -0,0 +1,7 @@
// { dg-lto-do link }
struct a {char c;}; // { dg-lto-message "8: 'struct a' violates the C\\+\\+ One Definition Rule" }
int
test (struct a *a)
{
return a->c;
}

View File

@ -0,0 +1,12 @@
--- a/gcc/testsuite/g++.dg/lto/odr-8_1.C
+++ b/gcc/testsuite/g++.dg/lto/odr-8_1.C
@@ -1,9 +1,9 @@
struct a {char c; a() {} a(struct a &) {}}; // { dg-lto-message "one type needs to be constructed while other not" }
extern int test (struct a *a);
int
main()
{
struct a a;
a.c=0;
return test(&a);
}