From 8ccc80653e74a08a013b8174254a836978c6de7e Mon Sep 17 00:00:00 2001 From: user1 Date: Thu, 11 May 2017 11:29:29 -0700 Subject: added support for the case when a function argument expression is the address of an array subscript --- safercpp/safercpp-arr.cpp | 448 ++++++++++++++++++++++++++++++---------------- 1 file changed, 291 insertions(+), 157 deletions(-) (limited to 'safercpp') diff --git a/safercpp/safercpp-arr.cpp b/safercpp/safercpp-arr.cpp index c057188..f647ed1 100644 --- a/safercpp/safercpp-arr.cpp +++ b/safercpp/safercpp-arr.cpp @@ -703,6 +703,20 @@ public: clang::QualType m_qtype; }; +class CStraightReplacementExprTextModifier : public CExprTextModifier { +public: + CStraightReplacementExprTextModifier(const std::string& replacement_text) : + m_replacement_text(replacement_text) {} + virtual ~CStraightReplacementExprTextModifier() {} + virtual std::string modified_copy(const std::string& input_text, const clang::Expr* expr_ptr = nullptr) const { + return m_replacement_text; + } + virtual std::string species_str() const { + return "straight replacement"; + } + std::string m_replacement_text; +}; + class CExprTextModifierStack : public std::vector> { public: }; @@ -777,23 +791,83 @@ public: return (*(static_cast(m_expr_cptr))); } virtual void update_current_text() { - if (false) { + if (true) { /* Do we need to update the kids first? */ - m_cond_shptr->update_current_text(); - m_lhs_shptr->update_current_text(); - m_rhs_shptr->update_current_text(); + cond_shptr()->update_current_text(); + lhs_shptr()->update_current_text(); + rhs_shptr()->update_current_text(); } - std::string updated_text = m_cond_shptr->m_current_text_str + " ? " - + m_lhs_shptr->m_current_text_str + " : " + m_rhs_shptr->m_current_text_str; + std::string updated_text = cond_shptr()->m_current_text_str + " ? " + + lhs_shptr()->m_current_text_str + " : " + rhs_shptr()->m_current_text_str; updated_text = modified_copy(updated_text); m_current_text_str = updated_text; } + std::shared_ptr& cond_shptr() { + if (3 != m_children_shptrs.size()) { + assert(false); + return m_cond_shptr; + } else { + return m_children_shptrs[0]; + } + } + std::shared_ptr& lhs_shptr() { + if (3 != m_children_shptrs.size()) { + assert(false); + return m_lhs_shptr; + } else { + return m_children_shptrs[1]; + } + } + std::shared_ptr& rhs_shptr() { + if (3 != m_children_shptrs.size()) { + assert(false); + return m_rhs_shptr; + } else { + return m_children_shptrs[2]; + } + } + +private: std::shared_ptr m_cond_shptr; std::shared_ptr m_lhs_shptr; std::shared_ptr m_rhs_shptr; }; +class CAddressofArraySubscriptExprConversionState : public CExprConversionState { +public: + CAddressofArraySubscriptExprConversionState(const clang::UnaryOperator& addrofexpr_cref, Rewriter &Rewrite, const clang::ArraySubscriptExpr& arraysubscriptexpr_cref) : CExprConversionState(addrofexpr_cref, Rewrite), m_arraysubscriptexpr_cptr(&arraysubscriptexpr_cref) { + assert(clang::UnaryOperatorKind::UO_AddrOf == addrofexpr_cref.getOpcode()); + m_arraysubscriptexpr_shptr = std::make_shared(*m_arraysubscriptexpr_cptr, Rewrite); + m_children_shptrs.push_back(m_arraysubscriptexpr_shptr); + } + const clang::UnaryOperator& addrofexpr_cref() const { + return (*(static_cast(m_expr_cptr))); + } + virtual void update_current_text() { + if (true) { + /* Do we need to update the kids first? */ + arraysubscriptexpr_shptr()->update_current_text(); + } + std::string updated_text = "&(" + arraysubscriptexpr_shptr()->m_current_text_str + ")"; + updated_text = modified_copy(updated_text); + m_current_text_str = updated_text; + } + + std::shared_ptr& arraysubscriptexpr_shptr() { + if (1 != m_children_shptrs.size()) { + assert(false); + return m_arraysubscriptexpr_shptr; + } else { + return m_children_shptrs[0]; + } + } + +private: + std::shared_ptr m_arraysubscriptexpr_shptr; + const clang::ArraySubscriptExpr* m_arraysubscriptexpr_cptr = nullptr; +}; + template std::shared_ptr make_expr_conversion_state_shared_ptr(Args&&... args) { std::shared_ptr retval = std::make_shared(std::forward(args)...); @@ -807,13 +881,21 @@ public: iterator insert( const std::shared_ptr& cr_shptr ) { iterator retval(end()); if (!cr_shptr) { assert(false); } else { + decltype((*cr_shptr).m_children_shptrs) mapped_children_shptrs; + for (auto& child_shptr_ref : (*cr_shptr).m_children_shptrs) { + //value_type val((*child_shptr_ref).m_expr_cptr, child_shptr_ref); + //auto res2 = base_class::insert(val); + auto iter1 = insert(child_shptr_ref); + if (child_shptr_ref != (*iter1).second) { + int q = 7; + } + mapped_children_shptrs.push_back((*iter1).second); + } + value_type val((*cr_shptr).m_expr_cptr, cr_shptr); auto res1 = base_class::insert(val); retval = res1.first; - for (auto& child_shptr_ref : (*cr_shptr).m_children_shptrs) { - value_type val((*child_shptr_ref).m_expr_cptr, child_shptr_ref); - auto res1 = base_class::insert(val); - } + (*((*retval).second)).m_children_shptrs = mapped_children_shptrs; } return retval; } @@ -932,6 +1014,19 @@ public: const CDDeclIndirection m_ddecl_indirection2; }; +class CAssignmentTargetConstrainsAddressofArraySubscriptExprArray2ReplacementAction : public CArray2ReplacementAction { +public: + CAssignmentTargetConstrainsAddressofArraySubscriptExprArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection, + const clang::UnaryOperator& addrofexpr_cref, const clang::ArraySubscriptExpr& arraysubscriptexpr_cref) : + CArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_addrofexpr_cptr(&addrofexpr_cref), m_arraysubscriptexpr_cptr(&arraysubscriptexpr_cref) {} + virtual ~CAssignmentTargetConstrainsAddressofArraySubscriptExprArray2ReplacementAction() {} + + virtual void do_replacement(CState1& state1) const; + + const clang::UnaryOperator* m_addrofexpr_cptr = nullptr; + const clang::ArraySubscriptExpr* m_arraysubscriptexpr_cptr = nullptr; +}; + class CDDecl2ReplacementActionMap : public std::multimap> { public: typedef std::multimap> base_class; @@ -1929,6 +2024,47 @@ void CSameTypeArray2ReplacementAction::do_replacement(CState1& state1) const { } } +void CAssignmentTargetConstrainsAddressofArraySubscriptExprArray2ReplacementAction::do_replacement(CState1& state1) const { + Rewriter &Rewrite = m_Rewrite; + const MatchFinder::MatchResult &MR = m_MR; + + const clang::UnaryOperator* UO = m_addrofexpr_cptr; + const ArraySubscriptExpr* ASE = m_arraysubscriptexpr_cptr; + if (UO && ASE) { + auto UOSR = nice_source_range(UO->getSourceRange(), (*this).m_Rewrite); + auto ase_SR = nice_source_range(ASE->getSourceRange(), (*this).m_Rewrite); + if ((UOSR.isValid()) && (ase_SR.isValid())) { + auto uocs_iter = state1.m_expr_conversion_state_map.find(UO); + if (state1.m_expr_conversion_state_map.end() == uocs_iter) { + std::shared_ptr shptr1 = make_expr_conversion_state_shared_ptr(*UO, m_Rewrite, *ASE); + uocs_iter = state1.m_expr_conversion_state_map.insert(shptr1); + } + auto& uocs_shptr_ref = (*uocs_iter).second; + + auto index_expr_cptr = ASE->getIdx(); + auto array_expr_cptr = ASE->getBase(); + if (index_expr_cptr && array_expr_cptr) { + auto index_expr_SR = nice_source_range(index_expr_cptr->getSourceRange(), (*this).m_Rewrite); + auto array_expr_SR = nice_source_range(array_expr_cptr->getSourceRange(), (*this).m_Rewrite); + if (index_expr_SR.isValid() && array_expr_SR.isValid()) { + std::string index_expr_text = (*this).m_Rewrite.getRewrittenText(index_expr_SR); + std::string array_expr_text = (*this).m_Rewrite.getRewrittenText(array_expr_SR); + + std::string UO_replacement_text = "((" + array_expr_text + ") + (" + index_expr_text + "))"; + if (ConvertToSCPP) { + std::shared_ptr shptr1 = std::make_shared(UO_replacement_text); + (*uocs_shptr_ref).m_expr_text_modifier_stack.push_back(shptr1); + (*uocs_shptr_ref).update_current_text(); + + (*this).m_Rewrite.ReplaceText(UOSR, (*uocs_shptr_ref).m_current_text_str); + } + } + } + + } + } +} + void CConditionalOperatorReconciliation2ReplacementAction::do_replacement(CState1& state1) const { const clang::ConditionalOperator* CO = m_CO; const Expr* COND = nullptr; @@ -2044,6 +2180,8 @@ void CConditionalOperatorReconciliation2ReplacementAction::do_replacement(CState (*lhscs_shptr_ref).m_expr_text_modifier_stack.push_back(shptr1); (*lhscs_shptr_ref).update_current_text(); } + } else { + int q = 7; } } if (rhs_needs_to_be_wrapped) { @@ -2063,6 +2201,8 @@ void CConditionalOperatorReconciliation2ReplacementAction::do_replacement(CState (*rhscs_shptr_ref).m_expr_text_modifier_stack.push_back(shptr1); (*rhscs_shptr_ref).update_current_text(); } + } else { + int q = 7; } } @@ -2076,6 +2216,8 @@ void CConditionalOperatorReconciliation2ReplacementAction::do_replacement(CState auto& ddcs_ref = (*ddcs_map_iter).second; ddcs_ref.m_initializer_info_str = " = " + cocs_shptr_ref.m_current_text_str; + + update_declaration(*m_var_DD, m_Rewrite, state1); } } @@ -2086,6 +2228,7 @@ void CConditionalOperatorReconciliation2ReplacementAction::do_replacement(CState struct CLeadingAddressofOperatorInfo { bool leading_addressof_operator_detected = false; const clang::Expr* without_leading_addressof_operator_expr_cptr = nullptr; + const clang::UnaryOperator* addressof_unary_operator_cptr = nullptr; }; CLeadingAddressofOperatorInfo leading_addressof_operator_info_from_stmt(const clang::Stmt& stmt_cref, int depth = 0) { CLeadingAddressofOperatorInfo retval; @@ -2098,6 +2241,7 @@ CLeadingAddressofOperatorInfo leading_addressof_operator_info_from_stmt(const cl if (UO) { if (clang::UnaryOperatorKind::UO_AddrOf == UO->getOpcode()) { retval.leading_addressof_operator_detected = true; + retval.addressof_unary_operator_cptr = UO; auto child_iter = ST->child_begin(); if (child_iter != ST->child_end()) { @@ -2624,9 +2768,6 @@ public: } else { return; } - if (std::string::npos != source_location_str.find("526")) { - int q = 5; - } if (filtered_out_by_location(MR, BOSL)) { return void(); @@ -2761,15 +2902,14 @@ public: } const clang::Type* lhs_TP = lhs_QT.getTypePtr(); - auto lhs_type_str = clang::QualType::getAsString(lhs_QT.split()); + auto lhs_type_str = lhs_QT.getAsString(); std::string lhs_element_type_str; if (lhs_TP->isArrayType()) { auto ATP = llvm::cast(lhs_TP); assert(nullptr != ATP); auto element_type = ATP->getElementType(); - auto elementSplitQualType = element_type.split(); - auto type_str = clang::QualType::getAsString(elementSplitQualType); + auto type_str = element_type.getAsString(); if (("char" != type_str) && ("const char" != type_str)) { lhs_element_type_str = type_str; } @@ -2777,8 +2917,7 @@ public: auto TPP = llvm::cast(lhs_TP); assert(nullptr != TPP); auto target_type = TPP->getPointeeType(); - auto splitQualType = target_type.split(); - auto type_str = clang::QualType::getAsString(splitQualType); + auto type_str = target_type.getAsString(); if (("char" != type_str) && ("const char" != type_str)) { lhs_element_type_str = type_str; } @@ -2873,6 +3012,10 @@ public: return void(); } + if (std::string::npos != source_location_str.find("288")) { + int q = 5; + } + auto function_decl = CE->getDirectCallee(); auto num_args = CE->getNumArgs(); if (function_decl && ((1 == num_args) || (2 == num_args))) { @@ -2993,14 +3136,15 @@ public: auto ATP = llvm::cast(TP); assert(nullptr != ATP); auto element_type = ATP->getElementType(); - auto elementSplitQualType = element_type.split(); - element_type_str = clang::QualType::getAsString(elementSplitQualType); + auto type_str = element_type.getAsString(); + if (("char" != type_str) && ("const char" != type_str)) { + element_type_str = type_str; + } } else if (TP->isPointerType()) { auto TPP = llvm::cast(TP); assert(nullptr != TPP); auto target_type = TPP->getPointeeType(); - auto splitQualType = target_type.split(); - auto type_str = clang::QualType::getAsString(splitQualType); + auto type_str = target_type.getAsString(); if (("char" != type_str) && ("const char" != type_str)) { element_type_str = type_str; } @@ -3105,35 +3249,23 @@ public: bool ends_with_free = ((lc_function_name.size() >= free_str.size()) && (0 == lc_function_name.compare(lc_function_name.size() - free_str.size(), free_str.size(), free_str))); if (ends_with_free) { - auto iter = CE->arg_begin(); - assert((*iter)->getType().getTypePtrOrNull()); - auto arg_source_range = nice_source_range((*iter)->getSourceRange(), Rewrite); + auto arg_iter = CE->arg_begin(); + assert((*arg_iter)->getType().getTypePtrOrNull()); + auto arg_source_range = nice_source_range((*arg_iter)->getSourceRange(), Rewrite); std::string arg_source_text; if (arg_source_range.isValid()) { arg_source_text = Rewrite.getRewrittenText(arg_source_range); //auto arg_source_text_sans_ws = with_whitespace_removed(arg_source_text); + QualType QT; - std::string element_type_str; - clang::SourceRange decl_source_range; std::string variable_name; std::string ce_replacement_code; - const clang::DeclaratorDecl* DD = nullptr; - auto decl = DRE->getDecl(); - DD = dynamic_cast(decl); - auto VD = dynamic_cast(decl); + auto res2 = infer_array_type_info_from_stmt(*(*(CE->arg_begin())), "malloc target", (*this).m_state1); + auto DD = res2.ddecl_cptr; - const clang::FieldDecl* FD = nullptr; - if (nullptr != ME) { - auto member_decl = ME->getMemberDecl(); - FD = dynamic_cast(ME->getMemberDecl()); - } - if (nullptr != FD) { - DD = FD; - } else if (nullptr != VD) { - DD = VD; - } else { - int q = 7; + if (res2.update_declaration_flag) { + update_declaration(*DD, Rewrite, m_state1); } if (nullptr != DD) { @@ -3156,26 +3288,44 @@ public: return; } - auto res2 = infer_array_type_info_from_stmt(*(*(CE->arg_begin())), "malloc target", (*this).m_state1, DD); + const clang::Type* TP = QT.getTypePtr(); + auto type_str = QT.getAsString(); - if (res2.update_declaration_flag) { - update_declaration(*DD, Rewrite, m_state1); + std::string element_type_str; + if (TP->isArrayType()) { + auto ATP = llvm::cast(TP); + assert(nullptr != ATP); + auto element_type = ATP->getElementType(); + auto type_str = element_type.getAsString(); + if (("char" != type_str) && ("const char" != type_str)) { + element_type_str = type_str; + } + } else if (TP->isPointerType()) { + auto TPP = llvm::cast(TP); + assert(nullptr != TPP); + auto target_type = TPP->getPointeeType(); + auto type_str = target_type.getAsString(); + if (("char" != type_str) && ("const char" != type_str)) { + element_type_str = type_str; + } } - ce_replacement_code = "(" + arg_source_text + ")"; - ce_replacement_code += ".resize(0)"; + if ("" != element_type_str) { + ce_replacement_code = "(" + arg_source_text + ")"; + ce_replacement_code += ".resize(0)"; - if (ConvertToSCPP && decl_source_range.isValid() && (CESR.isValid()) - && (nullptr != res2.ddecl_conversion_state_ptr)) { - auto cr_shptr = std::make_shared(Rewrite, MR, CDDeclIndirection(*DD, res2.indirection_level), CE, ce_replacement_code); + if (ConvertToSCPP && decl_source_range.isValid() && (CESR.isValid()) + && (nullptr != res2.ddecl_conversion_state_ptr)) { + auto cr_shptr = std::make_shared(Rewrite, MR, CDDeclIndirection(*(res2.ddecl_cptr), res2.indirection_level), CE, ce_replacement_code); - if ((*(res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_an_array(res2.indirection_level)) { - (*cr_shptr).do_replacement(m_state1); + if ((*(res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_an_array(res2.indirection_level)) { + (*cr_shptr).do_replacement(m_state1); + } else { + m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr); + } } else { - m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr); + int q = 7; } - } else { - int q = 7; } } int q = 5; @@ -3244,72 +3394,49 @@ public: lhs_source_text = Rewrite.getRewrittenText(lhs_source_range); //auto lhs_source_text_sans_ws = with_whitespace_removed(lhs_source_text); - QualType QT; - std::string element_type_str; - clang::SourceRange decl_source_range; - std::string variable_name; - std::string bo_replacement_code; - const clang::DeclaratorDecl* DD = nullptr; - - auto decl = DRE->getDecl(); - DD = dynamic_cast(decl); - auto VD = dynamic_cast(decl); - - const clang::FieldDecl* FD = nullptr; - if (nullptr != ME) { - auto member_decl = ME->getMemberDecl(); - FD = dynamic_cast(ME->getMemberDecl()); - } - if (nullptr != FD) { - DD = FD; - } else if (nullptr != VD) { - DD = VD; - } else { - int q = 7; + auto lhs_res2 = infer_array_type_info_from_stmt(*LHS, "set to null", (*this).m_state1); + bool lhs_is_an_indirect_type = is_an_indirect_type(LHS->getType()); + + if (lhs_res2.update_declaration_flag) { + update_declaration(*(lhs_res2.ddecl_cptr), Rewrite, m_state1); } - if (nullptr != DD) { - auto decl_source_range = nice_source_range(DD->getSourceRange(), Rewrite); - auto decl_source_location_str = decl_source_range.getBegin().printToString(*MR.SourceManager); - std::string decl_source_text; - if (decl_source_range.isValid()) { - decl_source_text = Rewrite.getRewrittenText(decl_source_range); - } else { - return; - } - QT = DD->getType(); - variable_name = DD->getNameAsString(); - - auto qualified_name = DD->getQualifiedNameAsString(); - static const std::string mse_namespace_str1 = "mse::"; - static const std::string mse_namespace_str2 = "::mse::"; - if ((0 == qualified_name.compare(0, mse_namespace_str1.size(), mse_namespace_str1)) - || (0 == qualified_name.compare(0, mse_namespace_str2.size(), mse_namespace_str2))) { - return; + auto lhs_QT = LHS->getType(); + const clang::Type* lhs_TP = lhs_QT.getTypePtr(); + auto lhs_type_str = lhs_QT.getAsString(); + + std::string lhs_element_type_str; + if (lhs_TP->isArrayType()) { + auto ATP = llvm::cast(lhs_TP); + assert(nullptr != ATP); + auto element_type = ATP->getElementType(); + auto type_str = element_type.getAsString(); + if (("char" != type_str) && ("const char" != type_str)) { + lhs_element_type_str = type_str; } - - auto res2 = infer_array_type_info_from_stmt(*LHS, "set to null", (*this).m_state1, DD); - - if (res2.update_declaration_flag) { - update_declaration(*DD, Rewrite, m_state1); + } else if (lhs_TP->isPointerType()) { + auto TPP = llvm::cast(lhs_TP); + assert(nullptr != TPP); + auto target_type = TPP->getPointeeType(); + auto type_str = target_type.getAsString(); + if (("char" != type_str) && ("const char" != type_str)) { + lhs_element_type_str = type_str; } + } - auto lhs_source_range = nice_source_range(LHS->getSourceRange(), Rewrite); - auto lhs_source_text = Rewrite.getRewrittenText(lhs_source_range); - bo_replacement_code += "(" + lhs_source_text + ")"; - bo_replacement_code += ".resize(0)"; + if ("" != lhs_element_type_str) { + if (ConvertToSCPP && (lhs_res2.ddecl_conversion_state_ptr) && lhs_is_an_indirect_type) { + auto lhs_source_text = Rewrite.getRewrittenText(lhs_source_range); + std::string bo_replacement_code = "(" + lhs_source_text + ")"; + bo_replacement_code += ".resize(0)"; - if (ConvertToSCPP && decl_source_range.isValid() && (BOSR.isValid()) - && (nullptr != res2.ddecl_conversion_state_ptr)) { - auto cr_shptr = std::make_shared(Rewrite, MR, CDDeclIndirection(*DD, res2.indirection_level), BO, bo_replacement_code); + auto cr_shptr = std::make_shared(Rewrite, MR, CDDeclIndirection(*(lhs_res2.ddecl_cptr), lhs_res2.indirection_level), BO, bo_replacement_code); - if ((*(res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_an_array(res2.indirection_level)) { + if ((*(lhs_res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_an_array(lhs_res2.indirection_level)) { (*cr_shptr).do_replacement(m_state1); } else { m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr); } - } else { - int q = 7; } } int q = 5; @@ -3448,8 +3575,7 @@ public: auto ATP = llvm::cast(arg1_TP); assert(nullptr != ATP); auto element_type = ATP->getElementType(); - auto elementSplitQualType = element_type.split(); - auto type_str = clang::QualType::getAsString(elementSplitQualType); + auto type_str = element_type.getAsString(); if (("char" != type_str) && ("const char" != type_str)) { arg1_element_type_str = type_str; } @@ -3457,8 +3583,7 @@ public: auto TPP = llvm::cast(arg1_TP); assert(nullptr != TPP); auto target_type = TPP->getPointeeType(); - auto splitQualType = target_type.split(); - auto type_str = clang::QualType::getAsString(splitQualType); + auto type_str = target_type.getAsString(); if (("char" != type_str) && ("const char" != type_str)) { arg1_element_type_str = type_str; } @@ -3627,8 +3752,7 @@ public: auto ATP = llvm::cast(arg1_TP); assert(nullptr != ATP); auto element_type = ATP->getElementType(); - auto elementSplitQualType = element_type.split(); - auto type_str = clang::QualType::getAsString(elementSplitQualType); + auto type_str = element_type.getAsString(); if (("char" != type_str) && ("const char" != type_str)) { arg1_element_type_str = type_str; } @@ -3636,8 +3760,7 @@ public: auto TPP = llvm::cast(arg1_TP); assert(nullptr != TPP); auto target_type = TPP->getPointeeType(); - auto splitQualType = target_type.split(); - auto type_str = clang::QualType::getAsString(splitQualType); + auto type_str = target_type.getAsString(); if (("char" != type_str) && ("const char" != type_str)) { arg1_element_type_str = type_str; } @@ -4126,12 +4249,6 @@ public: if (ends_with_free || ends_with_alloc || ends_with_realloc || is_memcpy || is_memset || begins_with__builtin_) { return void(); } - if ("lodepng_deflate" == function_name) { - int q = 5; - } - if ("deflate" == function_name) { - int q = 5; - } auto function_decls_range = function_decl1->redecls(); @@ -4155,11 +4272,34 @@ public: bool rhs_is_an_indirect_type = is_an_indirect_type(arg_EX->getType()); assert(lhs_is_an_indirect_type == rhs_is_an_indirect_type); + auto res1 = m_state1.m_ddecl_conversion_state_map.insert(*param_VD); + auto ddcs_map_iter = res1.first; + auto& ddcs_ref = (*ddcs_map_iter).second; + bool update_declaration_flag = res1.second; + size_t lhs_indirection_level_adjustment = 0; auto rhs_res3 = leading_addressof_operator_info_from_stmt(*arg_EX); if (rhs_res3.without_leading_addressof_operator_expr_cptr) { + assert(rhs_res3.leading_addressof_operator_detected && rhs_res3.addressof_unary_operator_cptr); + arg_EX = rhs_res3.without_leading_addressof_operator_expr_cptr; lhs_indirection_level_adjustment = 1; + + const clang::ArraySubscriptExpr* array_subscript_expr_cptr = nullptr; + if (clang::Stmt::StmtClass::ArraySubscriptExprClass == (*(rhs_res3.without_leading_addressof_operator_expr_cptr)).getStmtClass()) { + assert(llvm::isa(rhs_res3.without_leading_addressof_operator_expr_cptr)); + array_subscript_expr_cptr = llvm::cast(rhs_res3.without_leading_addressof_operator_expr_cptr); + } + if (array_subscript_expr_cptr) { + std::shared_ptr cr_shptr = std::make_shared(Rewrite, MR, + CDDeclIndirection(*param_VD, 0), *(rhs_res3.addressof_unary_operator_cptr), *array_subscript_expr_cptr); + + if (ddcs_ref.has_been_determined_to_be_an_array(0)) { + (*cr_shptr).do_replacement(m_state1); + } else { + m_state1.m_array2_contingent_replacement_map.insert(cr_shptr); + } + } } auto rhs_res2 = infer_array_type_info_from_stmt(*arg_EX, "", (*this).m_state1); @@ -4217,11 +4357,6 @@ public: } } - auto res1 = m_state1.m_ddecl_conversion_state_map.insert(*param_VD); - auto ddcs_map_iter = res1.first; - auto& ddcs_ref = (*ddcs_map_iter).second; - bool update_declaration_flag = res1.second; - if (ddcs_ref.m_ddecl_cptr && update_declaration_flag) { update_declaration(*(ddcs_ref.m_ddecl_cptr), Rewrite, m_state1); } @@ -4243,6 +4378,8 @@ public: cr_shptr = std::make_shared(Rewrite, MR, CDDeclIndirection(*param_VD, i + lhs_indirection_level_adjustment), CDDeclIndirection(*(rhs_res2.ddecl_cptr), rhs_res2.indirection_level + i)); } else { + /* Levels of indirection beyond the first one must be of the same type, + * not just of "compatible" types. */ cr_shptr = std::make_shared(Rewrite, MR, CDDeclIndirection(*param_VD, i + lhs_indirection_level_adjustment), CDDeclIndirection(*(rhs_res2.ddecl_cptr), rhs_res2.indirection_level + i)); } @@ -4264,8 +4401,8 @@ public: cr_shptr = std::make_shared(Rewrite, MR, CDDeclIndirection(*(rhs_res2.ddecl_cptr), rhs_res2.indirection_level + i), CDDeclIndirection(*param_VD, i + lhs_indirection_level_adjustment)); } else { - /* This is actually redundant since we decided to make CSameTypeArray2ReplacementAction - * apply the constraint in both directions already. But the redundancy doesn't hurt. */ + /* Levels of indirection beyond the first one must be of the same type, + * not just of "compatible" types. */ cr_shptr = std::make_shared(Rewrite, MR, CDDeclIndirection(*(rhs_res2.ddecl_cptr), rhs_res2.indirection_level + i), CDDeclIndirection(*param_VD, i + lhs_indirection_level_adjustment)); } @@ -4429,8 +4566,8 @@ public: Matcher.addMatcher(clang::ast_matchers::declaratorDecl().bind("mcsssvardecl"), &HandlerForSSSVarDecl2); Matcher.addMatcher(expr(allOf( - hasParent(expr(anyOf( \ - unaryOperator(hasOperatorName("++")), unaryOperator(hasOperatorName("--")), \ + hasParent(expr(anyOf( + unaryOperator(hasOperatorName("++")), unaryOperator(hasOperatorName("--")), binaryOperator(hasOperatorName("+=")), binaryOperator(hasOperatorName("-=")), castExpr(hasParent(expr(anyOf( binaryOperator(hasOperatorName("+")), binaryOperator(hasOperatorName("+=")), @@ -4452,36 +4589,34 @@ public: hasOperatorName("="), hasRHS( anyOf( - cStyleCastExpr(has(callExpr().bind("mcsssmalloc2"))), - callExpr().bind("mcsssmalloc2") + cStyleCastExpr(has(ignoringParenCasts(callExpr().bind("mcsssmalloc2")))), + ignoringParenCasts(callExpr().bind("mcsssmalloc2")) ) ), - hasLHS(anyOf( - memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssmalloc3")))).bind("mcsssmalloc4"), + hasLHS(ignoringParenCasts(anyOf( + memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssmalloc3")))).bind("mcsssmalloc4"), declRefExpr().bind("mcsssmalloc3"), hasDescendant(memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssmalloc3")))).bind("mcsssmalloc4")), hasDescendant(declRefExpr().bind("mcsssmalloc3")) - )), + ))), hasLHS(expr(hasType(pointerType()))) )).bind("mcsssmalloc1"), &HandlerForSSSMalloc2); Matcher.addMatcher(declStmt(hasDescendant( - varDecl(hasInitializer(ignoringImpCasts( - anyOf( - cStyleCastExpr(has(callExpr().bind("mcsssmallocinitializer2"))), + varDecl(hasInitializer(ignoringParenCasts( callExpr().bind("mcsssmallocinitializer2") - ) ))).bind("mcsssmallocinitializer3") )).bind("mcsssmallocinitializer1"), &HandlerForSSSMallocInitializer2); Matcher.addMatcher( callExpr(allOf( - hasAnyArgument( + hasAnyArgument(ignoringParenCasts( expr(anyOf( memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssfree2")))).bind("mcsssfree3"), + declRefExpr().bind("mcsssfree2"), hasDescendant(memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssfree2")))).bind("mcsssfree3")), hasDescendant(declRefExpr().bind("mcsssfree2")) - ))), + )))), argumentCountIs(1), hasAnyArgument(hasType(pointerType())) )).bind("mcsssfree1"), &HandlerForSSSFree2); @@ -4489,9 +4624,8 @@ public: Matcher.addMatcher(binaryOperator(allOf( hasOperatorName("="), hasLHS(anyOf( - memberExpr(expr(hasDescendant(declRefExpr().bind("mcssssettonull3")))).bind("mcssssettonull4"), - hasDescendant(memberExpr(expr(hasDescendant(declRefExpr().bind("mcssssettonull3")))).bind("mcssssettonull4")), - hasDescendant(declRefExpr().bind("mcssssettonull3")) + ignoringParenCasts(declRefExpr().bind("mcssssettonull3")), + ignoringParenCasts(expr(hasDescendant(declRefExpr().bind("mcssssettonull3")))) )), hasLHS(expr(hasType(pointerType()))) )).bind("mcssssettonull1"), &HandlerForSSSSetToNull2); @@ -4499,11 +4633,12 @@ public: Matcher.addMatcher( callExpr(allOf( hasAnyArgument( - expr(anyOf( - memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssmemset2")))).bind("mcsssmemset3"), + ignoringParenCasts(expr(anyOf( + memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssmemset2")))).bind("mcsssmemset3"), + declRefExpr().bind("mcsssmemset2"), hasDescendant(memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssmemset2")))).bind("mcsssmemset3")), hasDescendant(declRefExpr().bind("mcsssmemset2")) - ))), + )))), argumentCountIs(3), hasAnyArgument(hasType(pointerType())) )).bind("mcsssmemset1"), &HandlerForSSSMemset); @@ -4511,22 +4646,21 @@ public: Matcher.addMatcher( callExpr(allOf( hasAnyArgument( - expr(anyOf( - memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssmemcpy2")))).bind("mcsssmemcpy3"), + ignoringParenCasts(expr(anyOf( + memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssmemcpy2")))).bind("mcsssmemcpy3"), + declRefExpr().bind("mcsssmemcpy2"), hasDescendant(memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssmemcpy2")))).bind("mcsssmemcpy3")), hasDescendant(declRefExpr().bind("mcsssmemcpy2")) - ))), + )))), argumentCountIs(3), hasAnyArgument(hasType(pointerType())) )).bind("mcsssmemcpy1"), &HandlerForSSSMemcpy); Matcher.addMatcher(declStmt(hasDescendant( - varDecl(hasInitializer(ignoringImpCasts( + varDecl(hasInitializer(ignoringParenCasts( anyOf( conditionalOperator(has(declRefExpr())).bind("mcsssconditionalinitializer2"), - conditionalOperator(hasDescendant(declRefExpr())).bind("mcsssconditionalinitializer2"), - cStyleCastExpr(has(conditionalOperator(has(declRefExpr())).bind("mcsssconditionalinitializer2"))), - cStyleCastExpr(has(conditionalOperator(hasDescendant(declRefExpr())).bind("mcsssconditionalinitializer2"))) + conditionalOperator(hasDescendant(declRefExpr())).bind("mcsssconditionalinitializer2") ) ))).bind("mcsssconditionalinitializer3") )).bind("mcsssconditionalinitializer1"), &HandlerForSSSConditionalInitializer); -- cgit v1.2.3