From c87e82a6432688f64b6712e69f93a56524652732 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 9 Apr 2013 14:11:38 -0400 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 6 +++++ gcc/cp/rtti.c | 12 ++++------ gcc/testsuite/g++.dg/rtti/typeid10.C | 36 ++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/rtti/typeid10.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0604b550092..c01fb3cb43e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2013-04-09 Jason Merrill + + 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 PR c++/56838 diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index e83d6666d9b..b3c6687a75d 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 00000000000..47b45b1056d --- /dev/null +++ b/gcc/testsuite/g++.dg/rtti/typeid10.C @@ -0,0 +1,36 @@ +// PR c++/25466 +// { dg-do run } + +#include + +const std::type_info *a; + +template +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()) __builtin_abort(); + if (is_polymorphic()) __builtin_abort(); + try + { + is_polymorphic(); + __builtin_abort(); // should have thrown bad_typeid + } + catch (std::bad_typeid&) + { + // OK + } + catch (...) + { + __builtin_abort(); + } +} -- 2.30.2