aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--safercpp/safercpp-arr.cpp2804
1 files changed, 2015 insertions, 789 deletions
diff --git a/safercpp/safercpp-arr.cpp b/safercpp/safercpp-arr.cpp
index f647ed1..7142e70 100644
--- a/safercpp/safercpp-arr.cpp
+++ b/safercpp/safercpp-arr.cpp
@@ -294,12 +294,34 @@ public:
class CIndirectionState {
public:
- CIndirectionState(std::string original, std::string current, bool current_is_function_type = false)
- : m_original(original), m_current(current), m_current_is_function_type(current_is_function_type) {}
+ CIndirectionState(const std::string& original, const std::string& current,
+ bool current_is_function_type = false, const std::vector<std::string>& params = std::vector<std::string>())
+ : m_original(original), m_current(current), m_current_is_function_type(current_is_function_type),
+ m_params_original(params), m_params_current(params) {}
+ CIndirectionState(const std::string& original, const std::string& current,
+ const std::string& array_size_expr)
+ : m_original(original), m_current(current), m_original_array_size_expr(array_size_expr) {}
CIndirectionState(const CIndirectionState& src) = default;
+
+ bool current_is_function_type() const { return m_current_is_function_type; }
+ std::string current_params_string() const {
+ std::string retval;
+ if (1 <= m_params_current.size()) {
+ static const std::string comma_space_str = ", ";
+ for (auto& param_current : m_params_current) {
+ retval += param_current + comma_space_str;
+ }
+ retval = retval.substr(0, retval.size() - comma_space_str.size());
+ retval = "(" + retval + ")";
+ }
+ return retval;
+ }
+
std::string m_original;
std::string m_current;
+ std::string m_original_array_size_expr;
+
bool m_current_is_function_type = false;
std::vector<std::string> m_params_original;
std::vector<std::string> m_params_current;
@@ -312,19 +334,24 @@ class CIndirectionStateStack : public std::vector<CIndirectionState> {};
* can, of course, function as arrays, but context is required to identify those situations. Such identification
* is not done in this function. It is done elsewhere. */
clang::QualType populateQTypeIndirectionStack(CIndirectionStateStack& stack, clang::QualType qtype, int depth = 0) {
- bool current_is_function_type = false;
- std::vector<const clang::DeclaratorDecl*> current_function_params;
- if(qtype->isFunctionType()) {
- auto type_class = qtype->getTypeClass();
+ auto l_qtype = qtype;
+ bool is_function_type = false;
+ std::vector<std::string> param_strings;
+ if(l_qtype->isFunctionType()) {
+ auto type_class = l_qtype->getTypeClass();
if (clang::Type::Decayed == type_class) {
int q = 5;
} else if (clang::Type::FunctionNoProto == type_class) {
int q = 5;
} else if (clang::Type::FunctionProto == type_class) {
- if (llvm::isa<const clang::FunctionProtoType>(qtype)) {
- auto FNQT = llvm::cast<const clang::FunctionProtoType>(qtype);
+ if (llvm::isa<const clang::FunctionProtoType>(l_qtype)) {
+ auto FNQT = llvm::cast<const clang::FunctionProtoType>(l_qtype);
if (FNQT) {
auto num_params = FNQT->getNumParams();
+ auto param_types = FNQT->param_types();
+ for (auto& param_type : param_types) {
+ param_strings.push_back(param_type.getAsString());
+ }
} else {
assert(false);
}
@@ -334,52 +361,104 @@ clang::QualType populateQTypeIndirectionStack(CIndirectionStateStack& stack, cla
int q = 5;
}
- if (llvm::isa<const clang::FunctionType>(qtype)) {
- auto FNQT = llvm::cast<const clang::FunctionType>(qtype);
+ if (clang::Type::Paren == type_class) {
+ if (llvm::isa<const clang::ParenType>(l_qtype)) {
+ auto PNQT = llvm::cast<const clang::ParenType>(l_qtype);
+ if (PNQT) {
+ return populateQTypeIndirectionStack(stack, PNQT->getInnerType(), depth+1);
+ } else {
+ assert(false);
+ }
+ } else {
+ int q = 7;
+ }
+ } else if (llvm::isa<const clang::FunctionType>(l_qtype)) {
+ auto FNQT = llvm::cast<const clang::FunctionType>(l_qtype);
if (FNQT) {
- current_is_function_type = true;
- qtype = FNQT->getReturnType();
+ is_function_type = true;
+ l_qtype = FNQT->getReturnType();
} else {
assert(false);
}
- } else {
- int q = 5;
}
}
- std::string qtype_str = qtype.getAsString();
- auto TP = qtype.getTypePtr();
+ std::string l_qtype_str = l_qtype.getAsString();
+ auto TP = l_qtype.getTypePtr();
if (TP->isArrayType()) {
- auto type_class = qtype->getTypeClass();
+ auto type_class = l_qtype->getTypeClass();
if (clang::Type::Decayed == type_class) {
int q = 5;
} else if (clang::Type::ConstantArray == type_class) {
int q = 5;
}
+ std::string size_text;
+ if (llvm::isa<const clang::VariableArrayType>(TP)) {
+ auto VATP = llvm::cast<const clang::VariableArrayType>(TP);
+ if (!VATP) {
+ assert(false);
+ } else {
+ auto size_expr = VATP->getSizeExpr();
+ //auto SR = nice_source_range(size_expr->getSourceRange(), Rewrite);
+ //size_text = Rewrite.getRewrittenText(SR);
+ }
+ } else if (llvm::isa<const clang::ConstantArrayType>(TP)) {
+ auto CATP = llvm::cast<const clang::ConstantArrayType>(TP);
+ if (!CATP) {
+ assert(false);
+ } else {
+ auto array_size = CATP->getSize();
+ size_text = array_size.toString(10, false);/*check this*/
+
+ if (false) {
+ /*
+ auto DDSR = nice_source_range(DD->getSourceRange(), Rewrite);
+ std::string array_size_expression_text;
+ std::string source_text;
+ if (DDSR.isValid()) {
+ source_text = Rewrite.getRewrittenText(DDSR);
+
+ auto left_bracket_pos = source_text.find('[');
+ auto right_bracket_pos = source_text.find(']');
+ if ((std::string::npos != left_bracket_pos) && (std::string::npos != right_bracket_pos)
+ && (left_bracket_pos + 1 < right_bracket_pos)) {
+ auto array_size_expression_text = source_text.substr(left_bracket_pos + 1, right_bracket_pos - (left_bracket_pos + 1));
+ int q = 3;
+ } else {
+ int q = 7;
+ }
+ } else {
+ int q = 5;
+ }
+ */
+ }
+ }
+ }
+
const clang::ArrayType* ATP = TP->getAsArrayTypeUnsafe();
if (ATP) {
clang::QualType QT = ATP->getElementType();
- auto l_TP = QT.getTypePtr();
auto l_type_str = QT.getAsString();
- stack.push_back(CIndirectionState("native array", "native array"));
+ stack.push_back(CIndirectionState("native array", "native array", size_text));
return populateQTypeIndirectionStack(stack, QT, depth+1);
} else {
assert(false);
}
- } else if (qtype->isPointerType()) {
- auto type_class = qtype->getTypeClass();
+
+ } else if (l_qtype->isPointerType()) {
+ auto type_class = l_qtype->getTypeClass();
if (clang::Type::Decayed == type_class) {
int q = 5;
} else if (clang::Type::Pointer == type_class) {
int q = 5;
}
- if (llvm::isa<const clang::PointerType>(qtype)) {
- auto PQT = llvm::cast<const clang::PointerType>(qtype);
+ if (llvm::isa<const clang::PointerType>(l_qtype)) {
+ auto PQT = llvm::cast<const clang::PointerType>(l_qtype);
if (PQT) {
int q = 5;
} else {
@@ -389,14 +468,19 @@ clang::QualType populateQTypeIndirectionStack(CIndirectionStateStack& stack, cla
int q = 5;
}
- clang::QualType QT = qtype->getPointeeType();
+ clang::QualType QT = l_qtype->getPointeeType();
auto l_type_str = QT.getAsString();
- stack.push_back(CIndirectionState("native pointer", "native pointer"));
+ stack.push_back(CIndirectionState("native pointer", "native pointer", is_function_type, param_strings));
return populateQTypeIndirectionStack(stack, QT, depth+1);
}
- return qtype;
+
+ if (is_function_type) {
+ return qtype;
+ } else {
+ return l_qtype;
+ }
}
/* Given an expression (in the form of a clang::Stmt) and an (empty) (string) stack,
@@ -440,7 +524,7 @@ const clang::Expr* populateStmtIndirectionStack(std::vector<std::string>& stack,
auto cast_kind_name = ICE->getCastKindName();
auto cast_kind = ICE->getCastKind();
if ((clang::CK_FunctionToPointerDecay == cast_kind)) {
- process_child_flag = false;
+ process_child_flag = true;
} else {
if ((clang::CK_ArrayToPointerDecay == cast_kind) || (clang::CK_LValueToRValue == cast_kind)) {
process_child_flag = true;
@@ -456,7 +540,7 @@ const clang::Expr* populateStmtIndirectionStack(std::vector<std::string>& stack,
auto cast_kind = CSCE->getCastKind();
auto qtype = CSCE->getType();
if ((clang::CK_FunctionToPointerDecay == cast_kind)) {
- process_child_flag = false;
+ process_child_flag = true;
} else {
if ((clang::CK_ArrayToPointerDecay == cast_kind) || (clang::CK_LValueToRValue == cast_kind)) {
process_child_flag = true;
@@ -509,6 +593,29 @@ const clang::Expr* populateStmtIndirectionStack(std::vector<std::string>& stack,
return retval;
}
+const clang::Stmt* find_stmt(const clang::Stmt::StmtClass& target_stmt_class, const clang::Stmt& stmt, int depth = 0) {
+ const clang::Stmt* ST = &stmt;
+ const auto stmt_class = ST->getStmtClass();
+ const auto stmt_class_name = ST->getStmtClassName();
+ if (stmt_class == target_stmt_class) {
+ return ST;
+ }
+ bool process_children_flag = true;
+ if (process_children_flag) {
+ for (auto child_iter = ST->child_begin(); child_iter != ST->child_end(); child_iter++) {
+ if (nullptr != (*child_iter)) {
+ auto res1 = find_stmt(target_stmt_class, *(*child_iter), depth+1);
+ if (res1) {
+ return res1;
+ }
+ } else {
+ assert(false);
+ }
+ }
+ }
+ return nullptr;
+}
+
void walkTheAST1(const clang::Stmt& stmt, int depth = 0) {
const clang::Stmt* ST = &stmt;
auto stmt_class = ST->getStmtClass();
@@ -599,9 +706,18 @@ public:
m_is_a_function = true;
}
m_original_direct_qtype = populateQTypeIndirectionStack(m_indirection_state_stack, QT);
- m_current_direct_qtype = m_original_direct_qtype;
+ set_current_direct_qtype(m_original_direct_qtype);
//std::reverse(m_indirection_state_stack.begin(), m_indirection_state_stack.end());
}
+ void set_current_direct_qtype(clang::QualType& new_direct_qtype) {
+ m_current_direct_qtype = new_direct_qtype;
+ m_current_direct_qtype_is_current = true;
+ m_current_direct_qtype_str = m_current_direct_qtype.getAsString();
+ }
+ void set_current_direct_qtype_str(const std::string& str) {
+ m_current_direct_qtype_is_current = false;
+ m_current_direct_qtype_str = str;
+ }
bool is_an_indirect_type(size_t indirection_level = 0) const { return (m_indirection_state_stack.size() > indirection_level); }
bool has_been_determined_to_be_an_array(size_t indirection_level = 0) const {
bool retval = false;
@@ -628,7 +744,10 @@ public:
const DeclaratorDecl* m_ddecl_cptr = nullptr;
CIndirectionStateStack m_indirection_state_stack;
clang::QualType m_original_direct_qtype;
+ bool m_current_direct_qtype_is_current = false;
clang::QualType m_current_direct_qtype;
+ std::string m_current_direct_qtype_str;
+
std::string m_initializer_info_str;
bool m_original_initialization_has_been_noted = false;
std::string m_original_initialization_expr_str;
@@ -661,7 +780,7 @@ bool is_an_indirect_type(const clang::DeclaratorDecl& ddecl) {
bool is_an_indirect_type(const QualType& QT, size_t indirection_level = 0) {
CIndirectionStateStack m_indirection_state_stack;
- auto m_current_direct_qtype = populateQTypeIndirectionStack(m_indirection_state_stack, QT);
+ auto direct_qtype = populateQTypeIndirectionStack(m_indirection_state_stack, QT);
return (indirection_level < m_indirection_state_stack.size());
}
@@ -767,6 +886,13 @@ public:
Rewriter &Rewrite;
};
+template<class X, class... Args>
+std::shared_ptr<X> make_expr_conversion_state_shared_ptr(Args&&... args) {
+ std::shared_ptr<X> retval = std::make_shared<X>(std::forward<Args>(args)...);
+ retval->set_childrens_parent_shptr(retval);
+ return retval;
+}
+
class CConditionalOperatorExprConversionState : public CExprConversionState {
public:
CConditionalOperatorExprConversionState(const clang::ConditionalOperator& co_cref, Rewriter &Rewrite) : CExprConversionState(co_cref, Rewrite) {
@@ -868,13 +994,6 @@ private:
const clang::ArraySubscriptExpr* m_arraysubscriptexpr_cptr = nullptr;
};
-template<class X, class... Args>
-std::shared_ptr<X> make_expr_conversion_state_shared_ptr(Args&&... args) {
- std::shared_ptr<X> retval = std::make_shared<X>(std::forward<Args>(args)...);
- retval->set_childrens_parent_shptr(retval);
- return retval;
-}
-
class CExprConversionStateMap : public std::map<const clang::Expr*, std::shared_ptr<CExprConversionState>> {
public:
typedef std::map<const clang::Expr*, std::shared_ptr<CExprConversionState>> base_class;
@@ -938,6 +1057,37 @@ public:
CDDeclIndirection m_ddecl_indirection;
};
+class CExprTextReplacementAction : public CDDecl2ReplacementAction {
+public:
+ CExprTextReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
+ const Expr* EX, const std::string& replacement_code) :
+ CDDecl2ReplacementAction(Rewrite, MR, ddecl_indirection), m_EX(EX), m_replacement_code(replacement_code) {}
+ virtual ~CExprTextReplacementAction() {}
+
+ virtual void do_replacement(CState1& state1) const;
+ /*
+ {
+ Rewriter &Rewrite = m_Rewrite;
+ const MatchFinder::MatchResult &MR = m_MR;
+ const Expr* EX = m_EX;
+
+ if (EX != nullptr)
+ {
+ auto EXSR = nice_source_range(EX->getSourceRange(), Rewrite);
+
+ if (ConvertToSCPP && (EXSR.isValid())) {
+ auto res2 = Rewrite.ReplaceText(EXSR, m_replacement_code);
+ } else {
+ int q = 7;
+ }
+ }
+ }
+ */
+
+ const Expr* m_EX = nullptr;
+ std::string m_replacement_code;
+};
+
class CArray2ReplacementAction : public CDDecl2ReplacementAction {
public:
using CDDecl2ReplacementAction::CDDecl2ReplacementAction;
@@ -1027,6 +1177,19 @@ public:
const clang::ArraySubscriptExpr* m_arraysubscriptexpr_cptr = nullptr;
};
+class CUpdateIndirectFunctionTypeParamsArray2ReplacementAction : public CArray2ReplacementAction {
+public:
+ CUpdateIndirectFunctionTypeParamsArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
+ const DeclaratorDecl& indirect_function_ddecl, const clang::CallExpr& call_expr) :
+ CArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_indirect_function_DD(&indirect_function_ddecl), m_CE(&call_expr) {}
+ virtual ~CUpdateIndirectFunctionTypeParamsArray2ReplacementAction() {}
+
+ virtual void do_replacement(CState1& state1) const;
+
+ const clang::DeclaratorDecl *m_indirect_function_DD = nullptr;
+ const clang::CallExpr* m_CE = nullptr;
+};
+
class CDDecl2ReplacementActionMap : public std::multimap<CDDeclIndirection, std::shared_ptr<CDDecl2ReplacementAction>> {
public:
typedef std::multimap<CDDeclIndirection, std::shared_ptr<CDDecl2ReplacementAction>> base_class;
@@ -1074,13 +1237,13 @@ public:
std::string m_bo_replacement_code;
};
-class CMallocInitializerArray2ReplacementAction : public CDynamicArray2ReplacementAction {
+class CInitializerArray2ReplacementAction : public CDynamicArray2ReplacementAction {
public:
- CMallocInitializerArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
+ CInitializerArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
const DeclStmt* DS, const std::string& initializer_info_str) :
CDynamicArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_DS(DS), m_DD(ddecl_indirection.m_ddecl_cptr),
m_initializer_info_str(initializer_info_str) {}
- virtual ~CMallocInitializerArray2ReplacementAction() {}
+ virtual ~CInitializerArray2ReplacementAction() {}
virtual void do_replacement(CState1& state1) const;
@@ -1107,21 +1270,16 @@ public:
std::string m_ce_replacement_code;
};
-class CSetArrayPointerToNull2ReplacementAction : public CDynamicArray2ReplacementAction {
+class CAssignmentTargetConstrainsSourceDynamicArray2ReplacementAction : public CDynamicArray2ReplacementAction {
public:
- CSetArrayPointerToNull2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
- const BinaryOperator* BO, const std::string& bo_replacement_code) :
- CDynamicArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_BO(BO), m_DD(ddecl_indirection.m_ddecl_cptr),
- m_bo_replacement_code(bo_replacement_code) {}
- virtual ~CSetArrayPointerToNull2ReplacementAction() {}
+ CAssignmentTargetConstrainsSourceDynamicArray2ReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const CDDeclIndirection& ddecl_indirection,
+ const CDDeclIndirection& ddecl_indirection2) :
+ CDynamicArray2ReplacementAction(Rewrite, MR, ddecl_indirection), m_ddecl_indirection2(ddecl_indirection2) {}
+ virtual ~CAssignmentTargetConstrainsSourceDynamicArray2ReplacementAction() {}
virtual void do_replacement(CState1& state1) const;
- const BinaryOperator* m_BO = nullptr;
- //const DeclRefExpr* m_DRE = nullptr;
- //const MemberExpr* m_ME = nullptr;
- const DeclaratorDecl* m_DD = nullptr;
- std::string m_bo_replacement_code;
+ const CDDeclIndirection m_ddecl_indirection2;
};
/* This class represents and "enforces" the constraint that the lhs and rhs
@@ -1150,9 +1308,11 @@ public:
class CArray2ReplacementActionMap : public CDDecl2ReplacementActionMap {
public:
+ /*
iterator insert( const std::shared_ptr<CArray2ReplacementAction>& cr_shptr ) {
return CDDecl2ReplacementActionMap::insert(static_cast<std::shared_ptr<CDDecl2ReplacementAction> >(cr_shptr));
}
+ */
};
class CState1 {
@@ -1174,6 +1334,133 @@ public:
CExprConversionStateMap m_expr_conversion_state_map;
};
+class CTypeIndirectionPrefixAndSuffixItem {
+public:
+ std::string m_prefix_str;
+ std::string m_suffix_str;
+ std::string m_action_species;
+ bool m_direct_type_must_be_non_const = false;
+};
+
+static CTypeIndirectionPrefixAndSuffixItem generate_type_indirection_prefix_and_suffix(CIndirectionStateStack& indirection_state_stack,
+ bool direct_type_is_char_type, bool direct_type_is_function_type, bool is_a_function_parameter) {
+ CTypeIndirectionPrefixAndSuffixItem retval;
+
+ bool changed_from_original = false;
+ std::string replacement_code;
+ std::string prefix_str;
+ std::string suffix_str;
+
+ if (true) {
+ for (size_t i = 0; i < indirection_state_stack.size(); i += 1) {
+ bool is_char_star = false;
+ bool is_function_pointer = false;
+ bool is_last_indirection = (indirection_state_stack.size() == (i+1));
+ if (is_last_indirection && (direct_type_is_char_type)) {
+ is_char_star = true;
+ } else if (is_last_indirection && direct_type_is_function_type) {
+ is_function_pointer = true;
+ } else if ((!is_last_indirection) && indirection_state_stack[i+1].current_is_function_type()) {
+ is_function_pointer = true;
+ }
+
+ if (indirection_state_stack[i].current_is_function_type()) {
+ //suffix_str = indirection_state_stack[i].current_params_string() + suffix_str;
+ }
+
+ if ("inferred array" == indirection_state_stack[i].m_current) {
+ if (is_char_star) {
+ /* We're assuming this is a null terminated string. We'll just leave it as a
+ * char* for now. At some point we'll replace it with an mse::string or whatever. */
+ //prefix_str = prefix_str + "";
+ suffix_str = "* " + suffix_str;
+ retval.m_action_species = "char*";
+ } else {
+ if (is_last_indirection) {
+ //retval.m_direct_type_must_be_non_const = true;
+ }
+ prefix_str = prefix_str + "mse::TNullableAnyRandomAccessIterator<";
+ suffix_str = "> " + suffix_str;
+ retval.m_action_species = "native pointer to TNullableAnyRandomAccessIterator";
+ }
+ } else if ("dynamic array" == indirection_state_stack[i].m_current) {
+ if (is_char_star) {
+ /* We're assuming this is a null terminated string. We'll just leave it as a
+ * char* for now. At some point we'll replace it with an mse::string or whatever. */
+ //prefix_str = prefix_str + "";
+ suffix_str = "* " + suffix_str;
+ retval.m_action_species = "char*";
+ } else {
+ if (is_last_indirection) {
+ retval.m_direct_type_must_be_non_const = true;
+ }
+ prefix_str = prefix_str + "mse::lh::TIPointerWithBundledVector<";
+ if (is_a_function_parameter) {
+ suffix_str = "> " + suffix_str;
+ retval.m_action_species = "native pointer parameter to TIPointerWithBundledVector";
+ } else {
+ suffix_str = "> " + suffix_str;
+ retval.m_action_species = "native pointer to TIPointerWithBundledVector";
+ }
+ }
+ } else if ("native array" == indirection_state_stack[i].m_current) {
+ std::string size_text = indirection_state_stack[i].m_original_array_size_expr;
+
+ if (is_char_star) {
+ /* We're assuming this is a null terminated string. We'll just leave it as a
+ * char[] for now. At some point we'll replace it with an mse::string or whatever. */
+ //prefix_str = prefix_str + "";
+ suffix_str = "[" + size_text + "]" + suffix_str;
+ } else {
+ if (is_a_function_parameter) {
+ prefix_str = prefix_str + "mse::TNullableAnyRandomAccessIterator<";
+ suffix_str = ", " + size_text + "> " + suffix_str;
+ retval.m_action_species = "native array parameter to TNullableAnyRandomAccessIterator";
+ } else {
+ if (is_last_indirection) {
+ retval.m_direct_type_must_be_non_const = true;
+ }
+ prefix_str = prefix_str + "mse::lh::TNativeArrayReplacement<";
+ suffix_str = ", " + size_text + "> " + suffix_str;
+ retval.m_action_species = "native array to TNativeArrayReplacement";
+ }
+ }
+ } else if ("native pointer" == indirection_state_stack[i].m_current) {
+ if (is_char_star) {
+ /* We're assuming this is a null terminated string. We'll just leave it as a
+ * char* for now. At some point we'll replace it with an mse::string or whatever. */
+ //prefix_str = prefix_str + "";
+ suffix_str = "* " + suffix_str;
+ retval.m_action_species = "char*";
+ } else if (is_function_pointer) {
+ prefix_str = prefix_str + "std::function<";
+ suffix_str = "> " + suffix_str;
+ retval.m_action_species = "function pointer to std::function";
+ } else {
+ if (false/*for now*/) {
+ prefix_str = prefix_str + "mse::TAnyPointer<";
+ suffix_str = "> " + suffix_str;
+ retval.m_action_species = "native pointer to TAnyPointer";
+ } else {
+ //prefix_str = prefix_str + "";
+ suffix_str = "* " + suffix_str;
+ retval.m_action_species = "native pointer";
+ }
+ }
+ } else if ("malloc target" == indirection_state_stack[i].m_current) {
+ /* We'll just leaving it as a native pointer for now. Ultimately, this won't be the case. */
+ //prefix_str = prefix_str + "";
+ suffix_str = "* " + suffix_str;
+ retval.m_action_species = "malloc target";
+ }
+ }
+ }
+ retval.m_prefix_str = prefix_str;
+ retval.m_suffix_str = suffix_str;
+
+ return retval;
+}
+
class CDeclarationReplacementCodeItem {
public:
std::string m_replacement_code;
@@ -1209,28 +1496,6 @@ static CDeclarationReplacementCodeItem generate_declaration_replacement_code(con
}
}
- const clang::Type* TP = QT.getTypePtr();
- auto qtype_str = QT.getAsString();
- auto direct_qtype_str = ddcs_ref.m_current_direct_qtype.getAsString();
- if ("_Bool" == direct_qtype_str) {
- direct_qtype_str = "bool";
- } else if ("const _Bool" == direct_qtype_str) {
- direct_qtype_str = "const bool";
- }
-
- auto non_const_direct_qtype = ddcs_ref.m_current_direct_qtype;
- non_const_direct_qtype.removeLocalConst();
- auto non_const_direct_qtype_str = non_const_direct_qtype.getAsString();
- if ("_Bool" == non_const_direct_qtype_str) {
- non_const_direct_qtype_str = "bool";
- }
-
- auto direct_TP = ddcs_ref.m_current_direct_qtype.getTypePtr();
- if (!direct_TP) {
- return retval;
- }
- bool direct_type_is_function_type = direct_TP->isFunctionType();
-
std::string variable_name = DD->getNameAsString();
std::string identifier_name_str;
auto pIdentifier = DD->getIdentifier();
@@ -1239,27 +1504,10 @@ static CDeclarationReplacementCodeItem generate_declaration_replacement_code(con
}
if ("" == variable_name) {
int q = 7;
- } else if ("LODEPNG_VERSION_STRING" == variable_name) {
+ } else if ("bitlen_ll" == variable_name) {
int q = 5;
}
- if (!(ddcs_ref.m_original_source_text_has_been_noted)) {
- ddcs_ref.m_original_source_text_str = Rewrite.getRewrittenText(decl_source_range);
- if (FND) {
- assert(type_is_function_type);
- ddcs_ref.m_is_a_function = true;
- for (size_t i = 0; i < FND->getNumParams(); i+=1) {
- ddcs_ref.m_original_function_parameter_decl_cptrs.push_back(FND->getParamDecl(i));
- }
- auto return_type_source_range = nice_source_range(FND->getReturnTypeSourceRange(), Rewrite);
- if (!(return_type_source_range.isValid())) {
- return retval;
- }
- ddcs_ref.m_function_return_type_original_source_text_str = Rewrite.getRewrittenText(return_type_source_range);
- }
- ddcs_ref.m_original_source_text_has_been_noted = true;
- }
-
clang::StorageClass storage_class = clang::StorageClass::SC_None;
bool is_extern = false;
clang::StorageDuration storage_duration = clang::StorageDuration::SD_Automatic;
@@ -1352,141 +1600,68 @@ static CDeclarationReplacementCodeItem generate_declaration_replacement_code(con
}
ddcs_ref.m_original_initialization_has_been_noted = true;
+ const clang::Type* TP = QT.getTypePtr();
+ auto qtype_str = QT.getAsString();
+ auto direct_qtype_str = ddcs_ref.m_current_direct_qtype_str;
+ if ("_Bool" == direct_qtype_str) {
+ direct_qtype_str = "bool";
+ } else if ("const _Bool" == direct_qtype_str) {
+ direct_qtype_str = "const bool";
+ }
+
+ auto non_const_direct_qtype_str = ddcs_ref.m_current_direct_qtype_str;
+ if (ddcs_ref.m_current_direct_qtype_is_current) {
+ auto non_const_direct_qtype = ddcs_ref.m_current_direct_qtype;
+ non_const_direct_qtype.removeLocalConst();
+ non_const_direct_qtype_str = non_const_direct_qtype.getAsString();
+ } else {
+ static const std::string const_space_str = "const ";
+ if (string_begins_with(non_const_direct_qtype_str, const_space_str)) {
+ non_const_direct_qtype_str = non_const_direct_qtype_str.substr(const_space_str.size());
+ }
+ }
+ if ("_Bool" == non_const_direct_qtype_str) {
+ non_const_direct_qtype_str = "bool";
+ }
+
+ auto direct_TP = ddcs_ref.m_current_direct_qtype.getTypePtr();
+ if (!direct_TP) {
+ return retval;
+ }
+ bool direct_type_is_function_type = direct_TP->isFunctionType();
+
+ if (!(ddcs_ref.m_original_source_text_has_been_noted)) {
+ ddcs_ref.m_original_source_text_str = Rewrite.getRewrittenText(decl_source_range);
+ if (FND) {
+ assert(type_is_function_type);
+ ddcs_ref.m_is_a_function = true;
+ for (size_t i = 0; i < FND->getNumParams(); i+=1) {
+ ddcs_ref.m_original_function_parameter_decl_cptrs.push_back(FND->getParamDecl(i));
+ }
+ auto return_type_source_range = nice_source_range(FND->getReturnTypeSourceRange(), Rewrite);
+ if (!(return_type_source_range.isValid())) {
+ return retval;
+ }
+ ddcs_ref.m_function_return_type_original_source_text_str = Rewrite.getRewrittenText(return_type_source_range);
+ }
+ ddcs_ref.m_original_source_text_has_been_noted = true;
+ }
+
+ bool direct_type_is_char_type = (("char" == direct_qtype_str) || ("const char" == direct_qtype_str));
bool changed_from_original = false;
std::string replacement_code;
std::string prefix_str;
std::string suffix_str;
- if (true) {
- for (size_t i = 0; i < ddcs_ref.m_indirection_state_stack.size(); i += 1) {
- bool is_char_star = false;
- bool is_function_pointer = false;
- bool is_last_indirection = (ddcs_ref.m_indirection_state_stack.size() == (i+1));
- if (is_last_indirection && (("char" == direct_qtype_str) || ("const char" == direct_qtype_str))) {
- is_char_star = true;
- } else if (is_last_indirection && direct_type_is_function_type) {
- is_function_pointer = true;
- }
- if ("inferred array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- if (is_char_star) {
- /* We're assuming this is a null terminated string. We'll just leave it as a
- * char* for now. At some point we'll replace it with an mse::string or whatever. */
- //prefix_str = prefix_str + "";
- suffix_str = "* " + suffix_str;
- retval.m_action_species = "char*";
- } else {
- direct_qtype_str = non_const_direct_qtype_str;
- prefix_str = prefix_str + "mse::TNullableAnyRandomAccessIterator<";
- suffix_str = "> " + suffix_str;
- retval.m_action_species = "native pointer to TNullableAnyRandomAccessIterator";
- }
- } else if ("dynamic array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- direct_qtype_str = non_const_direct_qtype_str;
- if (is_char_star) {
- /* We're assuming this is a null terminated string. We'll just leave it as a
- * char* for now. At some point we'll replace it with an mse::string or whatever. */
- //prefix_str = prefix_str + "";
- suffix_str = "* " + suffix_str;
- retval.m_action_species = "char*";
- } else {
- prefix_str = prefix_str + "mse::TIPointerWithBundledVector<";
- if (is_a_function_parameter) {
- suffix_str = "> " + suffix_str;
- retval.m_action_species = "native pointer parameter to TIPointerWithBundledVector";
- } else {
- suffix_str = "> " + suffix_str;
- retval.m_action_species = "native pointer to TIPointerWithBundledVector";
- }
- }
- } else if ("native array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- direct_qtype_str = non_const_direct_qtype_str;
- std::string size_text;
- if (TP->isVariableArrayType()) {
- auto VATP = llvm::cast<const clang::VariableArrayType>(TP);
- if (!VATP) {
- assert(false);
- } else {
- auto size_expr = VATP->getSizeExpr();
- auto SR = nice_source_range(size_expr->getSourceRange(), Rewrite);
- size_text = Rewrite.getRewrittenText(SR);
- }
- } else if (TP->isConstantArrayType()) {
- auto CATP = llvm::cast<const clang::ConstantArrayType>(TP);
- if (!CATP) {
- assert(false);
- } else {
- auto array_size = CATP->getSize();
- size_text = array_size.toString(10, false);/*check this*/
-
- if (false) {
- auto DDSR = nice_source_range(DD->getSourceRange(), Rewrite);
- std::string array_size_expression_text;
- std::string source_text;
- if (DDSR.isValid()) {
- source_text = Rewrite.getRewrittenText(DDSR);
-
- auto left_bracket_pos = source_text.find('[');
- auto right_bracket_pos = source_text.find(']');
- if ((std::string::npos != left_bracket_pos) && (std::string::npos != right_bracket_pos)
- && (left_bracket_pos + 1 < right_bracket_pos)) {
- auto array_size_expression_text = source_text.substr(left_bracket_pos + 1, right_bracket_pos - (left_bracket_pos + 1));
- int q = 3;
- } else {
- int q = 7;
- }
- } else {
- int q = 5;
- }
- }
- }
- }
+ auto res4 = generate_type_indirection_prefix_and_suffix(ddcs_ref.m_indirection_state_stack,
+ direct_type_is_char_type, direct_type_is_function_type, is_a_function_parameter);
+ retval.m_action_species = res4.m_action_species;
- if (is_char_star) {
- /* We're assuming this is a null terminated string. We'll just leave it as a
- * char[] for now. At some point we'll replace it with an mse::string or whatever. */
- //prefix_str = prefix_str + "";
- suffix_str = "[" + size_text + "]" + suffix_str;
- } else {
- if (is_a_function_parameter) {
- prefix_str = prefix_str + "mse::TNullableAnyRandomAccessIterator<";
- suffix_str = ", " + size_text + "> " + suffix_str;
- retval.m_action_species = "native array parameter to TNullableAnyRandomAccessIterator";
- } else {
- prefix_str = prefix_str + "mse::TIteratorWithBundledArray<";
- suffix_str = ", " + size_text + "> " + suffix_str;
- retval.m_action_species = "native array to TIteratorWithBundledArray";
- }
- }
- } else if ("native pointer" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- if (is_char_star) {
- /* We're assuming this is a null terminated string. We'll just leave it as a
- * char* for now. At some point we'll replace it with an mse::string or whatever. */
- //prefix_str = prefix_str + "";
- suffix_str = "* " + suffix_str;
- retval.m_action_species = "char*";
- } else if (is_function_pointer) {
- prefix_str = prefix_str + "std::function<";
- suffix_str = "> " + suffix_str;
- retval.m_action_species = "function pointer to std::function";
- } else {
- if (false/*for now*/) {
- prefix_str = prefix_str + "mse::TAnyPointer<";
- suffix_str = "> " + suffix_str;
- retval.m_action_species = "native pointer to TAnyPointer";
- } else {
- //prefix_str = prefix_str + "";
- suffix_str = "* " + suffix_str;
- retval.m_action_species = "native pointer";
- }
- }
- } else if ("malloc target" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- /* We'll just leaving it as a native pointer for now. Ultimately, this won't be the case. */
- //prefix_str = prefix_str + "";
- suffix_str = "* " + suffix_str;
- retval.m_action_species = "malloc target";
- }
- }
+ if (res4.m_direct_type_must_be_non_const) {
+ direct_qtype_str = non_const_direct_qtype_str;
}
+ prefix_str = res4.m_prefix_str;
+ suffix_str = res4.m_suffix_str;
bool discard_initializer_option_flag = (std::string::npos != options_str.find("[discard-initializer]"));
std::string initializer_append_str;
@@ -1512,7 +1687,7 @@ static CDeclarationReplacementCodeItem generate_declaration_replacement_code(con
if (FND) {
assert(type_is_function_type);
if (changed_from_original) {
- replacement_code += prefix_str + non_const_direct_qtype_str + suffix_str;
+ replacement_code += prefix_str + direct_qtype_str + suffix_str;
} else {
replacement_code = ddcs_ref.m_function_return_type_original_source_text_str;
}
@@ -1567,6 +1742,10 @@ static void update_declaration(const DeclaratorDecl& ddecl, Rewriter &Rewrite, C
if ((TP->isFunctionType()) || (false)) {
const clang::FunctionDecl* FND = dynamic_cast<const clang::FunctionDecl*>(DD);
if (FND) {
+ auto name_str = FND->getNameAsString();
+ if (std::string::npos != name_str.find("lodepng_chunk_data_const")) {
+ int q = 5;
+ }
auto return_type_source_range = nice_source_range(FND->getReturnTypeSourceRange(), Rewrite);
if (!(return_type_source_range.isValid())) {
return;
@@ -1626,6 +1805,248 @@ static void update_declaration(const DeclaratorDecl& ddecl, Rewriter &Rewrite, C
}
}
+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;
+ const clang::Stmt* ST = &stmt_cref;
+ auto stmt_class = ST->getStmtClass();
+ auto stmt_class_name = ST->getStmtClassName();
+ bool process_child_flag = false;
+ if (clang::Stmt::StmtClass::UnaryOperatorClass == stmt_class) {
+ auto UO = llvm::cast<const clang::UnaryOperator>(ST);
+ 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()) && (llvm::isa<const clang::Expr>(*child_iter))) {
+ retval.without_leading_addressof_operator_expr_cptr =
+ llvm::cast<const clang::Expr>(*child_iter);
+ } else {
+ assert(false);
+ }
+ }
+ } else {
+ assert(false);
+ }
+ } else if ((clang::Stmt::StmtClass::ImplicitCastExprClass == stmt_class)) {
+ auto ICE = llvm::cast<const clang::ImplicitCastExpr>(ST);
+ if (ICE) {
+ auto cast_kind_name = ICE->getCastKindName();
+ auto cast_kind = ICE->getCastKind();
+ if ((clang::CK_FunctionToPointerDecay == cast_kind)) {
+ process_child_flag = false;
+ } else {
+ if ((clang::CK_ArrayToPointerDecay == cast_kind) || (clang::CK_LValueToRValue == cast_kind)) {
+ process_child_flag = true;
+ } else {
+ process_child_flag = true;
+ }
+ }
+ } else { assert(false); }
+ } else if ((clang::Stmt::StmtClass::CStyleCastExprClass == stmt_class)) {
+ auto CSCE = llvm::cast<const clang::CStyleCastExpr>(ST);
+ if (CSCE) {
+ auto cast_kind_name = CSCE->getCastKindName();
+ auto cast_kind = CSCE->getCastKind();
+ auto qtype = CSCE->getType();
+ if ((clang::CK_FunctionToPointerDecay == cast_kind)) {
+ process_child_flag = false;
+ } else {
+ if ((clang::CK_ArrayToPointerDecay == cast_kind) || (clang::CK_LValueToRValue == cast_kind)) {
+ process_child_flag = true;
+ } else {
+ process_child_flag = true;
+ }
+ }
+ } else { assert(false); }
+ } else if ((clang::Stmt::StmtClass::ParenExprClass == stmt_class)) {
+ process_child_flag = true;
+ } else if ((clang::Stmt::StmtClass::CallExprClass == stmt_class)) {
+ process_child_flag = true;
+ } else if(clang::Stmt::StmtClass::DeclRefExprClass == stmt_class) {
+ auto DRE = llvm::cast<const clang::DeclRefExpr>(ST);
+ if (DRE) {
+ //retval = DRE;
+ //process_child_flag = true;
+ } else {
+ assert(false);
+ }
+ } else if(clang::Stmt::StmtClass::MemberExprClass == stmt_class) {
+ auto ME = llvm::cast<const clang::MemberExpr>(ST);
+ if (ME) {
+ //retval = ME;
+ } else {
+ assert(false);
+ }
+ } else {
+ if (0 == depth) {
+ int q = 5;
+ }
+ int q = 5;
+ }
+ if (process_child_flag) {
+ auto child_iter = ST->child_begin();
+ if (child_iter != ST->child_end()) {
+ if (nullptr != (*child_iter)) {
+ retval = leading_addressof_operator_info_from_stmt(*(*child_iter), depth+1);
+ } else {
+ assert(false);
+ }
+ } else {
+ int q = 5;
+ }
+ }
+ return retval;
+}
+
+struct CArrayInferenceInfo {
+ bool is_an_indirect_type() const {
+ if (nullptr != ddecl_conversion_state_ptr) {
+ return (1 <= ddecl_conversion_state_ptr->m_indirection_state_stack.size());
+ } else {
+ return false;
+ }
+ }
+ bool update_declaration_flag = false;
+ bool has_just_been_determined_to_be_an_array_flag = false;
+ size_t has_just_been_determined_to_be_an_array_indirection_level = 0;
+ size_t indirection_level = 0;
+ const DeclaratorDecl* ddecl_cptr = nullptr;
+ CDDeclConversionState* ddecl_conversion_state_ptr = nullptr;
+ const clang::Expr* declaration_expr_cptr = nullptr;
+};
+CArrayInferenceInfo infer_array_type_info_from_stmt_indirection_stack(CDDeclConversionState& ddcs_ref,
+ const std::vector<std::string>& stmt_indirection_stack, CState1& state1_ref) {
+ CArrayInferenceInfo retval;
+ auto DD = ddcs_ref.m_ddecl_cptr;
+ if (!DD) { assert(false); return retval; }
+ for (size_t i = 0; ((i < ddcs_ref.m_indirection_state_stack.size())
+ && (i < stmt_indirection_stack.size())); i += 1) {
+ if (("" == stmt_indirection_stack[i])) {
+ /* We're using the empty string as a generic state for the "terminal level of indirection"
+ * when we don't want to bother specifying a specific state. */
+ retval.indirection_level = i;
+ } else if ("native pointer" == ddcs_ref.m_indirection_state_stack[i].m_current) {
+ if (("ArraySubscriptExpr" == stmt_indirection_stack[i])
+ || ("pointer arithmetic" == stmt_indirection_stack[i])) {
+ ddcs_ref.m_indirection_state_stack[i].m_current = "inferred array";
+ retval.update_declaration_flag = true;
+ state1_ref.m_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1_ref, CDDeclIndirection(*DD, i));
+ } else if (("malloc target" == stmt_indirection_stack[i])) {
+ ddcs_ref.m_indirection_state_stack[i].m_current = "malloc target";
+ retval.indirection_level = i;
+ } else if (("set to null" == stmt_indirection_stack[i]) ||
+ ("memset/cpy target" == stmt_indirection_stack[i])) {
+ retval.indirection_level = i;
+ }
+ } else if ("malloc target" == ddcs_ref.m_indirection_state_stack[i].m_current) {
+ if (("ArraySubscriptExpr" == stmt_indirection_stack[i])
+ || ("pointer arithmetic" == stmt_indirection_stack[i])) {
+ ddcs_ref.m_indirection_state_stack[i].m_current = "dynamic array";
+ retval.update_declaration_flag = true;
+ state1_ref.m_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1_ref, CDDeclIndirection(*DD, i));
+ state1_ref.m_dynamic_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1_ref, CDDeclIndirection(*DD, i));
+ }
+ } else if ("inferred array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
+ if (("malloc target" == stmt_indirection_stack[i]) ||
+ ("set to null" == stmt_indirection_stack[i])) {
+ ddcs_ref.m_indirection_state_stack[i].m_current = "dynamic array";
+ retval.update_declaration_flag = true;
+ retval.has_just_been_determined_to_be_an_array_flag = true;
+ retval.indirection_level = i;
+ state1_ref.m_dynamic_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1_ref, CDDeclIndirection(*DD, i));
+ } else if (("memset/cpy target" == stmt_indirection_stack[i])) {
+ retval.has_just_been_determined_to_be_an_array_flag = true;
+ retval.indirection_level = i;
+ }
+ } else if ("dynamic array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
+ if (("malloc target" == stmt_indirection_stack[i]) ||
+ ("set to null" == stmt_indirection_stack[i])) {
+ retval.has_just_been_determined_to_be_an_array_flag = true;
+ retval.indirection_level = i;
+ }
+ }
+ /* We've changed it here so that retval.indirection_level will always end up being
+ * (stmt_indirection_stack.size() - 1) when (1 <= stmt_indirection_stack.size()). This
+ * renders the above "retval.indirection_level = i;" statements redundant, but we'll
+ * leave them there for now in case we need them again. */
+ retval.indirection_level = i;
+ }
+ return retval;
+}
+
+/* We are trying to determine, for each and every pointer, whether or not it is being used as an
+ * array iterator. So this function takes an expression using a declared (pointer) variable
+ * and notes when the (pointer) variable, or any dereference of the
+ * (pointer) variable, is being used as an array iterator. So for example, given a declaration,
+ * say, "int*** ptr1;" and an expression, say, "(*(ptr1[3]))[5]", it will note the two levels
+ * of dereference/"indirection" that are being used as array iterators/pointers. Upon determining
+ * that a pointer (or a dereference/indirection of the pointer) is being used as an array iterator,
+ * the function will execute any queued up actions that were contingent on such a determination. */
+CArrayInferenceInfo infer_array_type_info_from_stmt(const clang::Stmt& stmt_cref, const std::string& stmt_array_info_str,
+ CState1& state1_ref, const DeclaratorDecl* DD = nullptr) {
+ CArrayInferenceInfo retval;
+
+ std::vector<std::string> stmt_indirection_stack;
+ const clang::Expr* expr2 = populateStmtIndirectionStack(stmt_indirection_stack, stmt_cref);
+ std::reverse(stmt_indirection_stack.begin(), stmt_indirection_stack.end());
+ stmt_indirection_stack.push_back(stmt_array_info_str);
+ if (expr2) {
+ const DeclaratorDecl* l_DD = DD;
+ std::string expr2_stmt_class_name;
+ expr2_stmt_class_name = expr2->getStmtClassName();
+ const DeclaratorDecl* expr2_DD = nullptr;
+ if (clang::Stmt::StmtClass::DeclRefExprClass == expr2->getStmtClass()) {
+ auto expr2_DRE = llvm::cast<const clang::DeclRefExpr>(expr2);
+ if (expr2_DRE) {
+ auto expr2_decl = expr2_DRE->getDecl();
+ expr2_DD = dynamic_cast<const DeclaratorDecl*>(expr2_decl);
+ } else { assert(false); }
+ } else if (clang::Stmt::StmtClass::MemberExprClass == expr2->getStmtClass()) {
+ auto expr2_ME = llvm::cast<const clang::MemberExpr>(expr2);
+ if (expr2_ME) {
+ auto expr2_FD = dynamic_cast<const clang::FieldDecl*>(expr2_ME->getMemberDecl());
+ if (expr2_FD) {
+ expr2_DD = expr2_FD;
+ } else { assert(false); }
+ } else { assert(false); }
+ }
+ if (expr2_DD) {
+ auto expr2_QT = expr2_DD->getType();
+ auto expr2_type_str = expr2_QT.getAsString();
+ std::string expr2_variable_name = expr2_DD->getNameAsString();
+
+ if (nullptr == l_DD) {
+ l_DD = expr2_DD;
+ }
+ auto res1 = state1_ref.m_ddecl_conversion_state_map.insert(*l_DD);
+ auto ddcs_map_iter = res1.first;
+ auto& ddcs_ref = (*ddcs_map_iter).second;
+ bool update_declaration_flag = res1.second;
+
+ auto QT = (*l_DD).getType();
+ std::string variable_name = (*l_DD).getNameAsString();
+
+ if ((expr2_QT == QT) && (expr2_variable_name == variable_name)) {
+ retval = infer_array_type_info_from_stmt_indirection_stack(ddcs_ref, stmt_indirection_stack, state1_ref);
+ }
+
+ retval.update_declaration_flag |= update_declaration_flag;
+ retval.ddecl_conversion_state_ptr = &ddcs_ref;
+ }
+ retval.ddecl_cptr = expr2_DD;
+ }
+ retval.declaration_expr_cptr = expr2;
+
+ return retval;
+}
+
void CMallocArray2ReplacementAction::do_replacement(CState1& state1) const {
Rewriter &Rewrite = m_Rewrite;
const MatchFinder::MatchResult &MR = m_MR;
@@ -1644,6 +2065,31 @@ void CMallocArray2ReplacementAction::do_replacement(CState1& state1) const {
return;
}
+ if (ddecl_indirection_cref().m_ddecl_cptr) {
+ auto res1 = state1.m_ddecl_conversion_state_map.insert(*(ddecl_indirection_cref().m_ddecl_cptr));
+ auto ddcs_map_iter = res1.first;
+ auto& ddcs_ref = (*ddcs_map_iter).second;
+ bool update_declaration_flag = res1.second;
+
+ if (ddcs_ref.m_indirection_state_stack.size() >= ddecl_indirection_cref().m_indirection_level) {
+ if ("inferred array" == ddcs_ref.m_indirection_state_stack[ddecl_indirection_cref().m_indirection_level].m_current) {
+ ddcs_ref.m_indirection_state_stack[ddecl_indirection_cref().m_indirection_level].m_current = "dynamic array";
+ update_declaration_flag |= true;
+ state1.m_dynamic_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1, ddecl_indirection_cref());
+ } else {
+ int q = 5;
+ }
+ } else {
+ int q = 7;
+ }
+
+ if (update_declaration_flag) {
+ //update_declaration(*(ddecl_indirection_cref().m_ddecl_cptr), Rewrite, state1);
+ }
+ } else {
+ int q = 7;
+ }
+
if (ConvertToSCPP && decl_source_range.isValid() && (BOSR.isValid())) {
update_declaration(*DD, Rewrite, state1);
@@ -1659,7 +2105,7 @@ void CMallocArray2ReplacementAction::do_replacement(CState1& state1) const {
}
}
-void CMallocInitializerArray2ReplacementAction::do_replacement(CState1& state1) const {
+void CInitializerArray2ReplacementAction::do_replacement(CState1& state1) const {
Rewriter &Rewrite = m_Rewrite;
const MatchFinder::MatchResult &MR = m_MR;
const DeclStmt* DS = m_DS;
@@ -1680,7 +2126,7 @@ void CMallocInitializerArray2ReplacementAction::do_replacement(CState1& state1)
auto ddcs_map_iter = res1.first;
auto& ddcs_ref = (*ddcs_map_iter).second;
- std::string current_direct_qtype_str = ddcs_ref.m_current_direct_qtype.getAsString();
+ std::string current_direct_qtype_str = ddcs_ref.m_current_direct_qtype_str;
std::string initializer_info_str = m_initializer_info_str;
static const std::string void_str = "void";
auto void_pos = initializer_info_str.find(void_str);
@@ -1736,33 +2182,28 @@ void CFreeDynamicArray2ReplacementAction::do_replacement(CState1& state1) const
}
}
-void CSetArrayPointerToNull2ReplacementAction::do_replacement(CState1& state1) const {
+void CAssignmentTargetConstrainsSourceDynamicArray2ReplacementAction::do_replacement(CState1& state1) const {
Rewriter &Rewrite = m_Rewrite;
const MatchFinder::MatchResult &MR = m_MR;
- const BinaryOperator* BO = m_BO;
- const DeclaratorDecl* DD = m_DD;
-
- if ((BO != nullptr) && (DD != nullptr))
- {
- auto BOSR = nice_source_range(BO->getSourceRange(), Rewrite);
- 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;
- }
-
- if (ConvertToSCPP && decl_source_range.isValid() && (BOSR.isValid())) {
- update_declaration(*DD, Rewrite, state1);
+ auto res1 = state1.m_ddecl_conversion_state_map.insert(*(m_ddecl_indirection2.m_ddecl_cptr));
+ auto ddcs_map_iter = res1.first;
+ auto& ddcs_ref = (*ddcs_map_iter).second;
+ bool update_declaration_flag = res1.second;
- auto res2 = Rewrite.ReplaceText(BOSR, m_bo_replacement_code);
- int q = 3;
- } else {
- int q = 7;
+ if (ddcs_ref.m_indirection_state_stack.size() >= m_ddecl_indirection2.m_indirection_level) {
+ if (true) {
+ ddcs_ref.m_indirection_state_stack[m_ddecl_indirection2.m_indirection_level].m_current = "dynamic array";
+ update_declaration_flag |= true;
+ //state1.m_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1, m_ddecl_indirection2);
+ state1.m_dynamic_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1, m_ddecl_indirection2);
}
+ } else {
+ int q = 7;
+ }
+
+ if (update_declaration_flag) {
+ update_declaration(*(m_ddecl_indirection2.m_ddecl_cptr), Rewrite, state1);
}
}
@@ -2024,6 +2465,32 @@ void CSameTypeArray2ReplacementAction::do_replacement(CState1& state1) const {
}
}
+void CExprTextReplacementAction::do_replacement(CState1& state1) const {
+ Rewriter &Rewrite = m_Rewrite;
+ const MatchFinder::MatchResult &MR = m_MR;
+
+ const Expr* EX = m_EX;
+ if (EX) {
+ auto EXSR = nice_source_range(EX->getSourceRange(), (*this).m_Rewrite);
+ if (EXSR.isValid()) {
+ auto excs_iter = state1.m_expr_conversion_state_map.find(EX);
+ if (state1.m_expr_conversion_state_map.end() == excs_iter) {
+ std::shared_ptr<CExprConversionState> shptr1 = make_expr_conversion_state_shared_ptr<CExprConversionState>(*EX, m_Rewrite);
+ excs_iter = state1.m_expr_conversion_state_map.insert(shptr1);
+ }
+ auto& excs_shptr_ref = (*excs_iter).second;
+
+ if (ConvertToSCPP) {
+ std::shared_ptr<CExprTextModifier> shptr1 = std::make_shared<CStraightReplacementExprTextModifier>((*this).m_replacement_code);
+ (*excs_shptr_ref).m_expr_text_modifier_stack.push_back(shptr1);
+ (*excs_shptr_ref).update_current_text();
+
+ (*this).m_Rewrite.ReplaceText(EXSR, (*excs_shptr_ref).m_current_text_str);
+ }
+ }
+ }
+}
+
void CAssignmentTargetConstrainsAddressofArraySubscriptExprArray2ReplacementAction::do_replacement(CState1& state1) const {
Rewriter &Rewrite = m_Rewrite;
const MatchFinder::MatchResult &MR = m_MR;
@@ -2065,6 +2532,86 @@ void CAssignmentTargetConstrainsAddressofArraySubscriptExprArray2ReplacementActi
}
}
+void CUpdateIndirectFunctionTypeParamsArray2ReplacementAction::do_replacement(CState1& state1) const {
+ Rewriter &Rewrite = m_Rewrite;
+ const MatchFinder::MatchResult &MR = m_MR;
+
+ const clang::CallExpr* CE = m_CE;
+ if (CE) {
+ auto res1 = state1.m_ddecl_conversion_state_map.insert(*((*this).m_indirect_function_DD));
+ auto ddcs_map_iter = res1.first;
+ auto& ddcs_ref = (*ddcs_map_iter).second;
+ ddcs_ref.m_current_direct_qtype;
+
+ if (llvm::isa<const clang::FunctionType>(ddcs_ref.m_current_direct_qtype)) {
+ auto FNQT = llvm::cast<const clang::FunctionType>(ddcs_ref.m_current_direct_qtype);
+ std::string new_function_type_code = FNQT->getReturnType().getAsString();
+ new_function_type_code += "(";
+
+ for (size_t i = 0; (i < CE->getNumArgs()); i += 1) {
+ if (1 <= i) {
+ new_function_type_code += ", ";
+ }
+
+ auto arg = CE->getArg(i);
+ auto rhs_res2 = infer_array_type_info_from_stmt(*arg, "", state1);
+ bool rhs_is_an_indirect_type = is_an_indirect_type(arg->getType());
+ if (rhs_res2.ddecl_cptr && rhs_res2.update_declaration_flag) {
+ update_declaration(*(rhs_res2.ddecl_cptr), Rewrite, state1);
+ }
+
+ if (rhs_res2.ddecl_cptr && rhs_res2.ddecl_conversion_state_ptr) {
+ CIndirectionStateStack indirection_state_stack;
+ for (size_t i = rhs_res2.indirection_level; (*(rhs_res2.ddecl_conversion_state_ptr)).m_indirection_state_stack.size() > i; i += 1) {
+ indirection_state_stack.push_back((*(rhs_res2.ddecl_conversion_state_ptr)).m_indirection_state_stack[i]);
+ }
+ auto rhs_direct_qtype = (*(rhs_res2.ddecl_conversion_state_ptr)).m_current_direct_qtype;
+
+ bool rhs_direct_type_is_function_type = rhs_direct_qtype->isFunctionType();
+ bool rhs_is_a_function_parameter = true;
+
+ std::string rhs_direct_qtype_str = rhs_direct_qtype.getAsString();
+ if ("_Bool" == rhs_direct_qtype_str) {
+ rhs_direct_qtype_str = "bool";
+ } else if ("const _Bool" == rhs_direct_qtype_str) {
+ rhs_direct_qtype_str = "const bool";
+ }
+ bool rhs_direct_type_is_char_type = (("char" == rhs_direct_qtype_str) || ("const char" == rhs_direct_qtype_str));
+ auto rhs_non_const_direct_qtype = rhs_direct_qtype;
+ rhs_non_const_direct_qtype.removeLocalConst();
+ std::string rhs_non_const_direct_qtype_str = rhs_non_const_direct_qtype.getAsString();
+ if ("_Bool" == rhs_non_const_direct_qtype_str) {
+ rhs_non_const_direct_qtype_str = "bool";
+ }
+
+ auto res3 = generate_type_indirection_prefix_and_suffix(indirection_state_stack, rhs_direct_type_is_char_type,
+ rhs_direct_type_is_function_type, rhs_is_a_function_parameter);
+
+ if (res3.m_direct_type_must_be_non_const) {
+ rhs_direct_qtype_str = rhs_non_const_direct_qtype_str;
+ }
+
+ std::string new_param_type_str = res3.m_prefix_str + rhs_direct_qtype_str + res3.m_suffix_str;
+
+ new_function_type_code += new_param_type_str;
+ } else {
+ new_function_type_code += arg->getType().getAsString();
+ int q = 7;
+ }
+ }
+ new_function_type_code += ")";
+
+ ddcs_ref.set_current_direct_qtype_str(new_function_type_code);
+
+ update_declaration(*((*this).m_indirect_function_DD), (*this).m_Rewrite, state1);
+ } else {
+ int q = 7;
+ }
+ } else {
+ int q = 7;
+ }
+}
+
void CConditionalOperatorReconciliation2ReplacementAction::do_replacement(CState1& state1) const {
const clang::ConditionalOperator* CO = m_CO;
const Expr* COND = nullptr;
@@ -2225,242 +2772,6 @@ 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;
- const clang::Stmt* ST = &stmt_cref;
- auto stmt_class = ST->getStmtClass();
- auto stmt_class_name = ST->getStmtClassName();
- bool process_child_flag = false;
- if (clang::Stmt::StmtClass::UnaryOperatorClass == stmt_class) {
- auto UO = llvm::cast<const clang::UnaryOperator>(ST);
- 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()) {
- retval.without_leading_addressof_operator_expr_cptr =
- llvm::cast<const clang::Expr>(*child_iter);
- } else {
- assert(false);
- }
- }
- } else {
- assert(false);
- }
- } else if ((clang::Stmt::StmtClass::ImplicitCastExprClass == stmt_class)) {
- auto ICE = llvm::cast<const clang::ImplicitCastExpr>(ST);
- if (ICE) {
- auto cast_kind_name = ICE->getCastKindName();
- auto cast_kind = ICE->getCastKind();
- if ((clang::CK_FunctionToPointerDecay == cast_kind)) {
- process_child_flag = false;
- } else {
- if ((clang::CK_ArrayToPointerDecay == cast_kind) || (clang::CK_LValueToRValue == cast_kind)) {
- process_child_flag = true;
- } else {
- process_child_flag = true;
- }
- }
- } else { assert(false); }
- } else if ((clang::Stmt::StmtClass::CStyleCastExprClass == stmt_class)) {
- auto CSCE = llvm::cast<const clang::CStyleCastExpr>(ST);
- if (CSCE) {
- auto cast_kind_name = CSCE->getCastKindName();
- auto cast_kind = CSCE->getCastKind();
- auto qtype = CSCE->getType();
- if ((clang::CK_FunctionToPointerDecay == cast_kind)) {
- process_child_flag = false;
- } else {
- if ((clang::CK_ArrayToPointerDecay == cast_kind) || (clang::CK_LValueToRValue == cast_kind)) {
- process_child_flag = true;
- } else {
- process_child_flag = true;
- }
- }
- } else { assert(false); }
- } else if ((clang::Stmt::StmtClass::ParenExprClass == stmt_class)) {
- process_child_flag = true;
- } else if ((clang::Stmt::StmtClass::CallExprClass == stmt_class)) {
- process_child_flag = true;
- } else if(clang::Stmt::StmtClass::DeclRefExprClass == stmt_class) {
- auto DRE = llvm::cast<const clang::DeclRefExpr>(ST);
- if (DRE) {
- //retval = DRE;
- //process_child_flag = true;
- } else {
- assert(false);
- }
- } else if(clang::Stmt::StmtClass::MemberExprClass == stmt_class) {
- auto ME = llvm::cast<const clang::MemberExpr>(ST);
- if (ME) {
- //retval = ME;
- } else {
- assert(false);
- }
- } else {
- if (0 == depth) {
- int q = 5;
- }
- int q = 5;
- }
- if (process_child_flag) {
- auto child_iter = ST->child_begin();
- if (child_iter != ST->child_end()) {
- if (nullptr != (*child_iter)) {
- retval = leading_addressof_operator_info_from_stmt(*(*child_iter), depth+1);
- } else {
- assert(false);
- }
- } else {
- int q = 5;
- }
- }
- return retval;
-}
-
-struct CArrayInferenceInfo {
- bool is_an_indirect_type() const {
- if (nullptr != ddecl_conversion_state_ptr) {
- return (1 <= ddecl_conversion_state_ptr->m_indirection_state_stack.size());
- } else {
- return false;
- }
- }
- bool update_declaration_flag = false;
- bool has_just_been_determined_to_be_an_array = false;
- size_t indirection_level = 0;
- const DeclaratorDecl* ddecl_cptr = nullptr;
- CDDeclConversionState* ddecl_conversion_state_ptr = nullptr;
- const clang::Expr* declaration_expr_cptr = nullptr;
-};
-CArrayInferenceInfo infer_array_type_info_from_stmt_indirection_stack(CDDeclConversionState& ddcs_ref,
- const std::vector<std::string>& stmt_indirection_stack, CState1& state1_ref) {
- CArrayInferenceInfo retval;
- auto DD = ddcs_ref.m_ddecl_cptr;
- if (!DD) { assert(false); return retval; }
- for (size_t i = 0; ((i < ddcs_ref.m_indirection_state_stack.size())
- && (i < stmt_indirection_stack.size())); i += 1) {
- if (("" == stmt_indirection_stack[i])) {
- /* We're using the empty string as a generic state for the "terminal level of indirection"
- * when we don't want to bother specifying a specific state. */
- retval.indirection_level = i;
- } else if ("native pointer" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- if (("ArraySubscriptExpr" == stmt_indirection_stack[i])
- || ("pointer arithmetic" == stmt_indirection_stack[i])) {
- ddcs_ref.m_indirection_state_stack[i].m_current = "inferred array";
- retval.update_declaration_flag = true;
- state1_ref.m_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1_ref, CDDeclIndirection(*DD, i));
- } else if (("malloc target" == stmt_indirection_stack[i])) {
- ddcs_ref.m_indirection_state_stack[i].m_current = "malloc target";
- retval.indirection_level = i;
- } else if (("set to null" == stmt_indirection_stack[i]) ||
- ("memset/cpy target" == stmt_indirection_stack[i])) {
- retval.indirection_level = i;
- }
- } else if ("malloc target" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- if (("ArraySubscriptExpr" == stmt_indirection_stack[i])
- || ("pointer arithmetic" == stmt_indirection_stack[i])) {
- ddcs_ref.m_indirection_state_stack[i].m_current = "dynamic array";
- retval.update_declaration_flag = true;
- state1_ref.m_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1_ref, CDDeclIndirection(*DD, i));
- state1_ref.m_dynamic_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1_ref, CDDeclIndirection(*DD, i));
- }
- } else if ("inferred array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- if (("malloc target" == stmt_indirection_stack[i]) ||
- ("set to null" == stmt_indirection_stack[i])) {
- ddcs_ref.m_indirection_state_stack[i].m_current = "dynamic array";
- retval.update_declaration_flag = true;
- retval.has_just_been_determined_to_be_an_array = true;
- retval.indirection_level = i;
- state1_ref.m_dynamic_array2_contingent_replacement_map.do_and_dispose_matching_replacements(state1_ref, CDDeclIndirection(*DD, i));
- } else if (("memset/cpy target" == stmt_indirection_stack[i])) {
- retval.has_just_been_determined_to_be_an_array = true;
- retval.indirection_level = i;
- }
- } else if ("dynamic array" == ddcs_ref.m_indirection_state_stack[i].m_current) {
- if (("malloc target" == stmt_indirection_stack[i]) ||
- ("set to null" == stmt_indirection_stack[i])) {
- retval.has_just_been_determined_to_be_an_array = true;
- retval.indirection_level = i;
- }
- }
- }
- return retval;
-}
-
-/* We are trying to determine, for each and every pointer, whether or not it is being used as an
- * array iterator. So this function takes an expression using a declared (pointer) variable
- * and notes when the (pointer) variable, or any dereference of the
- * (pointer) variable, is being used as an array iterator. So for example, given a declaration,
- * say, "int*** ptr1;" and an expression, say, "(*(ptr1[3]))[5]", it will note the two levels
- * of dereference/"indirection" that are being used as array iterators/pointers. Upon determining
- * that a pointer (or a dereference/indirection of the pointer) is being used as an array iterator,
- * the function will execute any queued up actions that were contingent on such a determination. */
-CArrayInferenceInfo infer_array_type_info_from_stmt(const clang::Stmt& stmt_cref, const std::string& stmt_array_info_str,
- CState1& state1_ref, const DeclaratorDecl* DD = nullptr) {
- CArrayInferenceInfo retval;
-
- std::vector<std::string> stmt_indirection_stack;
- const clang::Expr* expr2 = populateStmtIndirectionStack(stmt_indirection_stack, stmt_cref);
- std::reverse(stmt_indirection_stack.begin(), stmt_indirection_stack.end());
- stmt_indirection_stack.push_back(stmt_array_info_str);
- if (expr2) {
- const DeclaratorDecl* l_DD = DD;
- std::string expr2_stmt_class_name;
- expr2_stmt_class_name = expr2->getStmtClassName();
- const DeclaratorDecl* expr2_DD = nullptr;
- if (clang::Stmt::StmtClass::DeclRefExprClass == expr2->getStmtClass()) {
- auto expr2_DRE = llvm::cast<const clang::DeclRefExpr>(expr2);
- if (expr2_DRE) {
- auto expr2_decl = expr2_DRE->getDecl();
- expr2_DD = dynamic_cast<const DeclaratorDecl*>(expr2_decl);
- } else { assert(false); }
- } else if (clang::Stmt::StmtClass::MemberExprClass == expr2->getStmtClass()) {
- auto expr2_ME = llvm::cast<const clang::MemberExpr>(expr2);
- if (expr2_ME) {
- auto expr2_FD = dynamic_cast<const clang::FieldDecl*>(expr2_ME->getMemberDecl());
- if (expr2_FD) {
- expr2_DD = expr2_FD;
- } else { assert(false); }
- } else { assert(false); }
- }
- if (expr2_DD) {
- auto expr2_QT = expr2_DD->getType();
- auto expr2_type_str = expr2_QT.getAsString();
- std::string expr2_variable_name = expr2_DD->getNameAsString();
-
- if (nullptr == l_DD) {
- l_DD = expr2_DD;
- }
- auto res1 = state1_ref.m_ddecl_conversion_state_map.insert(*l_DD);
- auto ddcs_map_iter = res1.first;
- auto& ddcs_ref = (*ddcs_map_iter).second;
- bool update_declaration_flag = res1.second;
-
- auto QT = (*l_DD).getType();
- std::string variable_name = (*l_DD).getNameAsString();
-
- if ((expr2_QT == QT) && (expr2_variable_name == variable_name)) {
- retval = infer_array_type_info_from_stmt_indirection_stack(ddcs_ref, stmt_indirection_stack, state1_ref);
- }
-
- retval.update_declaration_flag |= update_declaration_flag;
- retval.ddecl_conversion_state_ptr = &ddcs_ref;
- }
- retval.ddecl_cptr = expr2_DD;
- }
- retval.declaration_expr_cptr = expr2;
-
- return retval;
-}
-
/**********************************************************************************************************************/
class MCSSSArrayToPointerDecay : public MatchFinder::MatchCallback
{
@@ -2733,6 +3044,98 @@ private:
/**********************************************************************************************************************/
+struct CAllocFunctionInfo {
+ bool m_seems_to_be_some_kind_of_malloc_or_realloc = false;
+ clang::CallExpr::const_arg_iterator m_num_bytes_arg_iter;
+ std::string m_num_bytes_arg_source_text;
+};
+CAllocFunctionInfo analyze_malloc_resemblance(const clang::CallExpr& call_expr, Rewriter &Rewrite) {
+ CAllocFunctionInfo retval;
+
+ auto CE = &call_expr;
+ auto function_decl = CE->getDirectCallee();
+ auto num_args = CE->getNumArgs();
+ if (function_decl && ((1 == num_args) || (2 == num_args))) {
+ std::string function_name = function_decl->getNameAsString();
+ static const std::string alloc_str = "alloc";
+ static const std::string realloc_str = "realloc";
+ auto lc_function_name = tolowerstr(function_name);
+ bool ends_with_alloc = ((lc_function_name.size() >= alloc_str.size())
+ && (0 == lc_function_name.compare(lc_function_name.size() - alloc_str.size(), alloc_str.size(), alloc_str)));
+ bool ends_with_realloc = (ends_with_alloc && (lc_function_name.size() >= realloc_str.size())
+ && (0 == lc_function_name.compare(lc_function_name.size() - realloc_str.size(), realloc_str.size(), realloc_str)));
+ bool still_potentially_valid1 = (ends_with_alloc && (1 == num_args)) || (ends_with_realloc && (2 == num_args));
+ if (still_potentially_valid1) {
+ auto arg_iter = CE->arg_begin();
+ if (ends_with_realloc) {
+ arg_iter++;
+ }
+ bool argIsIntegerType = false;
+ if (*arg_iter) {
+ argIsIntegerType = (*arg_iter)->getType().split().asPair().first->isIntegerType();
+ }
+ if (argIsIntegerType) {
+ 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);
+
+ bool asterisk_found = false;
+ auto sizeof_start_index = arg_source_text.find("sizeof(");
+ if (std::string::npos != sizeof_start_index) {
+ auto sizeof_end_index = arg_source_text.find(")", sizeof_start_index);
+ if (std::string::npos != sizeof_end_index) {
+ assert(sizeof_end_index > sizeof_start_index);
+ std::string before_str = arg_source_text.substr(0, sizeof_start_index);
+ std::string after_str;
+ if (sizeof_end_index + 1 < arg_source_text.size()) {
+ after_str = arg_source_text.substr(sizeof_end_index + 1);
+ }
+
+ auto index = before_str.size() - 1;
+ while (0 <= index) {
+ if ('*' == before_str[index]) {
+ asterisk_found = true;
+ }
+ if (!std::isspace(before_str[index])) {
+ break;
+ }
+
+ index -= 1;
+ }
+ if (asterisk_found) {
+ before_str = before_str.substr(0, index);
+ } else {
+ size_t index2 = 0;
+ while (after_str.size() > index2) {
+ if ('*' == after_str[index2]) {
+ asterisk_found = true;
+ }
+ if (!std::isspace(after_str[index2])) {
+ break;
+ }
+
+ index2 += 1;
+ }
+ if (asterisk_found) {
+ after_str = after_str.substr(index2 + 1);
+ }
+ }
+ }
+ }
+ if (true || asterisk_found) {
+ retval.m_num_bytes_arg_iter = arg_iter;
+ retval.m_seems_to_be_some_kind_of_malloc_or_realloc = true;
+ retval.m_num_bytes_arg_source_text = arg_source_text;
+ }
+ }
+ }
+ }
+ }
+ return retval;
+}
+
class MCSSSMalloc2 : public MatchFinder::MatchCallback
{
public:
@@ -2773,6 +3176,175 @@ public:
return void();
}
+ if (std::string::npos != source_location_str.find("130")) {
+ int q = 5;
+ }
+
+ auto alloc_function_info1 = analyze_malloc_resemblance(*CE, Rewrite);
+ if (alloc_function_info1.m_seems_to_be_some_kind_of_malloc_or_realloc) {
+ /* The argument is in the form "something * sizeof(something_else)" or
+ * "sizeof(something) * something_else". So we're just going to assume that
+ * this is an instance of an array being allocated. */
+ std::string num_elements_text/* = before_str + after_str*/;
+ 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 lhs_QT = LHS->getType();
+
+ auto decl = DRE->getDecl();
+ DD = dynamic_cast<const DeclaratorDecl*>(decl);
+ auto VD = dynamic_cast<const VarDecl*>(decl);
+
+ const clang::FieldDecl* FD = nullptr;
+ if (nullptr != ME) {
+ auto member_decl = ME->getMemberDecl();
+ FD = dynamic_cast<const clang::FieldDecl*>(ME->getMemberDecl());
+ }
+ if (nullptr != FD) {
+ DD = FD;
+ } else if (nullptr != VD) {
+ DD = VD;
+ } else {
+ int q = 7;
+ }
+
+ 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 res2 = infer_array_type_info_from_stmt(*LHS, "malloc target", (*this).m_state1, DD);
+
+ if (res2.update_declaration_flag) {
+ update_declaration(*DD, Rewrite, m_state1);
+ }
+
+ const clang::Type* lhs_TP = lhs_QT.getTypePtr();
+ auto lhs_type_str = lhs_QT.getAsString();
+
+ std::string lhs_element_type_str;
+ if (llvm::isa<const clang::ArrayType>(lhs_TP)) {
+ auto ATP = llvm::cast<const clang::ArrayType>(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;
+ }
+ } else if (llvm::isa<const clang::PointerType>(lhs_TP)) {
+ auto TPP = llvm::cast<const clang::PointerType>(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;
+ }
+ }
+ if ("" != lhs_element_type_str) {
+ num_elements_text = "(";
+ num_elements_text += alloc_function_info1.m_num_bytes_arg_source_text;
+ num_elements_text += ") / sizeof(";
+ num_elements_text += lhs_element_type_str;
+ num_elements_text += ")";
+
+ 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(";
+ bo_replacement_code += num_elements_text;
+ bo_replacement_code += ")";
+
+ 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;
+ }
+
+ auto BOSR = clang::SourceRange(BOSL, BOSLE);
+ if (ConvertToSCPP && decl_source_range.isValid() && (BOSR.isValid())
+ && (nullptr != res2.ddecl_conversion_state_ptr)) {
+ auto cr_shptr = std::make_shared<CMallocArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*DD, res2.indirection_level), BO, bo_replacement_code);
+
+ 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_array2_contingent_replacement_map.insert(cr_shptr);
+ //m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
+ }
+ } else {
+ int q = 7;
+ }
+ }
+ }
+ }
+ }
+ }
+
+private:
+ Rewriter &Rewrite;
+ CState1& m_state1;
+};
+
+class MCSSSMallocInitializer2 : public MatchFinder::MatchCallback
+{
+public:
+ MCSSSMallocInitializer2 (Rewriter &Rewrite, CState1& state1) :
+ Rewrite(Rewrite), m_state1(state1) {}
+
+ virtual void run(const MatchFinder::MatchResult &MR)
+ {
+ const DeclStmt* DS = MR.Nodes.getNodeAs<clang::DeclStmt>("mcsssmallocinitializer1");
+ const CallExpr* CE = MR.Nodes.getNodeAs<clang::CallExpr>("mcsssmallocinitializer2");
+ const DeclaratorDecl* DD = MR.Nodes.getNodeAs<clang::DeclaratorDecl>("mcsssmallocinitializer3");
+
+ if ((DS != nullptr) && (CE != nullptr) && (DD != nullptr))
+ {
+ auto DSSR = nice_source_range(DS->getSourceRange(), Rewrite);
+ SourceLocation DSSL = DSSR.getBegin();
+ SourceLocation DSSLE = DSSR.getEnd();
+
+ ASTContext *const ASTC = MR.Context;
+ FullSourceLoc FDSSL = ASTC->getFullLoc(DSSL);
+
+ SourceManager &SM = ASTC->getSourceManager();
+
+ auto source_location_str = DSSL.printToString(*MR.SourceManager);
+ std::string source_text;
+ if (DSSL.isValid() && DSSLE.isValid()) {
+ source_text = Rewrite.getRewrittenText(SourceRange(DSSL, DSSLE));
+ } else {
+ return;
+ }
+
+ if (filtered_out_by_location(MR, DSSL)) {
+ 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))) {
@@ -2790,11 +3362,7 @@ public:
if (ends_with_realloc) {
iter++;
}
- bool argIsIntegerType = false;
- if (*iter) {
- argIsIntegerType = (*iter)->getType().split().asPair().first->isIntegerType();
- }
- if (argIsIntegerType) {
+ {
auto arg_source_range = nice_source_range((*iter)->getSourceRange(), Rewrite);
std::string arg_source_text;
if (arg_source_range.isValid()) {
@@ -2849,31 +3417,6 @@ public:
* "sizeof(something) * something_else". So we're just going to assume that
* this is an instance of an array being allocated. */
std::string num_elements_text/* = before_str + after_str*/;
- 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 lhs_QT = LHS->getType();
-
- auto decl = DRE->getDecl();
- DD = dynamic_cast<const DeclaratorDecl*>(decl);
- auto VD = dynamic_cast<const VarDecl*>(decl);
-
- const clang::FieldDecl* FD = nullptr;
- if (nullptr != ME) {
- auto member_decl = ME->getMemberDecl();
- FD = dynamic_cast<const clang::FieldDecl*>(ME->getMemberDecl());
- }
- if (nullptr != FD) {
- DD = FD;
- } else if (nullptr != VD) {
- DD = VD;
- } else {
- int q = 7;
- }
if (nullptr != DD) {
auto decl_source_range = nice_source_range(DD->getSourceRange(), Rewrite);
@@ -2884,8 +3427,8 @@ public:
} else {
return;
}
- QT = DD->getType();
- variable_name = DD->getNameAsString();
+ QualType QT = DD->getType();
+ auto variable_name = DD->getNameAsString();
auto qualified_name = DD->getQualifiedNameAsString();
static const std::string mse_namespace_str1 = "mse::";
@@ -2895,46 +3438,62 @@ public:
return;
}
- auto res2 = infer_array_type_info_from_stmt(*LHS, "malloc target", (*this).m_state1, DD);
+ if (!is_an_indirect_type(DD->getType())) {
+ return;
+ }
+
+ auto res1 = (*this).m_state1.m_ddecl_conversion_state_map.insert(*DD);
+ auto ddcs_map_iter = res1.first;
+ auto& ddcs_ref = (*ddcs_map_iter).second;
+ bool update_declaration_flag = res1.second;
- if (res2.update_declaration_flag) {
- update_declaration(*DD, Rewrite, m_state1);
+ bool lhs_has_been_determined_to_be_an_array = false;
+ if ("native pointer" == ddcs_ref.m_indirection_state_stack[0].m_current) {
+ ddcs_ref.m_indirection_state_stack[0].m_current = "malloc target";
+ } else if ("inferred array" == ddcs_ref.m_indirection_state_stack[0].m_current) {
+ ddcs_ref.m_indirection_state_stack[0].m_current = "dynamic array";
+ lhs_has_been_determined_to_be_an_array = true;
+ //update_declaration_flag = true;
+ m_state1.m_dynamic_array2_contingent_replacement_map.do_and_dispose_matching_replacements(m_state1, CDDeclIndirection(*DD, 0));
+ } else if ("dynamic array" == ddcs_ref.m_indirection_state_stack[0].m_current) {
+ lhs_has_been_determined_to_be_an_array = true;
+ } else {
+ assert("native array" != ddcs_ref.m_indirection_state_stack[0].m_current);
}
- const clang::Type* lhs_TP = lhs_QT.getTypePtr();
- auto lhs_type_str = lhs_QT.getAsString();
+ const clang::Type* TP = QT.getTypePtr();
+ auto lhs_type_str = QT.getAsString();
- std::string lhs_element_type_str;
- if (lhs_TP->isArrayType()) {
- auto ATP = llvm::cast<const clang::ArrayType>(lhs_TP);
+ std::string element_type_str;
+ if (TP->isArrayType()) {
+ auto ATP = llvm::cast<const clang::ArrayType>(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;
+ element_type_str = type_str;
}
- } else if (lhs_TP->isPointerType()) {
- auto TPP = llvm::cast<const clang::PointerType>(lhs_TP);
+ } else if (TP->isPointerType()) {
+ auto TPP = llvm::cast<const clang::PointerType>(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;
+ element_type_str = type_str;
}
}
- if ("" != lhs_element_type_str) {
+ if ("" != element_type_str) {
num_elements_text = "(";
num_elements_text += arg_source_text;
- num_elements_text += ") / sizeof(";
- num_elements_text += lhs_element_type_str;
+ if (true || (("void" != element_type_str) && ("const void" != element_type_str))) {
+ num_elements_text += ") / sizeof(";
+ num_elements_text += element_type_str;
+ } else {
+ /* todo: something */
+ }
num_elements_text += ")";
- 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(";
- bo_replacement_code += num_elements_text;
- bo_replacement_code += ")";
+ std::string initializer_info_str = "(" + num_elements_text + ")";
auto decl_source_location_str = decl_source_range.getBegin().printToString(*MR.SourceManager);
std::string decl_source_text;
@@ -2944,16 +3503,17 @@ public:
return;
}
- auto BOSR = clang::SourceRange(BOSL, BOSLE);
- if (ConvertToSCPP && decl_source_range.isValid() && (BOSR.isValid())
- && (nullptr != res2.ddecl_conversion_state_ptr)) {
- auto cr_shptr = std::make_shared<CMallocArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*DD, res2.indirection_level), BO, bo_replacement_code);
+ auto DSSR = clang::SourceRange(DSSL, DSSLE);
+ if (ConvertToSCPP && decl_source_range.isValid() && (DSSR.isValid())) {
+ auto cr_shptr = std::make_shared<CInitializerArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*DD, 0/*indirection_level*/), DS, initializer_info_str);
- if ((*(res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_an_array(res2.indirection_level)) {
+ if (lhs_has_been_determined_to_be_an_array) {
(*cr_shptr).do_replacement(m_state1);
} else {
m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
}
+
+ int q = 3;
} else {
int q = 7;
}
@@ -2977,19 +3537,19 @@ private:
CState1& m_state1;
};
-class MCSSSMallocInitializer2 : public MatchFinder::MatchCallback
+class MCSSSNullInitializer : public MatchFinder::MatchCallback
{
public:
- MCSSSMallocInitializer2 (Rewriter &Rewrite, CState1& state1) :
+ MCSSSNullInitializer (Rewriter &Rewrite, CState1& state1) :
Rewrite(Rewrite), m_state1(state1) {}
virtual void run(const MatchFinder::MatchResult &MR)
{
- const DeclStmt* DS = MR.Nodes.getNodeAs<clang::DeclStmt>("mcsssmallocinitializer1");
- const CallExpr* CE = MR.Nodes.getNodeAs<clang::CallExpr>("mcsssmallocinitializer2");
- const DeclaratorDecl* DD = MR.Nodes.getNodeAs<clang::DeclaratorDecl>("mcsssmallocinitializer3");
+ const DeclStmt* DS = MR.Nodes.getNodeAs<clang::DeclStmt>("mcsssnullinitializer1");
+ const Expr* RHS = MR.Nodes.getNodeAs<clang::Expr>("mcsssnullinitializer2");
+ const DeclaratorDecl* DD = MR.Nodes.getNodeAs<clang::DeclaratorDecl>("mcsssnullinitializer3");
- if ((DS != nullptr) && (CE != nullptr) && (DD != nullptr))
+ if ((DS != nullptr) && (RHS != nullptr) && (DD != nullptr))
{
auto DSSR = nice_source_range(DS->getSourceRange(), Rewrite);
SourceLocation DSSL = DSSR.getBegin();
@@ -3012,83 +3572,16 @@ public:
return void();
}
- if (std::string::npos != source_location_str.find("288")) {
+ if (std::string::npos != source_location_str.find("99")) {
int q = 5;
}
- auto function_decl = CE->getDirectCallee();
- auto num_args = CE->getNumArgs();
- if (function_decl && ((1 == num_args) || (2 == num_args))) {
- std::string function_name = function_decl->getNameAsString();
- static const std::string alloc_str = "alloc";
- static const std::string realloc_str = "realloc";
- auto lc_function_name = tolowerstr(function_name);
- bool ends_with_alloc = ((lc_function_name.size() >= alloc_str.size())
- && (0 == lc_function_name.compare(lc_function_name.size() - alloc_str.size(), alloc_str.size(), alloc_str)));
- bool ends_with_realloc = (ends_with_alloc && (lc_function_name.size() >= realloc_str.size())
- && (0 == lc_function_name.compare(lc_function_name.size() - realloc_str.size(), realloc_str.size(), realloc_str)));
- bool still_potentially_valid1 = (ends_with_alloc && (1 == num_args)) || (ends_with_realloc && (2 == num_args));
- if (still_potentially_valid1) {
- auto iter = CE->arg_begin();
- if (ends_with_realloc) {
- iter++;
- }
+ Expr::NullPointerConstantKind kind = RHS->IgnoreParenCasts()->isNullPointerConstant(*ASTC, Expr::NullPointerConstantValueDependence());
+ if (clang::Expr::NPCK_NotNull != kind) {
+ if (true) {
{
- auto arg_source_range = nice_source_range((*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);
-
- bool asterisk_found = false;
- auto sizeof_start_index = arg_source_text.find("sizeof(");
- if (std::string::npos != sizeof_start_index) {
- auto sizeof_end_index = arg_source_text.find(")", sizeof_start_index);
- if (std::string::npos != sizeof_end_index) {
- assert(sizeof_end_index > sizeof_start_index);
- std::string before_str = arg_source_text.substr(0, sizeof_start_index);
- std::string after_str;
- if (sizeof_end_index + 1 < arg_source_text.size()) {
- after_str = arg_source_text.substr(sizeof_end_index + 1);
- }
-
- auto index = before_str.size() - 1;
- while (0 <= index) {
- if ('*' == before_str[index]) {
- asterisk_found = true;
- }
- if (!std::isspace(before_str[index])) {
- break;
- }
-
- index -= 1;
- }
- if (asterisk_found) {
- before_str = before_str.substr(0, index);
- } else {
- size_t index2 = 0;
- while (after_str.size() > index2) {
- if ('*' == after_str[index2]) {
- asterisk_found = true;
- }
- if (!std::isspace(after_str[index2])) {
- break;
- }
-
- index2 += 1;
- }
- if (asterisk_found) {
- after_str = after_str.substr(index2 + 1);
- }
- }
- }
- }
- if (true || asterisk_found) {
- /* The argument is in the form "something * sizeof(something_else)" or
- * "sizeof(something) * something_else". So we're just going to assume that
- * this is an instance of an array being allocated. */
- std::string num_elements_text/* = before_str + after_str*/;
-
+ if (true) {
+ if (true) {
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);
@@ -3109,25 +3602,15 @@ public:
return;
}
+ if (!is_an_indirect_type(DD->getType())) {
+ return;
+ }
+
auto res1 = (*this).m_state1.m_ddecl_conversion_state_map.insert(*DD);
auto ddcs_map_iter = res1.first;
auto& ddcs_ref = (*ddcs_map_iter).second;
bool update_declaration_flag = res1.second;
- bool lhs_has_been_determined_to_be_an_array = false;
- if ("native pointer" == ddcs_ref.m_indirection_state_stack[0].m_current) {
- ddcs_ref.m_indirection_state_stack[0].m_current = "malloc target";
- } else if ("inferred array" == ddcs_ref.m_indirection_state_stack[0].m_current) {
- ddcs_ref.m_indirection_state_stack[0].m_current = "dynamic array";
- lhs_has_been_determined_to_be_an_array = true;
- //update_declaration_flag = true;
- m_state1.m_dynamic_array2_contingent_replacement_map.do_and_dispose_matching_replacements(m_state1, CDDeclIndirection(*DD, 0));
- } else if ("dynamic array" == ddcs_ref.m_indirection_state_stack[0].m_current) {
- lhs_has_been_determined_to_be_an_array = true;
- } else {
- assert("native array" != ddcs_ref.m_indirection_state_stack[0].m_current);
- }
-
const clang::Type* TP = QT.getTypePtr();
auto lhs_type_str = QT.getAsString();
@@ -3150,17 +3633,9 @@ public:
}
}
if ("" != element_type_str) {
- num_elements_text = "(";
- num_elements_text += arg_source_text;
- if (true || (("void" != element_type_str) && ("const void" != element_type_str))) {
- num_elements_text += ") / sizeof(";
- num_elements_text += element_type_str;
- } else {
- /* todo: something */
- }
- num_elements_text += ")";
-
- std::string initializer_info_str = "(" + num_elements_text + ")";
+ /* We use a space here because we are currently using the empty string to
+ * indicate that the initializer_info_str should be ignored. */
+ std::string initializer_info_str = " ";
auto decl_source_location_str = decl_source_range.getBegin().printToString(*MR.SourceManager);
std::string decl_source_text;
@@ -3172,12 +3647,13 @@ public:
auto DSSR = clang::SourceRange(DSSL, DSSLE);
if (ConvertToSCPP && decl_source_range.isValid() && (DSSR.isValid())) {
- auto cr_shptr = std::make_shared<CMallocInitializerArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*DD, 0/*indirection_level*/), DS, initializer_info_str);
+ auto cr_shptr = std::make_shared<CInitializerArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*DD, 0/*indirection_level*/), DS, initializer_info_str);
- if (lhs_has_been_determined_to_be_an_array) {
+ if (ddcs_ref.has_been_determined_to_be_an_array(0)) {
(*cr_shptr).do_replacement(m_state1);
} else {
- m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
+ m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
+ //m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
}
int q = 3;
@@ -3257,74 +3733,50 @@ public:
arg_source_text = Rewrite.getRewrittenText(arg_source_range);
//auto arg_source_text_sans_ws = with_whitespace_removed(arg_source_text);
- QualType QT;
- std::string variable_name;
- std::string ce_replacement_code;
-
- auto res2 = infer_array_type_info_from_stmt(*(*(CE->arg_begin())), "malloc target", (*this).m_state1);
- auto DD = res2.ddecl_cptr;
+ auto ARG = (*(arg_iter))->IgnoreParenCasts();
+ auto arg_res2 = infer_array_type_info_from_stmt(*ARG, "malloc target", (*this).m_state1);
+ bool arg_is_an_indirect_type = is_an_indirect_type(ARG->getType());
- if (res2.update_declaration_flag) {
- update_declaration(*DD, Rewrite, m_state1);
+ if (arg_res2.update_declaration_flag) {
+ update_declaration(*(arg_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 arg_QT = ARG->getType();
+ const clang::Type* arg_TP = arg_QT.getTypePtr();
+ auto arg_type_str = arg_QT.getAsString();
- 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;
+ std::string arg_element_type_str;
+ if (arg_TP->isArrayType()) {
+ auto ATP = llvm::cast<const clang::ArrayType>(arg_TP);
+ assert(nullptr != ATP);
+ auto element_type = ATP->getElementType();
+ auto type_str = element_type.getAsString();
+ if (("char" != type_str) && ("const char" != type_str)) {
+ arg_element_type_str = type_str;
}
-
- const clang::Type* TP = QT.getTypePtr();
- auto type_str = QT.getAsString();
-
- std::string element_type_str;
- if (TP->isArrayType()) {
- auto ATP = llvm::cast<const clang::ArrayType>(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<const clang::PointerType>(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;
- }
+ } else if (arg_TP->isPointerType()) {
+ auto TPP = llvm::cast<const clang::PointerType>(arg_TP);
+ assert(nullptr != TPP);
+ auto target_type = TPP->getPointeeType();
+ auto type_str = target_type.getAsString();
+ if (("char" != type_str) && ("const char" != type_str)) {
+ arg_element_type_str = type_str;
}
+ }
- if ("" != element_type_str) {
- ce_replacement_code = "(" + arg_source_text + ")";
+ if ("" != arg_element_type_str) {
+ if (ConvertToSCPP && (arg_res2.ddecl_conversion_state_ptr) && arg_is_an_indirect_type) {
+ auto arg_source_text = Rewrite.getRewrittenText(arg_source_range);
+ std::string 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<CFreeDynamicArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*(res2.ddecl_cptr), res2.indirection_level), CE, ce_replacement_code);
+ auto cr_shptr = std::make_shared<CFreeDynamicArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*(arg_res2.ddecl_cptr), arg_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);
- } else {
- m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
- }
+ if ((*(arg_res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_an_array(arg_res2.indirection_level)) {
+ (*cr_shptr).do_replacement(m_state1);
} else {
- int q = 7;
+ m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
+ //m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
}
}
}
@@ -3387,7 +3839,7 @@ public:
}
Expr::NullPointerConstantKind kind = RHS->isNullPointerConstant(*ASTC, Expr::NullPointerConstantValueDependence());
- if (clang::Expr::NPCK_NotNull != kind) {
+ if (false && (clang::Expr::NPCK_NotNull != kind)) {
auto lhs_source_range = nice_source_range(LHS->getSourceRange(), Rewrite);
std::string lhs_source_text;
if (lhs_source_range.isValid()) {
@@ -3406,7 +3858,7 @@ public:
auto lhs_type_str = lhs_QT.getAsString();
std::string lhs_element_type_str;
- if (lhs_TP->isArrayType()) {
+ if (llvm::isa<const clang::ArrayType>(lhs_TP)) {
auto ATP = llvm::cast<const clang::ArrayType>(lhs_TP);
assert(nullptr != ATP);
auto element_type = ATP->getElementType();
@@ -3414,7 +3866,7 @@ public:
if (("char" != type_str) && ("const char" != type_str)) {
lhs_element_type_str = type_str;
}
- } else if (lhs_TP->isPointerType()) {
+ } else if (llvm::isa<const clang::PointerType>(lhs_TP)) {
auto TPP = llvm::cast<const clang::PointerType>(lhs_TP);
assert(nullptr != TPP);
auto target_type = TPP->getPointeeType();
@@ -3427,15 +3879,125 @@ public:
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)";
+ std::string bo_replacement_code = "( (" + lhs_source_text + ") = typename std::remove_reference<decltype(" + lhs_source_text + ")>::type() )";
- auto cr_shptr = std::make_shared<CSetArrayPointerToNull2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*(lhs_res2.ddecl_cptr), lhs_res2.indirection_level), BO, bo_replacement_code);
+ auto cr_shptr = std::make_shared<CExprTextReplacementAction>(Rewrite, MR, CDDeclIndirection(*(lhs_res2.ddecl_cptr), lhs_res2.indirection_level), BO, bo_replacement_code);
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);
+ m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
+ //m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
+ }
+ }
+ }
+ int q = 5;
+ } else {
+ int q = 5;
+ }
+ int q = 5;
+ }
+ }
+ }
+
+private:
+ Rewriter &Rewrite;
+ CState1& m_state1;
+};
+
+class MCSSSCompareWithNull2 : public MatchFinder::MatchCallback
+{
+public:
+ MCSSSCompareWithNull2 (Rewriter &Rewrite, CState1& state1) :
+ Rewrite(Rewrite), m_state1(state1) {}
+
+ virtual void run(const MatchFinder::MatchResult &MR)
+ {
+ const BinaryOperator* BO = MR.Nodes.getNodeAs<clang::BinaryOperator>("mcssscomparewithnull1");
+ const Expr* RHS = nullptr;
+ const Expr* LHS = nullptr;
+ if (BO != nullptr) {
+ RHS = BO->getRHS();
+ LHS = BO->getLHS();
+ }
+ const DeclRefExpr* DRE = MR.Nodes.getNodeAs<clang::DeclRefExpr>("mcssscomparewithnull3");
+ const MemberExpr* ME = MR.Nodes.getNodeAs<clang::MemberExpr>("mcssscomparewithnull4");
+
+ if ((BO != nullptr) && (RHS != nullptr) && (LHS != nullptr) && (DRE != nullptr))
+ {
+ auto BOSR = nice_source_range(BO->getSourceRange(), Rewrite);
+ SourceLocation BOSL = BOSR.getBegin();
+ SourceLocation BOSLE = BOSR.getEnd();
+
+ ASTContext *const ASTC = MR.Context;
+ FullSourceLoc FBOSL = ASTC->getFullLoc(BOSL);
+
+ SourceManager &SM = ASTC->getSourceManager();
+
+ auto source_location_str = BOSL.printToString(*MR.SourceManager);
+ std::string source_text;
+ if (BOSL.isValid() && BOSLE.isValid()) {
+ source_text = Rewrite.getRewrittenText(SourceRange(BOSL, BOSLE));
+ } else {
+ return;
+ }
+
+ if (filtered_out_by_location(MR, BOSL)) {
+ return void();
+ }
+
+ Expr::NullPointerConstantKind kind = RHS->isNullPointerConstant(*ASTC, Expr::NullPointerConstantValueDependence());
+ if (clang::Expr::NPCK_NotNull != kind) {
+ auto lhs_source_range = nice_source_range(LHS->getSourceRange(), Rewrite);
+ std::string lhs_source_text;
+ if (lhs_source_range.isValid()) {
+ lhs_source_text = Rewrite.getRewrittenText(lhs_source_range);
+ //auto lhs_source_text_sans_ws = with_whitespace_removed(lhs_source_text);
+
+ auto lhs_res2 = infer_array_type_info_from_stmt(*LHS, "compare with 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);
+ }
+
+ 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 (llvm::isa<const clang::ArrayType>(lhs_TP)) {
+ auto ATP = llvm::cast<const clang::ArrayType>(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;
+ }
+ } else if (llvm::isa<const clang::PointerType>(lhs_TP)) {
+ auto TPP = llvm::cast<const clang::PointerType>(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;
+ }
+ }
+
+ if ("" != lhs_element_type_str) {
+ if (ConvertToSCPP && (lhs_res2.ddecl_conversion_state_ptr) && lhs_is_an_indirect_type) {
+ std::string opcode_str = BO->getOpcodeStr();
+
+ auto lhs_source_text = Rewrite.getRewrittenText(lhs_source_range);
+ std::string bo_replacement_code = "bool(" + lhs_source_text + ")";
+
+ auto cr_shptr = std::make_shared<CExprTextReplacementAction>(Rewrite, MR, CDDeclIndirection(*(lhs_res2.ddecl_cptr), lhs_res2.indirection_level), BO, bo_replacement_code);
+
+ 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_array2_contingent_replacement_map.insert(cr_shptr);
+ //m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
}
}
}
@@ -3589,10 +4151,14 @@ public:
}
}
if ("" != arg1_element_type_str) {
- ce_replacement_code = "for (size_t i = 0; i < (" + arg_source_text3
- + ")/sizeof(" + arg1_element_type_str + "); i += 1) { ";
- ce_replacement_code += "(" + arg_source_text1 + ")[i] = " + arg_source_text2 + "; ";
- ce_replacement_code += "}";
+ if (false) {
+ ce_replacement_code = "for (size_t i = 0; i < (" + arg_source_text3
+ + ")/sizeof(" + arg1_element_type_str + "); i += 1) { ";
+ ce_replacement_code += "(" + arg_source_text1 + ")[i] = " + arg_source_text2 + "; ";
+ ce_replacement_code += "}";
+ } else {
+ ce_replacement_code = "MSE_LH_MEMSET(" + arg_source_text1 + ", " + arg_source_text2 + ", " + arg_source_text3 + ")";
+ }
if (ConvertToSCPP && decl_source_range.isValid() && (CESR.isValid())
&& (nullptr != res2.ddecl_conversion_state_ptr)) {
@@ -3767,10 +4333,14 @@ public:
}
std::string ce_replacement_code;
if (("" != arg1_element_type_str) && ("void" != arg1_element_type_str) && ("const void" != arg1_element_type_str)) {
- ce_replacement_code = "for (size_t i = 0; i < (" + arg_source_text3
- + ")/sizeof(" + arg1_element_type_str + "); i += 1) { ";
- ce_replacement_code += "(" + arg_source_text1 + ")[i] = (" + arg_source_text2 + ")[i]; ";
- ce_replacement_code += "}";
+ if (false) {
+ ce_replacement_code = "for (size_t i = 0; i < (" + arg_source_text3
+ + ")/sizeof(" + arg1_element_type_str + "); i += 1) { ";
+ ce_replacement_code += "(" + arg_source_text1 + ")[i] = (" + arg_source_text2 + ")[i]; ";
+ ce_replacement_code += "}";
+ } else {
+ ce_replacement_code = "MSE_LH_MEMCPY(" + arg_source_text1 + ", " + arg_source_text2 + ", " + arg_source_text3 + ")";
+ }
}
if (ConvertToSCPP && (CESR.isValid()) && ("" != ce_replacement_code)) {
@@ -4083,7 +4653,7 @@ public:
return void();
}
- if (std::string::npos != source_location_str.find("129")) {
+ if (std::string::npos != source_location_str.find("457")) {
int q = 5;
}
@@ -4108,26 +4678,36 @@ public:
auto direct_rhs_qtype = populateQTypeIndirectionStack(rhs_qtype_indirection_state_stack, rhs_QT);
auto direct_rhs_qtype_str = direct_rhs_qtype.getAsString();
auto casted_expr_ptr = CCE->IgnoreCasts();
+ if (llvm::isa<const clang::CallExpr>(casted_expr_ptr->IgnoreParenCasts())) {
+ auto CE = llvm::cast<const clang::CallExpr>(casted_expr_ptr->IgnoreParenCasts());
+ auto alloc_function_info1 = analyze_malloc_resemblance(*CE, Rewrite);
+ if (alloc_function_info1.m_seems_to_be_some_kind_of_malloc_or_realloc) {
+ /* This seems to be some kind of malloc/realloc function. These case should not be
+ * handled here. They are handled elsewhere. */
+ return;
+ }
+ }
if ((rhs_qtype_indirection_state_stack.size() + rhs_res2.indirection_level
== (*(rhs_res2.ddecl_conversion_state_ptr)).m_indirection_state_stack.size())
&& (1 <= (*rhs_res2.ddecl_conversion_state_ptr).m_indirection_state_stack.size())
&& (nullptr != casted_expr_ptr)) {
- std::string rhs_ddecl_current_direct_qtype_str = (*rhs_res2.ddecl_conversion_state_ptr).m_current_direct_qtype.getAsString();
+ std::string rhs_ddecl_current_direct_qtype_str = (*rhs_res2.ddecl_conversion_state_ptr).m_current_direct_qtype_str;
auto casted_expr_SR = nice_source_range(casted_expr_ptr->getSourceRange(), Rewrite);
auto CCESR = nice_source_range(CCE->getSourceRange(), Rewrite);
+ auto cast_operation_SR = clang::SourceRange(CCE->getLParenLoc(), CCE->getRParenLoc());
- if (CCESR.isValid() && casted_expr_SR.isValid()
+ if (cast_operation_SR.isValid()
&& (("void" == rhs_ddecl_current_direct_qtype_str) || ("const void" == rhs_ddecl_current_direct_qtype_str))) {
if (ConvertToSCPP) {
- (*rhs_res2.ddecl_conversion_state_ptr).m_current_direct_qtype = direct_rhs_qtype;
+ (*rhs_res2.ddecl_conversion_state_ptr).set_current_direct_qtype(direct_rhs_qtype);
+ auto cast_operation_text = Rewrite.getRewrittenText(cast_operation_SR);
/* This is not the proper way to modify an expression. See the function
* CConditionalOperatorReconciliation2ReplacementAction::do_replacement() for an example of
* the proper way to do it. But for now this is good enough. */
- auto casted_expr_text = Rewrite.getRewrittenText(casted_expr_SR);
- auto res2 = Rewrite.ReplaceText(CCESR, casted_expr_text);
+ auto res2 = Rewrite.ReplaceText(cast_operation_SR, "");
static const std::string void_str = "void";
auto void_pos = (*rhs_res2.ddecl_conversion_state_ptr).m_initializer_info_str.find(void_str);
@@ -4139,7 +4719,9 @@ public:
}
} else {
if (ConvertToSCPP) {
- //(*rhs_res2.ddecl_conversion_state_ptr).m_current_direct_qtype = direct_rhs_qtype;
+ if (false) {
+ (*rhs_res2.ddecl_conversion_state_ptr).set_current_direct_qtype(direct_rhs_qtype);
+ }
}
}
} else {
@@ -4150,6 +4732,32 @@ public:
}
}
+ size_t lhs_indirection_level_adjustment = 0;
+ auto rhs_res3 = leading_addressof_operator_info_from_stmt(*RHS);
+ if (rhs_res3.without_leading_addressof_operator_expr_cptr) {
+ assert(rhs_res3.leading_addressof_operator_detected && rhs_res3.addressof_unary_operator_cptr);
+
+ RHS = rhs_res3.without_leading_addressof_operator_expr_cptr;
+ rhs_res2 = infer_array_type_info_from_stmt(*RHS, "", (*this).m_state1);
+ 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<const clang::ArraySubscriptExpr>(rhs_res3.without_leading_addressof_operator_expr_cptr));
+ array_subscript_expr_cptr = llvm::cast<const clang::ArraySubscriptExpr>(rhs_res3.without_leading_addressof_operator_expr_cptr);
+ }
+ if (ConvertToSCPP && array_subscript_expr_cptr) {
+ std::shared_ptr<CArray2ReplacementAction> cr_shptr = std::make_shared<CAssignmentTargetConstrainsAddressofArraySubscriptExprArray2ReplacementAction>(Rewrite, MR,
+ CDDeclIndirection(*(lhs_res2.ddecl_cptr), 0), *(rhs_res3.addressof_unary_operator_cptr), *array_subscript_expr_cptr);
+
+ if ((*(lhs_res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_an_array()) {
+ (*cr_shptr).do_replacement(m_state1);
+ } else {
+ m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
+ }
+ }
+ }
+
if (ConvertToSCPP && (lhs_res2.ddecl_conversion_state_ptr) && (rhs_res2.ddecl_conversion_state_ptr) && lhs_is_an_indirect_type) {
for (size_t i = 0; (rhs_res2.indirection_level + i < (*(lhs_res2.ddecl_conversion_state_ptr)).m_indirection_state_stack.size())
&& (rhs_res2.indirection_level + i < (*(rhs_res2.ddecl_conversion_state_ptr)).m_indirection_state_stack.size()); i += 1) {
@@ -4157,11 +4765,18 @@ public:
/* Here we're establishing and "enforcing" the constraint that the rhs value must
* be of an (array) type that can be assigned to the lhs. */
auto cr_shptr = std::make_shared<CAssignmentTargetConstrainsSourceArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*(lhs_res2.ddecl_cptr), lhs_res2.indirection_level + i), CDDeclIndirection(*(rhs_res2.ddecl_cptr), rhs_res2.indirection_level + i));
+ auto cr_shptr2 = std::make_shared<CAssignmentTargetConstrainsSourceDynamicArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*(lhs_res2.ddecl_cptr), lhs_res2.indirection_level + i), CDDeclIndirection(*(rhs_res2.ddecl_cptr), rhs_res2.indirection_level + i));
if ((*(lhs_res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_an_array(lhs_res2.indirection_level + i)) {
(*cr_shptr).do_replacement(m_state1);
+ if ((*(lhs_res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_a_dynamic_array(lhs_res2.indirection_level + i)) {
+ (*cr_shptr2).do_replacement(m_state1);
+ } else {
+ m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr2);
+ }
} else {
m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
+ m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr2);
}
}
{
@@ -4221,7 +4836,7 @@ public:
return void();
}
- if (std::string::npos != source_location_str.find("130")) {
+ if (std::string::npos != source_location_str.find("438")) {
int q = 5;
}
@@ -4277,6 +4892,104 @@ public:
auto& ddcs_ref = (*ddcs_map_iter).second;
bool update_declaration_flag = res1.second;
+ auto lhs_QT = param_VD->getType();
+ const clang::Type* lhs_TP = lhs_QT.getTypePtr();
+ auto lhs_type_str = lhs_QT.getAsString();
+
+ bool lhs_element_type_is_const_char = false;
+ std::string lhs_element_type_str;
+ if (llvm::isa<const clang::ArrayType>(lhs_TP)) {
+ auto ATP = llvm::cast<const clang::ArrayType>(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;
+ } else if ("const char" == type_str) {
+ lhs_element_type_is_const_char = true;
+ }
+ } else if (llvm::isa<const clang::PointerType>(lhs_TP)) {
+ auto TPP = llvm::cast<const clang::PointerType>(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;
+ } else if ("const char" == type_str) {
+ lhs_element_type_is_const_char = true;
+ }
+ }
+
+ Expr::NullPointerConstantKind kind = arg_EX->isNullPointerConstant(*ASTC, Expr::NullPointerConstantValueDependence());
+ if (false && (clang::Expr::NPCK_NotNull != kind)) {
+
+ if ("" != lhs_element_type_str) {
+ auto lhs_source_range = nice_source_range(param_VD->getSourceRange(), Rewrite);
+ if (ConvertToSCPP && lhs_is_an_indirect_type && lhs_source_range.isValid()) {
+ auto lhs_source_text = Rewrite.getRewrittenText(lhs_source_range);
+
+ auto res4 = generate_type_indirection_prefix_and_suffix(ddcs_ref.m_indirection_state_stack, false/*direct_type_is_char_type*/, false/*direct_type_is_function_type*/, true/*is_a_function_parameter*/);
+ if (true) {
+ auto direct_qtype = ddcs_ref.m_current_direct_qtype;
+ if (res4.m_direct_type_must_be_non_const) {
+ direct_qtype.removeLocalConst();
+ }
+ std::string direct_qtype_str = direct_qtype.getAsString();
+ std::string arg_replacement_code = res4.m_prefix_str + direct_qtype_str + res4.m_suffix_str + "()";
+
+ auto cr_shptr = std::make_shared<CExprTextReplacementAction>(Rewrite, MR, CDDeclIndirection(*(param_VD), 0/*indirection_level*/), arg_EX, arg_replacement_code);
+
+ if (ddcs_ref.has_been_determined_to_be_an_array()) {
+ (*cr_shptr).do_replacement(m_state1);
+ } else {
+ m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
+ //m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ auto argii_EX = (*arg_iter)->IgnoreImplicit();
+ if (rhs_is_an_indirect_type && (argii_EX->getStmtClass() == clang::Stmt::StmtClass::CStyleCastExprClass)) {
+ bool special_case1_flag = false;
+ auto casted_expr = argii_EX->IgnoreParenCasts();
+ std::string casted_expr_type_str = casted_expr->getType().getAsString();
+ if ("const unsigned char" == lhs_element_type_str) {
+ if (("char *" == casted_expr_type_str) || ("const char *" == casted_expr_type_str)) {
+ special_case1_flag = true;
+ }
+ } else if (lhs_element_type_is_const_char) {
+ //lhs_element_type_str = "const char";
+ if (("unsigned char *" == casted_expr_type_str) || ("const unsigned char *" == casted_expr_type_str)) {
+ special_case1_flag = true;
+ }
+ }
+ if (special_case1_flag) {
+ auto casted_expr_SR = nice_source_range(casted_expr->getSourceRange(), Rewrite);
+ std::string casted_expr_text = Rewrite.getRewrittenText(casted_expr_SR);
+ std::string replacement_casted_expr_text = "std::addressof(" + casted_expr_text + "[0])";
+ Rewrite.ReplaceText(casted_expr_SR, replacement_casted_expr_text);
+ return;
+ } else {
+ auto CSCE = llvm::cast<const clang::CStyleCastExpr>(argii_EX);
+ if (CSCE) {
+ auto cast_operation_SR = clang::SourceRange(CSCE->getLParenLoc(), CSCE->getRParenLoc());
+ if (ConvertToSCPP && cast_operation_SR.isValid()) {
+ auto cast_operation_text = Rewrite.getRewrittenText(cast_operation_SR);
+ /* This is not the proper way to modify an expression. See the function
+ * CConditionalOperatorReconciliation2ReplacementAction::do_replacement() for an example of
+ * the proper way to do it. But for now this is good enough. */
+ auto res2 = Rewrite.ReplaceText(cast_operation_SR, "");
+ }
+
+ auto cast_kind_name = CSCE->getCastKindName();
+ auto cast_kind = CSCE->getCastKind();
+ } else { assert(false); }
+ }
+ }
+
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) {
@@ -4290,11 +5003,11 @@ public:
assert(llvm::isa<const clang::ArraySubscriptExpr>(rhs_res3.without_leading_addressof_operator_expr_cptr));
array_subscript_expr_cptr = llvm::cast<const clang::ArraySubscriptExpr>(rhs_res3.without_leading_addressof_operator_expr_cptr);
}
- if (array_subscript_expr_cptr) {
+ if (ConvertToSCPP && array_subscript_expr_cptr) {
std::shared_ptr<CArray2ReplacementAction> cr_shptr = std::make_shared<CAssignmentTargetConstrainsAddressofArraySubscriptExprArray2ReplacementAction>(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)) {
+ if (ddcs_ref.has_been_determined_to_be_an_array()) {
(*cr_shptr).do_replacement(m_state1);
} else {
m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
@@ -4307,56 +5020,6 @@ public:
update_declaration(*(rhs_res2.ddecl_cptr), Rewrite, m_state1);
}
- if ((nullptr != CCE) && (rhs_res2.ddecl_conversion_state_ptr)) {
- auto cce_QT = CCE->getType();
- auto rhs_QT = arg_EX->getType();
- if (cce_QT == rhs_QT) {
- CIndirectionStateStack rhs_qtype_indirection_state_stack;
- auto direct_rhs_qtype = populateQTypeIndirectionStack(rhs_qtype_indirection_state_stack, rhs_QT);
- auto direct_rhs_qtype_str = direct_rhs_qtype.getAsString();
- auto casted_expr_ptr = CCE->IgnoreCasts();
-
- if ((rhs_qtype_indirection_state_stack.size() + rhs_res2.indirection_level
- == (*(rhs_res2.ddecl_conversion_state_ptr)).m_indirection_state_stack.size())
- && (1 <= (*rhs_res2.ddecl_conversion_state_ptr).m_indirection_state_stack.size())
- && (nullptr != casted_expr_ptr)) {
-
- std::string rhs_ddecl_current_direct_qtype_str = (*rhs_res2.ddecl_conversion_state_ptr).m_current_direct_qtype.getAsString();
- auto casted_expr_SR = nice_source_range(casted_expr_ptr->getSourceRange(), Rewrite);
- auto CCESR = nice_source_range(CCE->getSourceRange(), Rewrite);
-
- if (CCESR.isValid() && casted_expr_SR.isValid()
- && (("void" == rhs_ddecl_current_direct_qtype_str) || ("const void" == rhs_ddecl_current_direct_qtype_str))) {
- if (ConvertToSCPP) {
- (*rhs_res2.ddecl_conversion_state_ptr).m_current_direct_qtype = direct_rhs_qtype;
-
- /* This is not the proper way to modify an expression. See the function
- * CConditionalOperatorReconciliation2ReplacementAction::do_replacement() for an example of
- * the proper way to do it. But for now this is good enough. */
- auto casted_expr_text = Rewrite.getRewrittenText(casted_expr_SR);
- auto res2 = Rewrite.ReplaceText(CCESR, casted_expr_text);
-
- static const std::string void_str = "void";
- auto void_pos = (*rhs_res2.ddecl_conversion_state_ptr).m_initializer_info_str.find(void_str);
- if (std::string::npos != void_pos) {
- (*rhs_res2.ddecl_conversion_state_ptr).m_initializer_info_str.replace(void_pos, void_str.length(), direct_rhs_qtype_str);
- }
-
- update_declaration(*(rhs_res2.ddecl_cptr), Rewrite, m_state1);
- }
- } else {
- if (ConvertToSCPP) {
- //(*rhs_res2.ddecl_conversion_state_ptr).m_current_direct_qtype = direct_rhs_qtype;
- }
- }
- } else {
- int q = 7;
- }
- } else {
- int q = 7;
- }
- }
-
if (ddcs_ref.m_ddecl_cptr && update_declaration_flag) {
update_declaration(*(ddcs_ref.m_ddecl_cptr), Rewrite, m_state1);
}
@@ -4425,7 +5088,65 @@ public:
int q = 5;
}
}
+ } else {
+ auto D = CE->getCalleeDecl();
+ auto DD = dynamic_cast<const DeclaratorDecl*>(D);
+ auto EX = CE->getCallee();
+
+ if (DD && EX) {
+ auto DDSR = nice_source_range(DD->getSourceRange(), Rewrite);
+ std::string ddecl_source_text;
+ if (DDSR.isValid()) {
+ ddecl_source_text = Rewrite.getRewrittenText(DDSR);
+ } else {
+ return;
+ }
+ auto EXSR = nice_source_range(EX->getSourceRange(), Rewrite);
+ std::string expr_source_text;
+ if (EXSR.isValid()) {
+ expr_source_text = Rewrite.getRewrittenText(EXSR);
+ } else {
+ return;
+ }
+
+ if (ConvertToSCPP) {
+ auto args = CE->arguments();
+ for (auto& arg : args) {
+ auto rhs_res2 = infer_array_type_info_from_stmt(*arg, "", (*this).m_state1);
+ bool rhs_is_an_indirect_type = is_an_indirect_type(arg->getType());
+
+ if (rhs_res2.ddecl_cptr && rhs_res2.ddecl_conversion_state_ptr) {
+ int int_max_indirection_level = int((*(rhs_res2.ddecl_conversion_state_ptr)).m_indirection_state_stack.size()) - int(rhs_res2.indirection_level);
+ size_t szt_max_indirection_level = 0;
+ if (0 <= int_max_indirection_level) {
+ szt_max_indirection_level = size_t(int_max_indirection_level);
+ }
+
+ for (size_t i = 0; i < szt_max_indirection_level; i += 1) {
+ std::shared_ptr<CUpdateIndirectFunctionTypeParamsArray2ReplacementAction> cr_shptr =
+ std::make_shared<CUpdateIndirectFunctionTypeParamsArray2ReplacementAction>(Rewrite, MR,
+ CDDeclIndirection(*(rhs_res2.ddecl_cptr), rhs_res2.indirection_level + i), *DD, *CE);
+
+ if ((*(rhs_res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_an_array(rhs_res2.indirection_level + i)) {
+ (*cr_shptr).do_replacement(m_state1);
+ if (!((*(rhs_res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_a_dynamic_array(rhs_res2.indirection_level + i))) {
+ m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
+ }
+ } else {
+ m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
+ m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
+ }
+ }
+ } else {
+ int q = 5;
+ }
+ }
+ }
+ int q = 5;
+ } else {
+ int q = 7;
+ }
}
}
}
@@ -4470,6 +5191,11 @@ public:
return void();
}
+ if (std::string::npos != source_location_str.find("129")) {
+ walkTheAST1(*RS);
+ int q = 5;
+ }
+
auto function_decl1 = FND;
auto num_params = FND->getNumParams();
if (function_decl1) {
@@ -4493,8 +5219,38 @@ public:
return void();
}
- auto rhs_res2 = infer_array_type_info_from_stmt(*(RS->getRetValue()), "", (*this).m_state1);
- bool rhs_is_an_indirect_type = is_an_indirect_type(RS->getRetValue()->getType());
+ auto retval_EX = RS->getRetValue();
+
+ bool rhs_is_an_indirect_type = is_an_indirect_type(retval_EX->getType());
+
+ auto retvalii_EX = RS->getRetValue()->IgnoreImplicit();
+ if (rhs_is_an_indirect_type && (retvalii_EX->getStmtClass() == clang::Stmt::StmtClass::CStyleCastExprClass)) {
+ auto CSCE = llvm::cast<const clang::CStyleCastExpr>(retvalii_EX);
+ if (CSCE) {
+ auto cast_operation_SR = clang::SourceRange(CSCE->getLParenLoc(), CSCE->getRParenLoc());
+ if (ConvertToSCPP && cast_operation_SR.isValid()) {
+ auto cast_operation_text = Rewrite.getRewrittenText(cast_operation_SR);
+ /* This is not the proper way to modify an expression. See the function
+ * CConditionalOperatorReconciliation2ReplacementAction::do_replacement() for an example of
+ * the proper way to do it. But for now this is good enough. */
+ auto res2 = Rewrite.ReplaceText(cast_operation_SR, "");
+ }
+
+ auto cast_kind_name = CSCE->getCastKindName();
+ auto cast_kind = CSCE->getCastKind();
+ } else { assert(false); }
+ }
+
+ size_t lhs_indirection_level_adjustment = 0;
+ auto rhs_res3 = leading_addressof_operator_info_from_stmt(*retval_EX);
+ if (rhs_res3.without_leading_addressof_operator_expr_cptr) {
+ assert(rhs_res3.leading_addressof_operator_detected && rhs_res3.addressof_unary_operator_cptr);
+
+ retval_EX = rhs_res3.without_leading_addressof_operator_expr_cptr;
+ lhs_indirection_level_adjustment = 1;
+ }
+
+ auto rhs_res2 = infer_array_type_info_from_stmt(*(retval_EX), "", (*this).m_state1);
if (rhs_res2.ddecl_cptr && rhs_res2.update_declaration_flag) {
update_declaration(*(rhs_res2.ddecl_cptr), Rewrite, m_state1);
}
@@ -4512,28 +5268,78 @@ public:
update_declaration(*(ddcs_ref.m_ddecl_cptr), Rewrite, m_state1);
}
+ if (rhs_res3.without_leading_addressof_operator_expr_cptr) {
+ 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<const clang::ArraySubscriptExpr>(rhs_res3.without_leading_addressof_operator_expr_cptr));
+ array_subscript_expr_cptr = llvm::cast<const clang::ArraySubscriptExpr>(rhs_res3.without_leading_addressof_operator_expr_cptr);
+ }
+ if (array_subscript_expr_cptr) {
+ std::shared_ptr<CArray2ReplacementAction> cr_shptr = std::make_shared<CAssignmentTargetConstrainsAddressofArraySubscriptExprArray2ReplacementAction>(Rewrite, MR,
+ CDDeclIndirection(*function_decl, 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);
+ }
+ }
+ }
+
if (ConvertToSCPP && (rhs_res2.ddecl_conversion_state_ptr) && lhs_is_an_indirect_type) {
- for (size_t i = 0; (rhs_res2.indirection_level + i < ddcs_ref.m_indirection_state_stack.size())
- && (rhs_res2.indirection_level + i < (*(rhs_res2.ddecl_conversion_state_ptr)).m_indirection_state_stack.size()); i += 1) {
+ int max_indirection_level1 = int((*(rhs_res2.ddecl_conversion_state_ptr)).m_indirection_state_stack.size()) - int(rhs_res2.indirection_level);
+ int int_max_indirection_level = std::min(int(ddcs_ref.m_indirection_state_stack.size()) - int(lhs_indirection_level_adjustment), max_indirection_level1);
+ size_t szt_max_indirection_level = 0;
+ if (0 <= int_max_indirection_level) {
+ szt_max_indirection_level = size_t(int_max_indirection_level);
+ }
+
+ for (size_t i = 0; (i < szt_max_indirection_level); i += 1) {
{
/* Here we're establishing and "enforcing" the constraint that the rhs value must
* be of an (array) type that can be assigned to the lhs. */
- auto cr_shptr = std::make_shared<CAssignmentTargetConstrainsSourceArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*function_decl, 0 + i), CDDeclIndirection(*(rhs_res2.ddecl_cptr), rhs_res2.indirection_level + i));
+ std::shared_ptr<CArray2ReplacementAction> cr_shptr;
+ if (1 > (i + lhs_indirection_level_adjustment)) {
+ cr_shptr = std::make_shared<CAssignmentTargetConstrainsSourceArray2ReplacementAction>(Rewrite, MR,
+ CDDeclIndirection(*function_decl, 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<CSameTypeArray2ReplacementAction>(Rewrite, MR,
+ CDDeclIndirection(*function_decl, i + lhs_indirection_level_adjustment), CDDeclIndirection(*(rhs_res2.ddecl_cptr), rhs_res2.indirection_level + i));
+ }
- if (ddcs_ref.has_been_determined_to_be_an_array(0 + i)) {
+ if (ddcs_ref.has_been_determined_to_be_an_array(i + lhs_indirection_level_adjustment)) {
(*cr_shptr).do_replacement(m_state1);
+ if (!(ddcs_ref.has_been_determined_to_be_a_dynamic_array(i + lhs_indirection_level_adjustment))) {
+ m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
+ }
} else {
m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
+ m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
}
}
{
/* Here we're establishing the constraint in the opposite direction as well. */
- auto cr_shptr = std::make_shared<CAssignmentSourceConstrainsTargetArray2ReplacementAction>(Rewrite, MR, CDDeclIndirection(*(rhs_res2.ddecl_cptr), rhs_res2.indirection_level + i), CDDeclIndirection(*function_decl, 0 + i));
+ std::shared_ptr<CArray2ReplacementAction> cr_shptr;
+ if (1 > (i + lhs_indirection_level_adjustment)) {
+ cr_shptr = std::make_shared<CAssignmentSourceConstrainsTargetArray2ReplacementAction>(Rewrite, MR,
+ CDDeclIndirection(*(rhs_res2.ddecl_cptr), rhs_res2.indirection_level + i), CDDeclIndirection(*function_decl, i + lhs_indirection_level_adjustment));
+ } else {
+ /* Levels of indirection beyond the first one must be of the same type,
+ * not just of "compatible" types. */
+ cr_shptr = std::make_shared<CSameTypeArray2ReplacementAction>(Rewrite, MR,
+ CDDeclIndirection(*(rhs_res2.ddecl_cptr), rhs_res2.indirection_level + i), CDDeclIndirection(*function_decl, i + lhs_indirection_level_adjustment));
+ }
if ((*(rhs_res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_an_array(rhs_res2.indirection_level + i)) {
(*cr_shptr).do_replacement(m_state1);
+ if (!((*(rhs_res2.ddecl_conversion_state_ptr)).has_been_determined_to_be_a_dynamic_array(rhs_res2.indirection_level + i))) {
+ m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
+ }
} else {
m_state1.m_array2_contingent_replacement_map.insert(cr_shptr);
+ m_state1.m_dynamic_array2_contingent_replacement_map.insert(cr_shptr);
}
}
}
@@ -4549,15 +5355,386 @@ private:
CState1& m_state1;
};
+class MCSSSFRead : public MatchFinder::MatchCallback
+{
+public:
+ MCSSSFRead (Rewriter &Rewrite, CState1& state1) :
+ Rewrite(Rewrite), m_state1(state1) {}
+
+ virtual void run(const MatchFinder::MatchResult &MR)
+ {
+ const CallExpr* CE = MR.Nodes.getNodeAs<clang::CallExpr>("mcsssfread1");
+ const DeclRefExpr* DRE = MR.Nodes.getNodeAs<clang::DeclRefExpr>("mcsssfread2");
+ const MemberExpr* ME = MR.Nodes.getNodeAs<clang::MemberExpr>("mcsssfread3");
+
+ if ((CE != nullptr) && (DRE != nullptr))
+ {
+ auto CESR = nice_source_range(CE->getSourceRange(), Rewrite);
+ SourceLocation CESL = CESR.getBegin();
+ SourceLocation CESLE = CESR.getEnd();
+
+ ASTContext *const ASTC = MR.Context;
+ FullSourceLoc FCESL = ASTC->getFullLoc(CESL);
+
+ SourceManager &SM = ASTC->getSourceManager();
+
+ auto source_location_str = CESL.printToString(*MR.SourceManager);
+ std::string source_text;
+ if (CESL.isValid() && CESLE.isValid()) {
+ source_text = Rewrite.getRewrittenText(SourceRange(CESL, CESLE));
+ } else {
+ return;
+ }
+
+ if (filtered_out_by_location(MR, CESL)) {
+ return void();
+ }
+
+ auto function_decl = CE->getDirectCallee();
+ auto num_args = CE->getNumArgs();
+ if (function_decl && (4 == num_args)) {
+ {
+ std::string function_name = function_decl->getNameAsString();
+ static const std::string fread_str = "fread";
+ if (fread_str == function_name) {
+ auto iter1 = CE->arg_begin();
+ assert((*iter1)->IgnoreParenCasts()->getType().getTypePtrOrNull());
+ auto arg_source_range1 = nice_source_range((*iter1)->IgnoreParenCasts()->getSourceRange(), Rewrite);
+
+ auto iter2 = iter1;
+ iter2++;
+ assert((*iter2)->IgnoreParenCasts()->getType().getTypePtrOrNull());
+ auto arg_source_range2 = nice_source_range((*iter2)->IgnoreParenCasts()->getSourceRange(), Rewrite);
+
+ auto iter3 = iter2;
+ iter3++;
+ assert((*iter3)->IgnoreParenCasts()->getType().getTypePtrOrNull());
+ auto arg_source_range3 = nice_source_range((*iter3)->IgnoreParenCasts()->getSourceRange(), Rewrite);
+
+ auto iter4 = iter3;
+ iter4++;
+ assert((*iter4)->IgnoreParenCasts()->getType().getTypePtrOrNull());
+ auto arg_source_range4 = nice_source_range((*iter4)->IgnoreParenCasts()->getSourceRange(), Rewrite);
+
+ std::string arg_source_text1;
+ std::string arg_source_text2;
+ std::string arg_source_text3;
+ std::string arg_source_text4;
+ if (arg_source_range1.isValid() && arg_source_range2.isValid() && arg_source_range3.isValid() && arg_source_range3.isValid() && arg_source_range4.isValid()) {
+ arg_source_text1 = Rewrite.getRewrittenText(arg_source_range1);
+ arg_source_text2 = Rewrite.getRewrittenText(arg_source_range2);
+ arg_source_text3 = Rewrite.getRewrittenText(arg_source_range3);
+ arg_source_text4 = Rewrite.getRewrittenText(arg_source_range4);
+
+ QualType QT;
+ clang::SourceRange decl_source_range;
+ std::string variable_name;
+ const clang::DeclaratorDecl* DD = nullptr;
+ CArrayInferenceInfo res2;
+
+ auto decl = DRE->getDecl();
+ DD = dynamic_cast<const DeclaratorDecl*>(decl);
+ auto VD = dynamic_cast<const VarDecl*>(decl);
+
+ const clang::FieldDecl* FD = nullptr;
+ if (nullptr != ME) {
+ auto member_decl = ME->getMemberDecl();
+ FD = dynamic_cast<const clang::FieldDecl*>(ME->getMemberDecl());
+ }
+ if (nullptr != FD) {
+ DD = FD;
+ } else if (nullptr != VD) {
+ DD = VD;
+ } else {
+ int q = 7;
+ }
+
+ if (nullptr != DD) {
+ 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();
+ auto qtype_str = QT.getAsString();
+ 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;
+ }
+
+ res2 = infer_array_type_info_from_stmt(*(*(CE->arg_begin())), "memset/cpy target", (*this).m_state1, DD);
+
+ if (res2.update_declaration_flag) {
+ update_declaration(*DD, Rewrite, m_state1);
+ }
+ }
+
+ clang::QualType arg1_QT = (*iter1)->IgnoreParenCasts()->getType();
+ if (nullptr != DD) {
+ arg1_QT = QT;
+ }
+ const clang::Type* arg1_TP = arg1_QT.getTypePtr();
+ auto arg1_type_str = arg1_QT.getAsString();
+
+ std::string arg1_element_type_str;
+ if (arg1_TP->isArrayType()) {
+ auto ATP = llvm::cast<const clang::ArrayType>(arg1_TP);
+ assert(nullptr != ATP);
+ auto element_type = ATP->getElementType();
+ auto type_str = element_type.getAsString();
+ if (("char" != type_str) && ("const char" != type_str)) {
+ arg1_element_type_str = type_str;
+ }
+ } else if (arg1_TP->isPointerType()) {
+ auto TPP = llvm::cast<const clang::PointerType>(arg1_TP);
+ assert(nullptr != TPP);
+ auto target_type = TPP->getPointeeType();
+ auto type_str = target_type.getAsString();
+ if (("char" != type_str) && ("const char" != type_str)) {
+ arg1_element_type_str = type_str;
+ }
+ }
+ std::string ce_replacement_code;
+ if (("" != arg1_element_type_str) && ("void" != arg1_element_type_str) && ("const void" != arg1_element_type_str)) {
+ ce_replacement_code = "MSE_LH_FREAD(" + arg_source_text1 + ", " + arg_source_text2
+ + ", "+ arg_source_text3 + ", "+ arg_source_text4 + ")";
+ }
+
+ if (ConvertToSCPP && (CESR.isValid()) && ("" != ce_replacement_code)) {
+ auto cr_shptr = std::make_shared<CExprTextReplacementAction>(Rewrite, MR, CDDeclIndirection(*DD, res2.indirection_level), CE, ce_replacement_code);
+ if ((nullptr != res2.ddecl_conversion_state_ptr)) {
+ if (true || (*(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_array2_contingent_replacement_map.insert(cr_shptr);
+ }
+ } else {
+ (*cr_shptr).do_replacement(m_state1);
+ }
+ } else {
+ int q = 7;
+ }
+
+ int q = 5;
+ } else {
+ int q = 5;
+ }
+ int q = 5;
+ }
+ }
+
+ }
+ }
+ }
+
+private:
+ Rewriter &Rewrite;
+ CState1& m_state1;
+};
+
+class MCSSSFWrite : public MatchFinder::MatchCallback
+{
+public:
+ MCSSSFWrite (Rewriter &Rewrite, CState1& state1) :
+ Rewrite(Rewrite), m_state1(state1) {}
+
+ virtual void run(const MatchFinder::MatchResult &MR)
+ {
+ const CallExpr* CE = MR.Nodes.getNodeAs<clang::CallExpr>("mcsssfwrite1");
+ const DeclRefExpr* DRE = MR.Nodes.getNodeAs<clang::DeclRefExpr>("mcsssfwrite2");
+ const MemberExpr* ME = MR.Nodes.getNodeAs<clang::MemberExpr>("mcsssfwrite3");
+
+ if ((CE != nullptr) && (DRE != nullptr))
+ {
+ auto CESR = nice_source_range(CE->getSourceRange(), Rewrite);
+ SourceLocation CESL = CESR.getBegin();
+ SourceLocation CESLE = CESR.getEnd();
+
+ ASTContext *const ASTC = MR.Context;
+ FullSourceLoc FCESL = ASTC->getFullLoc(CESL);
+
+ SourceManager &SM = ASTC->getSourceManager();
+
+ auto source_location_str = CESL.printToString(*MR.SourceManager);
+ std::string source_text;
+ if (CESL.isValid() && CESLE.isValid()) {
+ source_text = Rewrite.getRewrittenText(SourceRange(CESL, CESLE));
+ } else {
+ return;
+ }
+
+ if (filtered_out_by_location(MR, CESL)) {
+ return void();
+ }
+
+ auto function_decl = CE->getDirectCallee();
+ auto num_args = CE->getNumArgs();
+ if (function_decl && (4 == num_args)) {
+ {
+ std::string function_name = function_decl->getNameAsString();
+ static const std::string fwrite_str = "fwrite";
+ if (fwrite_str == function_name) {
+ auto iter1 = CE->arg_begin();
+ assert((*iter1)->IgnoreParenCasts()->IgnoreParenCasts()->getType().getTypePtrOrNull());
+ auto arg_source_range1 = nice_source_range((*iter1)->IgnoreParenCasts()->getSourceRange(), Rewrite);
+
+ auto iter2 = iter1;
+ iter2++;
+ assert((*iter2)->IgnoreParenCasts()->getType().getTypePtrOrNull());
+ auto arg_source_range2 = nice_source_range((*iter2)->IgnoreParenCasts()->getSourceRange(), Rewrite);
+
+ auto iter3 = iter2;
+ iter3++;
+ assert((*iter3)->IgnoreParenCasts()->getType().getTypePtrOrNull());
+ auto arg_source_range3 = nice_source_range((*iter3)->IgnoreParenCasts()->getSourceRange(), Rewrite);
+
+ auto iter4 = iter3;
+ iter4++;
+ assert((*iter4)->IgnoreParenCasts()->getType().getTypePtrOrNull());
+ auto arg_source_range4 = nice_source_range((*iter4)->IgnoreParenCasts()->getSourceRange(), Rewrite);
+
+ std::string arg_source_text1;
+ std::string arg_source_text2;
+ std::string arg_source_text3;
+ std::string arg_source_text4;
+ if (arg_source_range1.isValid() && arg_source_range2.isValid() && arg_source_range3.isValid() && arg_source_range3.isValid() && arg_source_range4.isValid()) {
+ arg_source_text1 = Rewrite.getRewrittenText(arg_source_range1);
+ arg_source_text2 = Rewrite.getRewrittenText(arg_source_range2);
+ arg_source_text3 = Rewrite.getRewrittenText(arg_source_range3);
+ arg_source_text4 = Rewrite.getRewrittenText(arg_source_range4);
+
+ QualType QT;
+ clang::SourceRange decl_source_range;
+ std::string variable_name;
+ const clang::DeclaratorDecl* DD = nullptr;
+ CArrayInferenceInfo res2;
+
+ auto decl = DRE->getDecl();
+ DD = dynamic_cast<const DeclaratorDecl*>(decl);
+ auto VD = dynamic_cast<const VarDecl*>(decl);
+
+ const clang::FieldDecl* FD = nullptr;
+ if (nullptr != ME) {
+ auto member_decl = ME->getMemberDecl();
+ FD = dynamic_cast<const clang::FieldDecl*>(ME->getMemberDecl());
+ }
+ if (nullptr != FD) {
+ DD = FD;
+ } else if (nullptr != VD) {
+ DD = VD;
+ } else {
+ int q = 7;
+ }
+
+ if (nullptr != DD) {
+ 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();
+ auto qtype_str = QT.getAsString();
+ 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;
+ }
+
+ res2 = infer_array_type_info_from_stmt(*(*(CE->arg_begin())), "memset/cpy target", (*this).m_state1, DD);
+
+ if (res2.update_declaration_flag) {
+ update_declaration(*DD, Rewrite, m_state1);
+ }
+ }
+
+ clang::QualType arg1_QT = (*iter1)->IgnoreParenCasts()->getType();
+ if (nullptr != DD) {
+ arg1_QT = QT;
+ }
+ const clang::Type* arg1_TP = arg1_QT.getTypePtr();
+ auto arg1_type_str = arg1_QT.getAsString();
+
+ std::string arg1_element_type_str;
+ if (arg1_TP->isArrayType()) {
+ auto ATP = llvm::cast<const clang::ArrayType>(arg1_TP);
+ assert(nullptr != ATP);
+ auto element_type = ATP->getElementType();
+ auto type_str = element_type.getAsString();
+ if (("char" != type_str) && ("const char" != type_str)) {
+ arg1_element_type_str = type_str;
+ }
+ } else if (arg1_TP->isPointerType()) {
+ auto TPP = llvm::cast<const clang::PointerType>(arg1_TP);
+ assert(nullptr != TPP);
+ auto target_type = TPP->getPointeeType();
+ auto type_str = target_type.getAsString();
+ if (("char" != type_str) && ("const char" != type_str)) {
+ arg1_element_type_str = type_str;
+ }
+ }
+ std::string ce_replacement_code;
+ if (("" != arg1_element_type_str) && ("void" != arg1_element_type_str) && ("const void" != arg1_element_type_str)) {
+ ce_replacement_code = "MSE_LH_FWRITE(" + arg_source_text1 + ", " + arg_source_text2
+ + ", "+ arg_source_text3 + ", "+ arg_source_text4 + ")";
+ }
+
+ if (ConvertToSCPP && (CESR.isValid()) && ("" != ce_replacement_code)) {
+ auto cr_shptr = std::make_shared<CExprTextReplacementAction>(Rewrite, MR, CDDeclIndirection(*DD, res2.indirection_level), CE, ce_replacement_code);
+ if ((nullptr != res2.ddecl_conversion_state_ptr)) {
+ if (true || (*(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_array2_contingent_replacement_map.insert(cr_shptr);
+ }
+ } else {
+ (*cr_shptr).do_replacement(m_state1);
+ }
+ } else {
+ int q = 7;
+ }
+
+ int q = 5;
+ } else {
+ int q = 5;
+ }
+ int q = 5;
+ }
+ }
+
+ }
+ }
+ }
+
+private:
+ Rewriter &Rewrite;
+ CState1& m_state1;
+};
+
/**********************************************************************************************************************/
class MyASTConsumer : public ASTConsumer {
public:
MyASTConsumer(Rewriter &R) : HandlerForSSSNativePointer(R), HandlerForSSSArrayToPointerDecay(R, m_state1),
HandlerForSSSVarDecl2(R, m_state1), HandlerForSSSPointerArithmetic2(R, m_state1), HandlerForSSSMalloc2(R, m_state1),
- HandlerForSSSMallocInitializer2(R, m_state1), HandlerForSSSFree2(R, m_state1), HandlerForSSSSetToNull2(R, m_state1),
- HandlerForSSSMemset(R, m_state1), HandlerForSSSMemcpy(R, m_state1), HandlerForSSSConditionalInitializer(R, m_state1),
- HandlerForSSSAssignment(R, m_state1), HandlerForSSSParameterPassing(R, m_state1), HandlerForSSSReturnValue(R, m_state1)
+ HandlerForSSSMallocInitializer2(R, m_state1), HandlerForSSSNullInitializer(R, m_state1), HandlerForSSSFree2(R, m_state1),
+ HandlerForSSSSetToNull2(R, m_state1), HandlerForSSSCompareWithNull2(R, m_state1), HandlerForSSSMemset(R, m_state1), HandlerForSSSMemcpy(R, m_state1),
+ HandlerForSSSConditionalInitializer(R, m_state1), HandlerForSSSAssignment(R, m_state1), HandlerForSSSParameterPassing(R, m_state1),
+ HandlerForSSSReturnValue(R, m_state1), HandlerForSSSFRead(R, m_state1), HandlerForSSSFWrite(R, m_state1)
{
Matcher.addMatcher(varDecl(hasType(pointerType())).bind("mcsssnativepointer"), &HandlerForSSSNativePointer);
@@ -4608,6 +5785,12 @@ public:
))).bind("mcsssmallocinitializer3")
)).bind("mcsssmallocinitializer1"), &HandlerForSSSMallocInitializer2);
+ Matcher.addMatcher(declStmt(hasDescendant(
+ varDecl(hasInitializer(ignoringParenCasts(
+ expr().bind("mcsssnullinitializer2")
+ ))).bind("mcsssnullinitializer3")
+ )).bind("mcsssnullinitializer1"), &HandlerForSSSNullInitializer);
+
Matcher.addMatcher(
callExpr(allOf(
hasAnyArgument(ignoringParenCasts(
@@ -4630,6 +5813,15 @@ public:
hasLHS(expr(hasType(pointerType())))
)).bind("mcssssettonull1"), &HandlerForSSSSetToNull2);
+ Matcher.addMatcher(binaryOperator(allOf(
+ anyOf(hasOperatorName("=="), hasOperatorName("!=")),
+ hasLHS(anyOf(
+ ignoringParenCasts(declRefExpr().bind("mcssscomparewithnull3")),
+ ignoringParenCasts(expr(hasDescendant(declRefExpr().bind("mcssscomparewithnull3"))))
+ )),
+ hasLHS(expr(hasType(pointerType())))
+ )).bind("mcssscomparewithnull1"), &HandlerForSSSCompareWithNull2);
+
Matcher.addMatcher(
callExpr(allOf(
hasAnyArgument(
@@ -4666,8 +5858,12 @@ public:
)).bind("mcsssconditionalinitializer1"), &HandlerForSSSConditionalInitializer);
Matcher.addMatcher(binaryOperator(allOf(
- hasOperatorName("="),
- hasLHS(hasDescendant(declRefExpr().bind("mcsssassignment2"))),
+ anyOf(hasOperatorName("="), hasOperatorName("=="), hasOperatorName("!="),
+ hasOperatorName("<"), hasOperatorName(">"), hasOperatorName("<="), hasOperatorName(">=")),
+ hasLHS(anyOf(
+ hasDescendant(declRefExpr().bind("mcsssassignment2")),
+ declRefExpr().bind("mcsssassignment2")
+ )),
hasRHS(anyOf(
cStyleCastExpr(hasDescendant(declRefExpr().bind("mcsssassignment3"))).bind("mcsssassignment4"),
expr(hasDescendant(declRefExpr().bind("mcsssassignment3")))
@@ -4698,6 +5894,32 @@ public:
hasDescendant(declRefExpr().bind("mcsssreturnvalue3"))
)).bind("mcsssreturnvalue2"), &HandlerForSSSReturnValue);
+ Matcher.addMatcher(
+ callExpr(allOf(
+ hasAnyArgument(
+ ignoringParenCasts(expr(anyOf(
+ memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssfread2")))).bind("mcsssfread3"),
+ declRefExpr().bind("mcsssfread2"),
+ hasDescendant(memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssfread2")))).bind("mcsssfread3")),
+ hasDescendant(declRefExpr().bind("mcsssfread2"))
+ )))),
+ argumentCountIs(4),
+ hasAnyArgument(hasType(pointerType()))
+ )).bind("mcsssfread1"), &HandlerForSSSFRead);
+
+ Matcher.addMatcher(
+ callExpr(allOf(
+ hasAnyArgument(
+ ignoringParenCasts(expr(anyOf(
+ memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssfwrite2")))).bind("mcsssfwrite3"),
+ declRefExpr().bind("mcsssfwrite2"),
+ hasDescendant(memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssfwrite2")))).bind("mcsssfwrite3")),
+ hasDescendant(declRefExpr().bind("mcsssfwrite2"))
+ )))),
+ argumentCountIs(4),
+ hasAnyArgument(hasType(pointerType()))
+ )).bind("mcsssfwrite1"), &HandlerForSSSFWrite);
+
}
void HandleTranslationUnit(ASTContext &Context) override
@@ -4715,14 +5937,18 @@ private:
MCSSSPointerArithmetic2 HandlerForSSSPointerArithmetic2;
MCSSSMalloc2 HandlerForSSSMalloc2;
MCSSSMallocInitializer2 HandlerForSSSMallocInitializer2;
+ MCSSSNullInitializer HandlerForSSSNullInitializer;
MCSSSFree2 HandlerForSSSFree2;
MCSSSSetToNull2 HandlerForSSSSetToNull2;
+ MCSSSCompareWithNull2 HandlerForSSSCompareWithNull2;
MCSSSMemset HandlerForSSSMemset;
MCSSSMemcpy HandlerForSSSMemcpy;
MCSSSConditionalInitializer HandlerForSSSConditionalInitializer;
MCSSSAssignment HandlerForSSSAssignment;
MCSSSParameterPassing HandlerForSSSParameterPassing;
MCSSSReturnValue HandlerForSSSReturnValue;
+ MCSSSFRead HandlerForSSSFRead;
+ MCSSSFWrite HandlerForSSSFWrite;
MatchFinder Matcher;
};