From 58b922f813ea1b1eb87c0a6a050546ac27e78c1b Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 13 Feb 2013 12:56:28 -0500 Subject: [PATCH] re PR c++/55993 ([C++11] derived-to-base conversion fails in constant expression) PR c++/55993 * semantics.c (cxx_fold_indirect_ref): Handle empty bases at non-zero offsets, too. From-SVN: r196023 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/semantics.c | 9 +++++++++ gcc/testsuite/g++.dg/cpp0x/constexpr-empty6.C | 11 +++++++++++ 3 files changed, 24 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-empty6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ddd0aa07a5a..977d2458663 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2013-02-13 Jason Merrill + PR c++/55993 + * semantics.c (cxx_fold_indirect_ref): Handle empty bases at + non-zero offsets, too. + PR c++/56155 * decl.c (build_enumerator): Always convert the value to a fixed underlying type. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 34158289623..30c8c522f24 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -7448,6 +7448,15 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) return build4_loc (loc, ARRAY_REF, type, op00, op01, NULL_TREE, NULL_TREE); } + /* Also handle conversion to an empty base class, which + is represented with a NOP_EXPR. */ + else if (is_empty_class (type) + && CLASS_TYPE_P (op00type) + && DERIVED_FROM_P (type, op00type)) + { + *empty_base = true; + return op00; + } /* ((foo *)&struct_with_foo_field)[1] => COMPONENT_REF */ else if (RECORD_OR_UNION_TYPE_P (op00type)) { diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-empty6.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty6.C new file mode 100644 index 00000000000..be9a6c6ad84 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty6.C @@ -0,0 +1,11 @@ +// PR c++/55993 +// { dg-do compile { target c++11 } } + +struct A {}; +struct B:A {}; +struct C:A {}; +struct D:B,C {}; + +constexpr D d {}; +constexpr const C& e=d; // OK +constexpr auto f=static_cast(d); // FAIL