From 288c5324bf6e418dd94d718d1619464a4f68ff8e Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 14 Jan 2020 21:45:03 +0100 Subject: [PATCH] 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. --- gcc/ChangeLog | 6 ++++++ gcc/ipa-devirt.c | 21 +++++++++++++++++++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/lto/odr-8_0.C | 7 +++++++ gcc/testsuite/g++.dg/lto/odr-8_1.C | 12 ++++++++++++ 5 files changed, 52 insertions(+) create mode 100644 gcc/testsuite/g++.dg/lto/odr-8_0.C create mode 100644 gcc/testsuite/g++.dg/lto/odr-8_1.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3816512..33ca91a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-01-14 Jan Hubicka + + PR lto/91576 + * ipa-devirt.c (odr_types_equivalent_p): Compare TREE_ADDRESSABLE and + TYPE_MODE. + 2020-01-14 David Malcolm * Makefile.in (lang_opt_files): Add analyzer.opt. diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index f003195..b609a77 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -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)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8e3b910..dc42601 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2020-01-14 Jan Hubicka + + 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 * gcc.dg/analyzer/CVE-2005-1689-minimal.c: New test. diff --git a/gcc/testsuite/g++.dg/lto/odr-8_0.C b/gcc/testsuite/g++.dg/lto/odr-8_0.C new file mode 100644 index 0000000..59f5139 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/odr-8_0.C @@ -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; +} diff --git a/gcc/testsuite/g++.dg/lto/odr-8_1.C b/gcc/testsuite/g++.dg/lto/odr-8_1.C new file mode 100644 index 0000000..742df8c --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/odr-8_1.C @@ -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); +} -- 2.7.4