From a8f9fd92a02864246bbefdd14b106352901de6be Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Mon, 11 Jun 2018 11:28:58 +0000 Subject: [PATCH] C++ front-end: support pointer to non-method members --- .../cpp/pointer_to_member_conversion1/test.desc | 5 +---- .../cpp/pointer_to_member_conversion2/test.desc | 6 ++---- src/cpp/cpp_typecheck_conversions.cpp | 17 +++++++++++++++++ src/cpp/cpp_typecheck_expr.cpp | 14 +++++++------- src/cpp/cpp_typecheck_initializer.cpp | 3 +++ src/cpp/cpp_typecheck_resolve.cpp | 9 +++++++-- 6 files changed, 37 insertions(+), 17 deletions(-) diff --git a/regression/cpp/pointer_to_member_conversion1/test.desc b/regression/cpp/pointer_to_member_conversion1/test.desc index 7851737adc1..1567bd1e5d4 100644 --- a/regression/cpp/pointer_to_member_conversion1/test.desc +++ b/regression/cpp/pointer_to_member_conversion1/test.desc @@ -1,10 +1,7 @@ -KNOWNBUG +CORE main.cpp ^EXIT=0$ ^SIGNAL=0$ -^VERIFICATION SUCCESSFUL$ -- ^warning: ignoring --- -should exercise cpp_typecheckt::standard_conversion_pointer_to_member, cpp/cpp_typecheck_conversion.cpp:610 once other bugs are fixed diff --git a/regression/cpp/pointer_to_member_conversion2/test.desc b/regression/cpp/pointer_to_member_conversion2/test.desc index 57b8cb22426..1e3c6fc2024 100644 --- a/regression/cpp/pointer_to_member_conversion2/test.desc +++ b/regression/cpp/pointer_to_member_conversion2/test.desc @@ -1,11 +1,9 @@ -KNOWNBUG +CORE main.cpp ^EXIT=(64|1)$ ^SIGNAL=0$ -invalid implicit conversion +pointer-to-member type error ^CONVERSION ERROR$ -- ^warning: ignoring --- -should exercise cpp_typecheckt::standard_conversion_pointer_to_member, cpp/cpp_typecheck_conversion.cpp:610 once other bugs are fixed diff --git a/src/cpp/cpp_typecheck_conversions.cpp b/src/cpp/cpp_typecheck_conversions.cpp index 77ec96ffb83..4eb8eadbbfa 100644 --- a/src/cpp/cpp_typecheck_conversions.cpp +++ b/src/cpp/cpp_typecheck_conversions.cpp @@ -1595,9 +1595,11 @@ bool cpp_typecheckt::cast_away_constness( if(is_reference(nt1)) nt1.remove(ID_C_reference); + nt1.remove("to-member"); if(is_reference(nt2)) nt2.remove(ID_C_reference); + nt2.remove("to-member"); // substitute final subtypes std::vector snt1; @@ -2021,6 +2023,21 @@ bool cpp_typecheckt::static_typecast( return true; } } + else if( + type.find("to-member").is_nil() && + e.type().find("to-member").is_not_nil()) + { + if(type.subtype() != e.type().subtype()) + return false; + + struct_typet from_struct = to_struct_type( + follow(static_cast(e.type().find("to-member")))); + + new_expr = e; + new_expr.type().add("to-member") = from_struct; + + return true; + } else return false; } diff --git a/src/cpp/cpp_typecheck_expr.cpp b/src/cpp/cpp_typecheck_expr.cpp index 1476b0e2028..3764435fd1e 100644 --- a/src/cpp/cpp_typecheck_expr.cpp +++ b/src/cpp/cpp_typecheck_expr.cpp @@ -748,6 +748,13 @@ void cpp_typecheckt::typecheck_expr_address_of(exprt &expr) } } } + else if( + expr.op0().id() == ID_ptrmember && expr.op0().op0().id() == "cpp-this") + { + expr.type() = pointer_type(expr.op0().type()); + expr.type().add("to-member") = expr.op0().op0().type().subtype(); + return; + } // the C front end does not know about references const bool is_ref=is_reference(expr.type()); @@ -2626,13 +2633,6 @@ void cpp_typecheckt::convert_pmop(exprt &expr) throw 0; } - if(expr.op1().type().subtype().id()!=ID_code) - { - error().source_location=expr.find_source_location(); - error() << "pointers to data member are not supported" << eom; - throw 0; - } - typecheck_expr_main(expr.op1()); if(expr.op0().type().id()!=ID_pointer) diff --git a/src/cpp/cpp_typecheck_initializer.cpp b/src/cpp/cpp_typecheck_initializer.cpp index adc598e855c..871cd972af0 100644 --- a/src/cpp/cpp_typecheck_initializer.cpp +++ b/src/cpp/cpp_typecheck_initializer.cpp @@ -133,6 +133,9 @@ void cpp_typecheckt::convert_initializer(symbolt &symbol) typecheck_expr(symbol.value); + if(symbol.value.type().find("to-member").is_not_nil()) + symbol.type.add("to-member") = symbol.value.type().find("to-member"); + if(symbol.value.id()==ID_initializer_list || symbol.value.id()==ID_string_constant) { diff --git a/src/cpp/cpp_typecheck_resolve.cpp b/src/cpp/cpp_typecheck_resolve.cpp index 86fcddea3bc..f18040f3dfb 100644 --- a/src/cpp/cpp_typecheck_resolve.cpp +++ b/src/cpp/cpp_typecheck_resolve.cpp @@ -309,11 +309,16 @@ exprt cpp_typecheck_resolvet::convert_identifier( } else { - // this has to be a method + // this has to be a method or form a pointer-to-member expression if(identifier.is_method) e=cpp_symbol_expr(cpp_typecheck.lookup(identifier.identifier)); else - e.make_nil(); + { + e.id(ID_ptrmember); + e.copy_to_operands( + exprt("cpp-this", pointer_type(compound_symbol.type))); + e.type() = type; + } } } }