diff options
author | Jason Merrill <jason@redhat.com> | 2013-04-09 14:11:38 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2013-04-09 14:11:38 -0400 |
commit | c87e82a6432688f64b6712e69f93a56524652732 (patch) | |
tree | 6e25f8fc1a042063f7c9aed3ca74aeadc7a7df52 | |
parent | 5017f1d2d31655ef19032f7c143bae64c8ae0142 (diff) | |
download | gcc-c87e82a6432688f64b6712e69f93a56524652732.zip gcc-c87e82a6432688f64b6712e69f93a56524652732.tar.gz gcc-c87e82a6432688f64b6712e69f93a56524652732.tar.bz2 |
re PR c++/25466 (typeid expression fails to throw bad_typeid according to 5.2.8p2)
PR c++/25466
* rtti.c (build_typeid): Check the address of the argument
rather than looking for an INDIRECT_REF.
From-SVN: r197644
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/rtti/typeid10.C | 36 |
3 files changed, 47 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0604b55..c01fb3c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-04-09 Jason Merrill <jason@redhat.com> + + PR c++/25466 + * rtti.c (build_typeid): Check the address of the argument + rather than looking for an INDIRECT_REF. + 2013-04-04 Jason Merrill <jason@redhat.com> PR c++/56838 diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index e83d666..b3c6687 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -326,18 +326,16 @@ build_typeid (tree exp, tsubst_flags_t complain) /* FIXME when integrating with c_fully_fold, mark resolves_to_fixed_type_p case as a non-constant expression. */ - if (INDIRECT_REF_P (exp) - && TYPE_PTR_P (TREE_TYPE (TREE_OPERAND (exp, 0))) - && TYPE_POLYMORPHIC_P (TREE_TYPE (exp)) + if (TYPE_POLYMORPHIC_P (TREE_TYPE (exp)) && ! resolves_to_fixed_type_p (exp, &nonnull) && ! nonnull) { /* So we need to look into the vtable of the type of exp. - This is an lvalue use of expr then. */ - exp = mark_lvalue_use (exp); + Make sure it isn't a null lvalue. */ + exp = cp_build_addr_expr (exp, complain); exp = stabilize_reference (exp); - cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0), - complain); + cond = cp_convert (boolean_type_node, exp, complain); + exp = cp_build_indirect_ref (exp, RO_NULL, complain); } exp = get_tinfo_decl_dynamic (exp, complain); diff --git a/gcc/testsuite/g++.dg/rtti/typeid10.C b/gcc/testsuite/g++.dg/rtti/typeid10.C new file mode 100644 index 0000000..47b45b1 --- /dev/null +++ b/gcc/testsuite/g++.dg/rtti/typeid10.C @@ -0,0 +1,36 @@ +// PR c++/25466 +// { dg-do run } + +#include <typeinfo> + +const std::type_info *a; + +template <class T> +bool is_polymorphic() { + bool result(false); + const std::type_info &a1 = typeid( (result=true), *(T*)0); + a = &a1; + return result; +} + +struct non_polymorphic {}; +struct polymorphic { virtual ~polymorphic() {} }; + + +int main() { + if (is_polymorphic<int>()) __builtin_abort(); + if (is_polymorphic<non_polymorphic>()) __builtin_abort(); + try + { + is_polymorphic<polymorphic>(); + __builtin_abort(); // should have thrown bad_typeid + } + catch (std::bad_typeid&) + { + // OK + } + catch (...) + { + __builtin_abort(); + } +} |