aboutsummaryrefslogtreecommitdiffstats
path: root/safercpp
diff options
context:
space:
mode:
authoruser1 <user1@ubuntu>2017-03-27 15:29:23 +0000
committeruser1 <user1@ubuntu>2017-03-27 15:29:23 +0000
commit961a09092f6055c08dfab936a83643d15966870a (patch)
tree2b8a7ca34d1c1b6aa7c2f3508fab426ef41347ec /safercpp
parentmoved macros inside macros.mk (diff)
downloadmutator-961a09092f6055c08dfab936a83643d15966870a.tar.gz
mutator-961a09092f6055c08dfab936a83643d15966870a.zip
preliminary auto-conversion of native arrays
Diffstat (limited to '')
-rw-r--r--safercpp/safercpp-arr.cpp2121
1 files changed, 2120 insertions, 1 deletions
diff --git a/safercpp/safercpp-arr.cpp b/safercpp/safercpp-arr.cpp
index f040144..969e551 100644
--- a/safercpp/safercpp-arr.cpp
+++ b/safercpp/safercpp-arr.cpp
@@ -28,6 +28,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*
/*Standard headers*/
#include <string>
#include <iostream>
+#include <string>
+#include <vector>
+#include <map>
+#include <algorithm>
+#include <locale>
/*Clang Headers*/
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
@@ -51,13 +56,2114 @@ using namespace clang::driver;
using namespace clang::tooling;
/**********************************************************************************************************************/
static llvm::cl::OptionCategory MatcherSampleCategory("TBD");
+
+cl::opt<bool> CheckSystemHeader("SysHeader", cl::desc("safercpp will run through System Headers"), cl::init(false), cl::cat(MatcherSampleCategory), cl::ZeroOrMore);
+cl::opt<bool> MainFileOnly("MainOnly", cl::desc("safercpp will only report the results that reside in the main file"), cl::init(false), cl::cat(MatcherSampleCategory), cl::ZeroOrMore);
+cl::opt<bool> SafeSubset("SafeSubset", cl::desc("safercpp will check for elements outside of the (memory) safe subset of the language"), cl::init(true), cl::cat(MatcherSampleCategory), cl::ZeroOrMore);
+cl::opt<bool> ConvertToSCPP("ConvertToSCPP", cl::desc("safercpp will translate the source to a (memory) safe subset of the language"), cl::init(false), cl::cat(MatcherSampleCategory), cl::ZeroOrMore);
+/**********************************************************************************************************************/
+
+static std::string with_whitespace_removed(const std::string& str) {
+ std::string retval = str;
+ retval.erase(std::remove_if(retval.begin(), retval.end(), isspace), retval.end());
+ return retval;
+}
+
+static std::string with_newlines_removed(const std::string& str) {
+ std::string retval = str;
+ auto riter1 = retval.rbegin();
+ while (retval.rend() != riter1) {
+ if ('\n' == *riter1) {
+ auto riter2 = riter1;
+ riter2++;
+ retval.erase(riter1.base()--);
+ while (retval.rend() != riter2) {
+ /* look for and remove 'continued on the next line' backslash if present. */
+ if ('\\' == (*riter2)) {
+ riter1++;
+ retval.erase(riter2.base()--);
+ break;
+ } else if (!std::isspace(*riter2)) {
+ break;
+ }
+
+ riter2++;
+ }
+ }
+
+ riter1++;
+ }
+
+ return retval;
+}
+
+static std::vector<std::string> f_declared_object_strings(const std::string& decl_stmt_str) {
+ std::vector<std::string> retval;
+
+ auto nice_decl_stmt_str = with_newlines_removed(decl_stmt_str);
+ auto semicolon_position = std::string::npos;
+ for (size_t pos = 3; pos < nice_decl_stmt_str.size(); pos += 1) {
+ if (';' == nice_decl_stmt_str[pos]) {
+ semicolon_position = pos;
+ }
+ }
+ if (std::string::npos == semicolon_position) {
+ assert(false);
+ return retval;
+ }
+
+ std::vector<size_t> delimiter_positions;
+ for (size_t pos = 3; ((pos < nice_decl_stmt_str.size()) && (pos < semicolon_position)); pos += 1) {
+ if (',' == nice_decl_stmt_str[pos]) {
+ delimiter_positions.push_back(pos);
+ }
+ }
+
+ delimiter_positions.push_back(semicolon_position);
+ auto first_delimiter_pos = delimiter_positions[0];
+
+ {
+ auto pos1 = first_delimiter_pos - 1;
+ auto pos2 = pos1;
+ bool nonspace_found = false;
+ while ((2 <= pos1) && (!nonspace_found)) {
+ if (!std::isspace(nice_decl_stmt_str[pos1])) {
+ pos2 = pos1 + 1;
+ nonspace_found = true;
+ }
+
+ pos1 -= 1;
+ }
+ if (!nonspace_found) {
+ assert(false);
+ return retval;
+ }
+
+ bool space_found = false;
+ while ((1 <= pos1) && (!space_found)) {
+ if (std::isspace(nice_decl_stmt_str[pos1])) {
+ space_found = true;
+ }
+
+ pos1 -= 1;
+ }
+ if (!space_found) {
+ assert(false);
+ return retval;
+ }
+
+ pos1 += 2;
+ std::string first_declaration_string = nice_decl_stmt_str.substr(pos1, pos2 - pos1);
+ retval.push_back(first_declaration_string);
+ }
+
+ {
+ size_t delimiter_index = 0;
+ while (delimiter_positions.size() > (delimiter_index + 1)) {
+ if (!(delimiter_positions[delimiter_index] + 1 < delimiter_positions[(delimiter_index + 1)])) {
+ //assert(false);
+ } else {
+ std::string declaration_string = nice_decl_stmt_str.substr(delimiter_positions[delimiter_index] + 1, delimiter_positions[(delimiter_index + 1)] - (delimiter_positions[delimiter_index] + 1));
+ retval.push_back(declaration_string);
+ }
+
+ delimiter_index += 1;
+ }
+ }
+
+ return retval;
+}
+
+class CDeclReplacementActionRecord {
+public:
+ CDeclReplacementActionRecord(Rewriter &Rewrite, const clang::DeclaratorDecl& ddecl, const std::string& replacement_text
+ , const std::string& action_species)
+ : m_Rewrite_ptr(&Rewrite), m_ddecl_cptr(&ddecl), m_replacement_text(replacement_text), m_action_species(action_species) {
+ }
+ virtual ~CDeclReplacementActionRecord() {}
+ clang::SourceRange source_range() {
+ clang::SourceRange retval = m_ddecl_cptr->getSourceRange();
+ return retval;
+ }
+ clang::SourceLocation start_location() {
+ clang::SourceLocation retval = source_range().getBegin();
+ return retval;
+ }
+ std::string get_var_name() {
+ std::string retval = m_ddecl_cptr->getNameAsString();
+ return retval;
+ }
+ const clang::DeclaratorDecl* get_ddecl_cptr() { return m_ddecl_cptr; }
+ std::string replacement_text() { return m_replacement_text; }
+ std::string action_species() { return m_action_species; }
+
+ Rewriter* m_Rewrite_ptr = nullptr;
+ const clang::DeclaratorDecl* m_ddecl_cptr = nullptr;
+ std::string m_replacement_text;
+ std::string m_action_species;
+};
+
+class CDeclReplacementActionRecordsLog : public std::vector<CDeclReplacementActionRecord> {
+public:
+ CDeclReplacementActionRecordsLog::iterator find(const clang::DeclaratorDecl* ddecl_cptr) {
+ CDeclReplacementActionRecordsLog::iterator retval = (*this).end();
+ CDeclReplacementActionRecordsLog::iterator iter = (*this).begin();
+ for (CDeclReplacementActionRecordsLog::iterator iter = (*this).begin(); (*this).end() != iter; iter++) {
+ if ((*iter).get_ddecl_cptr() == ddecl_cptr) {
+ retval = iter;
+ break;
+ }
+ }
+ return retval;
+ }
+ CDeclReplacementActionRecordsLog::iterator find(const clang::SourceLocation& start_location) {
+ CDeclReplacementActionRecordsLog::iterator retval = (*this).end();
+ for (CDeclReplacementActionRecordsLog::iterator iter = (*this).begin(); (*this).end() != iter; iter++) {
+ auto l_sl = (*iter).start_location();
+ if ((start_location.isValid()) && (l_sl.isValid()) && (start_location == l_sl)) {
+ retval = iter;
+ break;
+ }
+ }
+ return retval;
+ }
+};
+
+class CReplacementAction {
+public:
+ virtual ~CReplacementAction() {}
+ virtual void do_replacement() const = 0;
+};
+
+class CDDeclReplacementAction : public CReplacementAction {
+public:
+ CDDeclReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR,
+ const clang::DeclaratorDecl& ddecl) : m_Rewrite(Rewrite), m_MR(MR), m_ddecl_cptr(&ddecl) {
+ }
+ virtual ~CDDeclReplacementAction() {}
+
+ virtual void do_replacement() const = 0;
+ virtual const clang::DeclaratorDecl* get_ddecl_cptr() const { return m_ddecl_cptr; }
+
+ clang::SourceRange source_range() {
+ clang::SourceRange retval = m_ddecl_cptr->getSourceRange();
+ return retval;
+ }
+ clang::SourceLocation start_location() {
+ clang::SourceLocation retval = source_range().getBegin();
+ return retval;
+ }
+ std::string get_var_name() {
+ std::string retval = m_ddecl_cptr->getNameAsString();
+ return retval;
+ }
+
+ Rewriter& m_Rewrite;
+ const MatchFinder::MatchResult m_MR;
+ const clang::DeclaratorDecl* m_ddecl_cptr = nullptr;
+};
+
+class CDynamicArrayReplacementAction : public CDDeclReplacementAction {
+public:
+ using CDDeclReplacementAction::CDDeclReplacementAction;
+ virtual ~CDynamicArrayReplacementAction() {}
+};
+
+class CSetArrayPointerToNullReplacementAction : public CDynamicArrayReplacementAction {
+public:
+ CSetArrayPointerToNullReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const clang::DeclaratorDecl& ddecl,
+ const BinaryOperator* BO, const DeclRefExpr* DRE, const MemberExpr* ME)
+ : CDynamicArrayReplacementAction(Rewrite, MR, ddecl), m_BO(BO), m_DRE(DRE), m_ME(ME) {
+ }
+ virtual ~CSetArrayPointerToNullReplacementAction() {}
+
+ virtual void do_replacement() const {
+ Rewriter &Rewrite = m_Rewrite;
+ const MatchFinder::MatchResult &MR = m_MR;
+ const BinaryOperator* BO = m_BO;
+ const Expr* RHS = nullptr;
+ const Expr* LHS = nullptr;
+ if (BO != nullptr) {
+ RHS = BO->getRHS();
+ LHS = BO->getLHS();
+ }
+ const DeclRefExpr* DRE = m_DRE;
+ const MemberExpr* ME = m_ME;
+
+ if ((BO != nullptr) && (RHS != nullptr) && (LHS != nullptr) && (DRE != nullptr))
+ {
+ SourceLocation BOSL = BO->getLocStart();
+ SourceLocation BOSLMID;
+
+ if (BOSL.isMacroID())
+ {
+ BOSLMID = Devi::SourceLocationHasMacro(BOSL, Rewrite, "start");
+ }
+
+ BOSL = Devi::SourceLocationHasMacro(BOSL, Rewrite, "start");
+ SourceLocation BOSLE = BO->getLocEnd();
+ SourceLocation BOSLEMID;
+
+ if (BOSLE.isMacroID())
+ {
+ BOSLEMID = Devi::SourceLocationHasMacro(BOSLE, Rewrite, "end");
+ }
+
+ BOSLE = Devi::SourceLocationHasMacro(BOSLE, Rewrite, "end");
+
+ 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 (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, BOSL))
+ {
+ return void();
+ }
+
+ if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, BOSL))
+ {
+ return void();
+ }
+
+ Expr::NullPointerConstantKind kind = RHS->isNullPointerConstant(*ASTC, Expr::NullPointerConstantValueDependence());
+ if (clang::Expr::NPCK_NotNull != kind) {
+ auto lhs_source_range = LHS->getSourceRange();
+ 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);
+
+ QualType QT;
+ std::string element_type_str;
+ clang::SourceRange decl_source_range;
+ std::string variable_name;
+ std::string bo_replacement_code;
+ const clang::DeclaratorDecl* DD = nullptr;
+
+ auto decl = DRE->getDecl();
+ 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;
+
+ auto field_decl_source_range = FD->getSourceRange();
+ auto field_decl_source_location_str = field_decl_source_range.getBegin().printToString(*MR.SourceManager);
+ std::string field_decl_source_text;
+ if (field_decl_source_range.isValid()) {
+ field_decl_source_text = Rewrite.getRewrittenText(field_decl_source_range);
+ decl_source_range = field_decl_source_range;
+ } else {
+ return;
+ }
+ QT = FD->getType();
+ variable_name = FD->getNameAsString();
+ } else if (nullptr != VD) {
+ DD = VD;
+ SourceLocation VDSL = VD->getLocStart();
+ VDSL = Devi::SourceLocationHasMacro(VDSL, Rewrite, "start");
+ SourceLocation VDSLE = VD->getLocEnd();
+ VDSLE = Devi::SourceLocationHasMacro(VDSLE, Rewrite, "end");
+ decl_source_range = clang::SourceRange(VDSL, VDSLE);
+
+ auto qualified_name = VD->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;
+ }
+
+ QT = VD->getType();
+ variable_name = VD->getNameAsString();
+ } else {
+ int q = 7;
+ }
+
+ if (nullptr != DD) {
+ if (true) {
+ if (true) {
+ bo_replacement_code = lhs_source_text;
+ bo_replacement_code += ".resize(0)";
+
+ auto BOSR = clang::SourceRange(BOSL, BOSLE);
+ if (ConvertToSCPP && (BOSR.isValid())) {
+ auto res2 = Rewrite.ReplaceText(BOSR, bo_replacement_code);
+ int q = 3;
+ } else {
+ int q = 7;
+ }
+ } else {
+ int q = 5;
+ }
+ }
+ }
+ int q = 5;
+ } else {
+ int q = 5;
+ }
+ int q = 5;
+ }
+ }
+ }
+
+ const BinaryOperator* m_BO;
+ const DeclRefExpr* m_DRE;
+ const MemberExpr* m_ME;
+};
+
+std::string tolowerstr(const std::string& a) {
+ std::string retval;
+ for (const auto& ch : a) {
+ retval += tolower(ch);
+ }
+ return retval;
+}
+
+class CFreeDynamicArrayReplacementAction : public CDynamicArrayReplacementAction {
+public:
+ CFreeDynamicArrayReplacementAction(Rewriter &Rewrite, const MatchFinder::MatchResult &MR, const clang::DeclaratorDecl& ddecl,
+ const CallExpr* CE, const DeclRefExpr* DRE, const MemberExpr* ME)
+ : CDynamicArrayReplacementAction(Rewrite, MR, ddecl), m_CE(CE), m_DRE(DRE), m_ME(ME) {
+ }
+ virtual ~CFreeDynamicArrayReplacementAction() {}
+
+ virtual void do_replacement() const {
+ Rewriter &Rewrite = m_Rewrite;
+ const MatchFinder::MatchResult &MR = m_MR;
+ const CallExpr* CE = m_CE;
+ const DeclRefExpr* DRE = m_DRE;
+ const MemberExpr* ME = m_ME;
+
+ if ((CE != nullptr) && (DRE != nullptr))
+ {
+ SourceLocation CESL = CE->getLocStart();
+ SourceLocation CESLMID;
+
+ if (CESL.isMacroID())
+ {
+ CESLMID = Devi::SourceLocationHasMacro(CESL, Rewrite, "start");
+ }
+
+ CESL = Devi::SourceLocationHasMacro(CESL, Rewrite, "start");
+ SourceLocation CESLE = CE->getLocEnd();
+ SourceLocation CESLEMID;
+
+ if (CESLE.isMacroID())
+ {
+ CESLEMID = Devi::SourceLocationHasMacro(CESLE, Rewrite, "end");
+ }
+
+ CESLE = Devi::SourceLocationHasMacro(CESLE, Rewrite, "end");
+
+ 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 (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, CESL))
+ {
+ return void();
+ }
+
+ if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, CESL))
+ {
+ return void();
+ }
+
+ auto function_decl = CE->getDirectCallee();
+ auto num_args = CE->getNumArgs();
+ if (function_decl && (1 == num_args)) {
+ {
+ std::string function_name = function_decl->getNameAsString();
+ static const std::string free_str = "free";
+ auto lc_function_name = tolowerstr(function_name);
+ bool ends_with_free = ((lc_function_name.size() >= free_str.size())
+ && (0 == lc_function_name.compare(lc_function_name.size() - free_str.size(), free_str.size(), free_str)));
+ if (ends_with_free) {
+ auto iter = CE->arg_begin();
+ assert((*iter)->getType().getTypePtrOrNull());
+ auto arg_source_range = (*iter)->getSourceRange();
+ std::string arg_source_text;
+ if (arg_source_range.isValid()) {
+ arg_source_text = Rewrite.getRewrittenText(arg_source_range);
+ //auto arg_source_text_sans_ws = with_whitespace_removed(arg_source_text);
+ QualType QT;
+ std::string element_type_str;
+ clang::SourceRange decl_source_range;
+ std::string variable_name;
+ std::string ce_replacement_code;
+ const clang::DeclaratorDecl* DD = nullptr;
+
+ auto decl = DRE->getDecl();
+ DD = dynamic_cast<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 = DD->getSourceRange();
+ 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;
+ }
+
+ if (true) {
+ ce_replacement_code = arg_source_text;
+ ce_replacement_code += ".resize(0)";
+
+ auto CESR = clang::SourceRange(CESL, CESLE);
+ if (ConvertToSCPP && (CESR.isValid())) {
+ auto res2 = Rewrite.ReplaceText(CESR, ce_replacement_code);
+ int q = 3;
+ } else {
+ int q = 7;
+ }
+ }
+ }
+ int q = 5;
+ } else {
+ int q = 5;
+ }
+ int q = 5;
+ }
+ }
+
+ }
+ }
+ }
+
+ const CallExpr* m_CE;
+ const DeclRefExpr* m_DRE;
+ const MemberExpr* m_ME;
+};
+
+class CDynamicArrayReplacementActionMap : public std::multimap<const clang::DeclaratorDecl*, std::shared_ptr<CDynamicArrayReplacementAction>> {
+public:
+ typedef std::multimap<const clang::DeclaratorDecl*, std::shared_ptr<CDynamicArrayReplacementAction>> base_class;
+ iterator insert( const std::shared_ptr<CDynamicArrayReplacementAction>& cr_shptr ) {
+ iterator retval(end());
+ if (!cr_shptr) { assert(false); } else {
+ value_type val((*cr_shptr).get_ddecl_cptr(), cr_shptr);
+ retval = base_class::insert(val);
+ }
+ return retval;
+ }
+ void do_and_dispose_matching_replacements(const clang::DeclaratorDecl& ddecl) {
+ auto DD = &ddecl;
+ auto range = base_class::equal_range(DD);
+ while (range.first != range.second) {
+ for (auto iter = range.first; range.second != iter; iter++) {
+ (*((*iter).second)).do_replacement();
+ }
+ base_class::erase(range.first, range.second);
+ range = base_class::equal_range(DD);
+ }
+ }
+};
+
+class CState1 {
+public:
+ CDeclReplacementActionRecordsLog m_decl_replacement_action_records_log;
+ CDynamicArrayReplacementActionMap m_dynamic_array_contingent_replacement_map;
+};
+
+/**********************************************************************************************************************/
+class MCSSSArrayToPointerDecay : public MatchFinder::MatchCallback
+{
+public:
+ MCSSSArrayToPointerDecay (Rewriter &Rewrite, CState1& state1)
+ : Rewrite(Rewrite), m_state1(state1) {}
+
+ virtual void run(const MatchFinder::MatchResult &MR)
+ {
+ if (/*SafeSubset && */(MR.Nodes.getNodeAs<clang::CastExpr>("mcsssarraytopointerdecay") != nullptr))
+ {
+ const CastExpr* CE = MR.Nodes.getNodeAs<clang::CastExpr>("mcsssarraytopointerdecay");
+
+ SourceLocation SL = CE->getLocStart();
+ SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start");
+ SourceLocation SLE = CE->getLocEnd();
+ SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end");
+
+ ASTContext *const ASTC = MR.Context;
+ FullSourceLoc FSL = ASTC->getFullLoc(SL);
+
+ auto source_location_str = SL.printToString(*MR.SourceManager);
+ std::string source_text;
+ if (SL.isValid() && SLE.isValid()) {
+ source_text = Rewrite.getRewrittenText(SourceRange(SL, SLE));
+ } else {
+ return;
+ }
+
+ if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL))
+ {
+ /*intentionally left blank*/
+ }
+ else
+ {
+ if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL))
+ {
+ if (true) {
+ std::cout << "sss1.2:" << "array to pointer decay:";
+ std::cout << SL.printToString(*MR.SourceManager) << ":" << std::endl;
+
+ //XMLDocOut.XMLAddNode(MR.Context, SL, "sss1.2", "array to pointer decay: ");
+ //JSONDocOUT.JSONAddElement(MR.Context, SL, "sss1.2", "array to pointer decay: ");
+ }
+ }
+ }
+ }
+ }
+
+private:
+ Rewriter &Rewrite;
+ CState1& m_state1;
+};
+/**********************************************************************************************************************/
+class MCSSSNativePointer : public MatchFinder::MatchCallback
+{
+public:
+ MCSSSNativePointer (Rewriter &Rewrite) : Rewrite(Rewrite) {}
+
+ virtual void run(const MatchFinder::MatchResult &MR)
+ {
+ if (SafeSubset && (MR.Nodes.getNodeAs<clang::VarDecl>("mcsssnativepointer") != nullptr))
+ {
+ const VarDecl *VD = MR.Nodes.getNodeAs<clang::VarDecl>("mcsssnativepointer");
+
+ SourceLocation SL = VD->getLocStart();
+ SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start");
+ SourceLocation SE = VD->getLocEnd();
+ SE = Devi::SourceLocationHasMacro(SE, Rewrite, "end");
+
+ ASTContext* const ASTC = MR.Context;
+ FullSourceLoc FSL = ASTC->getFullLoc(SL);
+
+ auto source_location_str = SL.printToString(*MR.SourceManager);
+ std::string source_text;
+ if (SL.isValid() && SE.isValid()) {
+ source_text = Rewrite.getRewrittenText(SourceRange(SL, SE));
+ } else {
+ return;
+ }
+
+ if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL))
+ {
+ /*intentionally left blank*/
+ }
+ else
+ {
+ if (Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL))
+ {
+ if (SafeSubset) {
+ std::cout << "sss1.1:" << "native pointer:";
+ std::cout << SL.printToString(*MR.SourceManager) << ":" << std::endl;
+
+ //XMLDocOut.XMLAddNode(MR.Context, SL, "sss1.1", "native pointer: ");
+ //JSONDocOUT.JSONAddElement(MR.Context, SL, "sss1.1", "native pointer: ");
+ }
+ }
+ }
+ }
+ }
+
+ virtual void onEndOfTranslationUnit()
+ {
+ }
+
+private:
+ Rewriter &Rewrite;
+};
+/**********************************************************************************************************************/
+class MCSSSVarDecl : public MatchFinder::MatchCallback
+{
+public:
+ MCSSSVarDecl (Rewriter &Rewrite, CState1& state1)
+ : Rewrite(Rewrite), m_state1(state1) {}
+
+ virtual void run(const MatchFinder::MatchResult &MR)
+ {
+ if ((MR.Nodes.getNodeAs<clang::VarDecl>("mcsssvardecl") != nullptr))
+ {
+ const VarDecl* VD = MR.Nodes.getNodeAs<clang::VarDecl>("mcsssvardecl");
+
+ SourceLocation SL = VD->getLocStart();
+ SourceLocation SLMID;
+
+ if (SL.isMacroID())
+ {
+ SLMID = Devi::SourceLocationHasMacro(SL, Rewrite, "start");
+ }
+
+ SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start");
+ SourceLocation SLE = VD->getLocEnd();
+ SourceLocation SLEMID;
+
+ if (SLE.isMacroID())
+ {
+ SLEMID = Devi::SourceLocationHasMacro(SLE, Rewrite, "end");
+ }
+
+ SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end");
+
+ QualType QT = VD->getType();
+
+ const clang::Type* TP = QT.getTypePtr();
+
+ ASTContext *const ASTC = MR.Context;
+ FullSourceLoc FSL = ASTC->getFullLoc(SL);
+
+ SourceManager &SM = ASTC->getSourceManager();
+
+ auto source_location_str = SL.printToString(*MR.SourceManager);
+ std::string source_text;
+ if (SL.isValid() && SLE.isValid()) {
+ source_text = Rewrite.getRewrittenText(SourceRange(SL, SLE));
+ } else {
+ return;
+ }
+
+ auto storage_duration = VD->getStorageDuration();
+ bool has_dynamic_storage_duration = (clang::StorageDuration::SD_Dynamic == storage_duration);
+ bool is_a_temporary = (clang::StorageDuration::SD_FullExpression == storage_duration);
+ bool is_static = (clang::StorageDuration::SD_Static == storage_duration);
+ bool is_a_function_parameter = (VD->isLocalVarDeclOrParm() && (!VD->isLocalVarDecl()));
+
+ auto variable_name = VD->getName();
+ auto variable_name2 = VD->getNameAsString();
+ std::string identifier_name_str;
+ auto pIdentifier = VD->getIdentifier();
+ if (pIdentifier) {
+ identifier_name_str = pIdentifier->getName();
+ }
+
+ std::string initialization_expr_str;
+ auto pInitExpr = VD->getInit();
+ if (VD->hasInit() && pInitExpr) {
+ auto init_expr_source_range = pInitExpr->getSourceRange();
+ initialization_expr_str = Rewrite.getRewrittenText(init_expr_source_range);
+ }
+
+ if (TP->isArrayType()) {
+ auto ATP = static_cast<const clang::ArrayType*>(TP);
+ auto element_type = ATP->getElementType();
+ auto elementSplitQualType = element_type.split();
+ auto element_type_str = clang::QualType::getAsString(elementSplitQualType);
+
+ std::string replacement_code;
+ if (is_static) {
+ replacement_code += "static ";
+ }
+ replacement_code += "mse::mstd::array<";
+ replacement_code += element_type_str;
+ replacement_code += ", ";
+
+ if (TP->isConstantArrayType()) {
+ auto CATP = static_cast<const clang::ConstantArrayType*>(TP);
+ if (!CATP) {
+ assert(false);
+ } else {
+ auto array_size = CATP->getSize();
+
+ 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));
+
+ replacement_code += array_size_expression_text;
+ int q = 3;
+ } else {
+ int q = 7;
+ }
+ int q = 5;
+ }
+ } else if (TP->isVariableArrayType()) {
+ auto VATP = static_cast<const clang::VariableArrayType*>(TP);
+ if (!VATP) {
+ assert(false);
+ } else {
+ auto size_expr = VATP->getSizeExpr();
+ }
+ }
+
+ replacement_code += "> ";
+ std::string new_array_variable_name = variable_name;
+ new_array_variable_name += "_array";
+ replacement_code += new_array_variable_name;
+ if ("" != initialization_expr_str) {
+ replacement_code += " = ";
+ replacement_code += initialization_expr_str;
+ }
+ replacement_code += "; \n";
+ if (is_static) {
+ replacement_code += "static ";
+ }
+ replacement_code += "auto ";
+ replacement_code += variable_name;
+ replacement_code += " = ";
+ replacement_code += new_array_variable_name;
+ replacement_code += ".begin()";
+ if (ConvertToSCPP && SL.isValid() && SLE.isValid()) {
+ auto res = Rewrite.ReplaceText(SourceRange(SL, SLE), replacement_code);
+ CDeclReplacementActionRecord action_record(Rewrite, *VD, replacement_code, "native to mse array");
+ m_state1.m_decl_replacement_action_records_log.push_back(action_record);
+ m_state1.m_dynamic_array_contingent_replacement_map.do_and_dispose_matching_replacements(*VD);
+ int q = 3;
+ } else {
+ int q = 7;
+ }
+ m_state1.m_dynamic_array_contingent_replacement_map.do_and_dispose_matching_replacements(*VD);
+ int q = 5;
+ } else {
+ ;
+ }
+
+ }
+ }
+
+ virtual void onEndOfTranslationUnit()
+ {
+ }
+
+private:
+ Rewriter &Rewrite;
+ CState1& m_state1;
+};
+
+/**********************************************************************************************************************/
+class CRandomAccessIteratorFromPointerDDeclRetval {
+public:
+ std::string m_replacement_code;
+ std::string m_action_species;
+};
+static CRandomAccessIteratorFromPointerDDeclRetval RandomAccessIteratorFromPointerDDecl(const DeclaratorDecl* DD, Rewriter &Rewrite) {
+ CRandomAccessIteratorFromPointerDDeclRetval retval;
+
+ QualType QT = DD->getType();
+
+ const clang::Type* TP = QT.getTypePtr();
+
+ clang::StorageDuration storage_duration = clang::StorageDuration::SD_Automatic;
+ bool has_dynamic_storage_duration = false;
+ bool is_a_temporary = false;
+ bool is_static = false;
+ bool is_a_function_parameter = false;
+ std::string initialization_expr_str;
+
+ auto VD = dynamic_cast<const clang::VarDecl *>(DD);
+ if (VD) {
+ storage_duration = VD->getStorageDuration();
+ has_dynamic_storage_duration = (clang::StorageDuration::SD_Dynamic == storage_duration);
+ is_a_temporary = (clang::StorageDuration::SD_FullExpression == storage_duration);
+ is_static = (clang::StorageDuration::SD_Static == storage_duration);
+ is_a_function_parameter = (VD->isLocalVarDeclOrParm() && (!VD->isLocalVarDecl()));
+
+ auto pInitExpr = VD->getInit();
+ if (VD->hasInit() && pInitExpr) {
+ auto init_expr_source_range = pInitExpr->getSourceRange();
+ initialization_expr_str = Rewrite.getRewrittenText(init_expr_source_range);
+ }
+ }
+
+ auto variable_name = DD->getNameAsString();
+ std::string identifier_name_str;
+ auto pIdentifier = DD->getIdentifier();
+ if (pIdentifier) {
+ identifier_name_str = pIdentifier->getName();
+ }
+
+ bool replacement_code_generated = false;
+ if (TP->isPointerType()) {
+ auto TPP = static_cast<const clang::PointerType*>(TP);
+ if (TPP) {
+ auto target_type = TPP->getPointeeType();
+
+ auto splitQualType = target_type.split();
+ auto type_str = clang::QualType::getAsString(splitQualType);
+
+ if (("char" != type_str) && ("const char" != type_str)) {
+ std::string replacement_code;
+ if (is_static) {
+ replacement_code += "static ";
+ }
+ replacement_code += "mse::TAnyRandomAccessIterator<";
+ replacement_code += type_str;
+ replacement_code += "> ";
+ replacement_code += variable_name;
+
+ if ("" != initialization_expr_str) {
+ replacement_code += " = ";
+ replacement_code += initialization_expr_str;
+ }
+ retval.m_replacement_code = replacement_code;
+ retval.m_action_species = "pointer to random access iterator";
+ replacement_code_generated = true;
+ } else {
+ int q = 3;
+ }
+ } else {
+ assert(false);
+ int q = 1;
+ }
+ }
+
+ if (!replacement_code_generated) {
+ auto splitQualType = QT.split();
+ auto type_str = clang::QualType::getAsString(splitQualType);
+
+ std::string replacement_code;
+ if (is_static) {
+ replacement_code += "static ";
+ }
+ replacement_code += type_str;
+ replacement_code += " ";
+ replacement_code += variable_name;
+
+ if ("" != initialization_expr_str) {
+ replacement_code += " = ";
+ replacement_code += initialization_expr_str;
+ }
+ retval.m_replacement_code = replacement_code;
+ retval.m_action_species = "char*";
+ replacement_code_generated = true;
+ }
+ return retval;
+}
+
+static std::vector<const DeclaratorDecl*> IndividualDeclaratorDecls(const DeclaratorDecl* VD, Rewriter &Rewrite) {
+ std::vector<const DeclaratorDecl*> retval;
+
+ if (!VD) {
+ assert(false);
+ return retval;
+ }
+ SourceLocation SL = VD->getLocStart();
+ SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start");
+
+ auto decl_context = VD->getDeclContext();
+ if ((!decl_context) || (!SL.isValid())) {
+ assert(false);
+ retval.push_back(VD);
+ } else {
+ for (auto decl_iter = decl_context->decls_begin(); decl_iter != decl_context->decls_end(); decl_iter++) {
+ auto decl = (*decl_iter);
+ auto var_decl = dynamic_cast<const DeclaratorDecl*>(decl);
+ if (var_decl) {
+ SourceLocation l_SL = var_decl->getLocStart();
+ l_SL = Devi::SourceLocationHasMacro(l_SL, Rewrite, "start");
+ if (l_SL == SL) {
+ retval.push_back(var_decl);
+ }
+ }
+ }
+ }
+ if (0 == retval.size()) {
+ assert(false);
+ }
+
+ return retval;
+}
+
+class MCSSSPointerArithmetic : public MatchFinder::MatchCallback
+{
+public:
+ MCSSSPointerArithmetic (Rewriter &Rewrite, CState1& state1)
+ : Rewrite(Rewrite), m_state1(state1) {}
+
+ virtual void run(const MatchFinder::MatchResult &MR)
+ {
+ const DeclRefExpr* DRE = MR.Nodes.getNodeAs<clang::DeclRefExpr>("mcssspointerarithmetic");
+ const MemberExpr* ME = MR.Nodes.getNodeAs<clang::MemberExpr>("mcssspointerarithmetic2");
+
+ if (DRE != nullptr)
+ {
+ const DeclRefExpr* DRE = MR.Nodes.getNodeAs<clang::DeclRefExpr>("mcssspointerarithmetic");
+
+ SourceLocation SL = DRE->getLocStart();
+ SourceLocation SLMID;
+
+ if (SL.isMacroID())
+ {
+ SLMID = Devi::SourceLocationHasMacro(SL, Rewrite, "start");
+ }
+
+ SL = Devi::SourceLocationHasMacro(SL, Rewrite, "start");
+ SourceLocation SLE = DRE->getLocEnd();
+ SourceLocation SLEMID;
+
+ if (SLE.isMacroID())
+ {
+ SLEMID = Devi::SourceLocationHasMacro(SLE, Rewrite, "end");
+ }
+
+ SLE = Devi::SourceLocationHasMacro(SLE, Rewrite, "end");
+
+ QualType QT = DRE->getType();
+
+ const clang::Type* TP = QT.getTypePtr();
+
+ ASTContext *const ASTC = MR.Context;
+ FullSourceLoc FSL = ASTC->getFullLoc(SL);
+
+ SourceManager &SM = ASTC->getSourceManager();
+
+ auto source_location_str = SL.printToString(*MR.SourceManager);
+ std::string source_text;
+ if (SL.isValid() && SLE.isValid()) {
+ source_text = Rewrite.getRewrittenText(SourceRange(SL, SLE));
+ } else {
+ return;
+ }
+
+
+ if (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, SL))
+ {
+ return void();
+ }
+
+ if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, SL))
+ {
+ return void();
+ }
+
+ auto decl = DRE->getDecl();
+ auto DD = dynamic_cast<const DeclaratorDecl*>(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;
+ }
+
+ if (!DD) {
+ return;
+ } else {
+ auto decl_source_range = DD->getSourceRange();
+ 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();
+ std::string 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 iter = m_state1.m_decl_replacement_action_records_log.find(DD);
+ if (m_state1.m_decl_replacement_action_records_log.end() != iter) {
+ /* This variable declaration has already been processed. Probably. */
+ return;
+ }
+
+ auto var_decls = IndividualDeclaratorDecls(DD, Rewrite);
+ if ((1 <= var_decls.size()) && (var_decls.back() == DD)) {
+ std::vector<std::string> action_species_list;
+ std::string replacement_code;
+ for (const auto& var_decl : var_decls) {
+ auto res = RandomAccessIteratorFromPointerDDecl(var_decl, Rewrite);
+ action_species_list.push_back(res.m_action_species);
+ replacement_code += res.m_replacement_code;
+ replacement_code += "; \n";
+ }
+ if (replacement_code.size() >= 3) {
+ replacement_code = replacement_code.substr(0, replacement_code.size() - 3);
+ }
+
+ if (ConvertToSCPP && decl_source_range.isValid() && (3 <= replacement_code.size())) {
+ auto res = Rewrite.ReplaceText(decl_source_range, replacement_code);
+
+ for (auto var_decl : var_decls) {
+ assert(1 <= action_species_list.size());
+ CDeclReplacementActionRecord action_record(Rewrite, *var_decl, replacement_code, action_species_list.front());
+ action_species_list.erase(action_species_list.begin());
+ m_state1.m_decl_replacement_action_records_log.push_back(action_record);
+ //m_state1.m_dynamic_array_contingent_replacement_map.do_and_dispose_matching_replacements(*var_decl);
+ }
+ int q = 3;
+ } else {
+ int q = 7;
+ }
+ } else {
+ int q = 7;
+ }
+ }
+ }
+ }
+
+private:
+ Rewriter &Rewrite;
+ CState1& m_state1;
+};
+
/**********************************************************************************************************************/
+static std::string IPointerFromPointerDecl(const DeclaratorDecl* DD, Rewriter &Rewrite, bool discard_initializer = false) {
+ std::string retval;
+
+ QualType QT = DD->getType();
+
+ const clang::Type* TP = QT.getTypePtr();
+
+ clang::StorageDuration storage_duration = clang::StorageDuration::SD_Automatic;
+ bool has_dynamic_storage_duration = false;
+ bool is_a_temporary = false;
+ bool is_static = false;
+ bool is_a_function_parameter = false;
+ std::string initialization_expr_str;
+
+ auto FD = dynamic_cast<const clang::FieldDecl *>(DD);
+ auto VD = dynamic_cast<const clang::VarDecl *>(DD);
+ if (VD) {
+ storage_duration = VD->getStorageDuration();
+ has_dynamic_storage_duration = (clang::StorageDuration::SD_Dynamic == storage_duration);
+ is_a_temporary = (clang::StorageDuration::SD_FullExpression == storage_duration);
+ is_static = (clang::StorageDuration::SD_Static == storage_duration);
+ is_a_function_parameter = (VD->isLocalVarDeclOrParm() && (!VD->isLocalVarDecl()));
+
+ auto pInitExpr = VD->getInit();
+ if (VD->hasInit() && pInitExpr) {
+ auto init_expr_source_range = pInitExpr->getSourceRange();
+ initialization_expr_str = Rewrite.getRewrittenText(init_expr_source_range);
+ }
+ } else if (FD) {
+ /* Just placeholder code for now. Haven't thought about this case yet. */
+ auto pInitExpr = FD->getInClassInitializer();
+ if (FD->hasInClassInitializer() && pInitExpr) {
+ auto init_expr_source_range = pInitExpr->getSourceRange();
+ initialization_expr_str = Rewrite.getRewrittenText(init_expr_source_range);
+ }
+ }
+
+ auto variable_name = DD->getNameAsString();
+ std::string identifier_name_str;
+ auto pIdentifier = DD->getIdentifier();
+ if (pIdentifier) {
+ identifier_name_str = pIdentifier->getName();
+ }
+
+ bool replacement_code_generated = false;
+ if (TP->isPointerType()) {
+ auto TPP = static_cast<const clang::PointerType*>(TP);
+ if (TPP) {
+ auto target_type = TPP->getPointeeType();
+
+ auto splitQualType = target_type.split();
+ auto type_str = clang::QualType::getAsString(splitQualType);
+
+ if (("char" != type_str) && ("const char" != type_str)) {
+ std::string replacement_code;
+ if (is_static) {
+ replacement_code += "static ";
+ }
+ replacement_code += "mse::TIPointerWithBundledVector<";
+ replacement_code += type_str;
+ replacement_code += "> ";
+ replacement_code += variable_name;
+
+ if (("" != initialization_expr_str) && (!discard_initializer)) {
+ replacement_code += " = ";
+ replacement_code += initialization_expr_str;
+ }
+ retval = replacement_code;
+ replacement_code_generated = true;
+ } else {
+ int q = 3;
+ }
+ } else {
+ assert(false);
+ int q = 1;
+ }
+ }
+
+ if (!replacement_code_generated) {
+ auto splitQualType = QT.split();
+ auto type_str = clang::QualType::getAsString(splitQualType);
+
+ std::string replacement_code;
+ if (is_static) {
+ replacement_code += "static ";
+ }
+ replacement_code += type_str;
+ replacement_code += " ";
+ replacement_code += variable_name;
+
+ if ("" != initialization_expr_str) {
+ replacement_code += " = ";
+ replacement_code += initialization_expr_str;
+ }
+ retval = replacement_code;
+ replacement_code_generated = true;
+ }
+ return retval;
+}
+
+class MCSSSMalloc : public MatchFinder::MatchCallback
+{
+public:
+ MCSSSMalloc (Rewriter &Rewrite, CState1& state1)
+ : Rewrite(Rewrite), m_state1(state1) {}
+
+ virtual void run(const MatchFinder::MatchResult &MR)
+ {
+ const BinaryOperator* BO = MR.Nodes.getNodeAs<clang::BinaryOperator>("mcsssmalloc1");
+ const CallExpr* CE = MR.Nodes.getNodeAs<clang::CallExpr>("mcsssmalloc2");
+ const DeclRefExpr* DRE = MR.Nodes.getNodeAs<clang::DeclRefExpr>("mcsssmalloc3");
+ const MemberExpr* ME = MR.Nodes.getNodeAs<clang::MemberExpr>("mcsssmalloc4");
+
+ if ((BO != nullptr) && (CE != nullptr) && (DRE != nullptr))
+ {
+ SourceLocation BOSL = BO->getLocStart();
+ SourceLocation BOSLMID;
+
+ if (BOSL.isMacroID())
+ {
+ BOSLMID = Devi::SourceLocationHasMacro(BOSL, Rewrite, "start");
+ }
+
+ BOSL = Devi::SourceLocationHasMacro(BOSL, Rewrite, "start");
+ SourceLocation BOSLE = BO->getLocEnd();
+ SourceLocation BOSLEMID;
+
+ if (BOSLE.isMacroID())
+ {
+ BOSLEMID = Devi::SourceLocationHasMacro(BOSLE, Rewrite, "end");
+ }
+
+ BOSLE = Devi::SourceLocationHasMacro(BOSLE, Rewrite, "end");
+
+ 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 (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, BOSL))
+ {
+ return void();
+ }
+
+ if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, BOSL))
+ {
+ return void();
+ }
+
+ auto function_decl = CE->getDirectCallee();
+ auto num_args = CE->getNumArgs();
+ if (function_decl && (1 == 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)));
+ if (ends_with_realloc) {
+ int q = 5;
+ } else if (ends_with_alloc) {
+ auto iter = CE->arg_begin();
+ auto arg_source_range = (*iter)->getSourceRange();
+ 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);
+ 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);
+ }
+
+ bool asterisk_found = false;
+ 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 (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;
+ QualType QT;
+ std::string element_type_str;
+ clang::SourceRange decl_source_range;
+ std::string declaration_replacement_code;
+ std::string variable_name;
+ std::string bo_replacement_code;
+ const clang::DeclaratorDecl* DD = nullptr;
+
+
+ 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 = DD->getSourceRange();
+ 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 decls = IndividualDeclaratorDecls(DD, Rewrite);
+ if ((1 <= decls.size()) && (decls.back() == DD)) {
+ for (const auto& decl : decls) {
+ declaration_replacement_code += IPointerFromPointerDecl(decl, Rewrite);
+ declaration_replacement_code += "; \n";
+ }
+ if (declaration_replacement_code.size() >= 3) {
+ declaration_replacement_code = declaration_replacement_code.substr(0, declaration_replacement_code.size() - 3);
+ }
+ } else {
+ int q = 7;
+ }
+
+ const clang::Type* TP = QT.getTypePtr();
+
+ if (TP->isArrayType()) {
+ auto ATP = static_cast<const clang::ArrayType*>(TP);
+ assert(nullptr != ATP);
+ auto element_type = ATP->getElementType();
+ auto elementSplitQualType = element_type.split();
+ element_type_str = clang::QualType::getAsString(elementSplitQualType);
+ } else if (TP->isPointerType()) {
+ auto TPP = static_cast<const clang::PointerType*>(TP);
+ assert(nullptr != TPP);
+ auto target_type = TPP->getPointeeType();
+ auto splitQualType = target_type.split();
+ auto type_str = clang::QualType::getAsString(splitQualType);
+ if (("char" != type_str) && ("const char" != type_str)) {
+ element_type_str = type_str;
+ }
+ }
+ if ("" != element_type_str) {
+ auto lhs = BO->getLHS();
+ auto lhs_source_range = lhs->getSourceRange();
+ 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())) {
+ if ((3 <= declaration_replacement_code.size())) {
+ bool already_replaced_flag = false;
+ size_t replacement_text_length = 0;
+ for (const auto& decl : decls) {
+ auto iter = m_state1.m_decl_replacement_action_records_log.find(decl);
+ if (m_state1.m_decl_replacement_action_records_log.end() != iter) {
+ /* This declaration had already been replaced. We'll need to "undo"
+ * the replacement. */
+ already_replaced_flag = true;
+ auto replacement_text = (*iter).replacement_text();
+ if ((*iter).replacement_text().size() > replacement_text_length) {
+ replacement_text_length = (*iter).replacement_text().size();
+ }
+ m_state1.m_decl_replacement_action_records_log.erase(iter);
+ }
+
+ CDeclReplacementActionRecord action_record(Rewrite, *decl, declaration_replacement_code, "pointer targeting heap allocated array to mse vector iterator");
+ m_state1.m_decl_replacement_action_records_log.push_back(action_record);
+ m_state1.m_dynamic_array_contingent_replacement_map.do_and_dispose_matching_replacements(*decl);
+ }
+ auto adj_decl_source_range = decl_source_range;
+ if (already_replaced_flag) {
+ adj_decl_source_range = clang::SourceRange(decl_source_range.getBegin(), decl_source_range.getBegin().getLocWithOffset(replacement_text_length));
+ }
+ auto adj_decl_source_text = Rewrite.getRewrittenText(adj_decl_source_range);
+ auto res = Rewrite.ReplaceText(decl_source_range, declaration_replacement_code);
+ }
+ auto res2 = Rewrite.ReplaceText(BOSR, bo_replacement_code);
+ int q = 3;
+ } else {
+ int q = 7;
+ }
+ }
+ }
+ int q = 5;
+ }
+ }
+ }
+ } else {
+ int q = 5;
+ }
+ int q = 5;
+ }
+ }
+
+ }
+ }
+ }
+
+private:
+ Rewriter &Rewrite;
+ CState1& m_state1;
+};
+
+class MCSSSMallocInitializer : public MatchFinder::MatchCallback
+{
+public:
+ MCSSSMallocInitializer (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))
+ {
+ SourceLocation DSSL = DS->getLocStart();
+ SourceLocation DSSLMID;
+
+ if (DSSL.isMacroID())
+ {
+ DSSLMID = Devi::SourceLocationHasMacro(DSSL, Rewrite, "start");
+ }
+
+ DSSL = Devi::SourceLocationHasMacro(DSSL, Rewrite, "start");
+ SourceLocation DSSLE = DS->getLocEnd();
+ SourceLocation DSSLEMID;
+
+ if (DSSLE.isMacroID())
+ {
+ DSSLEMID = Devi::SourceLocationHasMacro(DSSLE, Rewrite, "end");
+ }
+
+ DSSLE = Devi::SourceLocationHasMacro(DSSLE, Rewrite, "end");
+
+ 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 (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, DSSL))
+ {
+ return void();
+ }
+
+ if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, DSSL))
+ {
+ return void();
+ }
+
+ auto function_decl = CE->getDirectCallee();
+ auto num_args = CE->getNumArgs();
+ if (function_decl && (1 == 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)));
+ if (ends_with_realloc) {
+ int q = 5;
+ } else if (ends_with_alloc) {
+ auto iter = CE->arg_begin();
+ auto arg_source_range = (*iter)->getSourceRange();
+ 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);
+ 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);
+ }
+
+ bool asterisk_found = false;
+ 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 (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;
+ QualType QT;
+ std::string element_type_str;
+ clang::SourceRange decl_source_range;
+ std::string declaration_replacement_code;
+ std::string variable_name;
+
+ if (nullptr != DD) {
+ auto decl_source_range = DD->getSourceRange();
+ 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 decls = IndividualDeclaratorDecls(DD, Rewrite);
+ if ((1 <= decls.size()) && (decls.back() == DD)) {
+ for (const auto& decl : decls) {
+ declaration_replacement_code += IPointerFromPointerDecl(decl, Rewrite, true/*discard_initializer*/);
+ declaration_replacement_code += "(";
+ declaration_replacement_code += num_elements_text;
+ declaration_replacement_code += "); \n";
+ }
+ if (declaration_replacement_code.size() >= 3) {
+ declaration_replacement_code = declaration_replacement_code.substr(0, declaration_replacement_code.size() - 3);
+ }
+ } else {
+ int q = 7;
+ }
+
+ const clang::Type* TP = QT.getTypePtr();
+
+ if (TP->isArrayType()) {
+ auto ATP = static_cast<const clang::ArrayType*>(TP);
+ assert(nullptr != ATP);
+ auto element_type = ATP->getElementType();
+ auto elementSplitQualType = element_type.split();
+ element_type_str = clang::QualType::getAsString(elementSplitQualType);
+ } else if (TP->isPointerType()) {
+ auto TPP = static_cast<const clang::PointerType*>(TP);
+ assert(nullptr != TPP);
+ auto target_type = TPP->getPointeeType();
+ auto splitQualType = target_type.split();
+ auto type_str = clang::QualType::getAsString(splitQualType);
+ if (("char" != type_str) && ("const char" != type_str)) {
+ element_type_str = type_str;
+ }
+ }
+ if ("" != element_type_str) {
+ 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 DSSR = clang::SourceRange(DSSL, DSSLE);
+ if (ConvertToSCPP && decl_source_range.isValid() && (DSSR.isValid())) {
+ if ((3 <= declaration_replacement_code.size())) {
+ bool already_replaced_flag = false;
+ size_t replacement_text_length = 0;
+ for (const auto& decl : decls) {
+ auto iter = m_state1.m_decl_replacement_action_records_log.find(decl);
+ if (m_state1.m_decl_replacement_action_records_log.end() != iter) {
+ /* This declaration had already been replaced. We'll need to "undo"
+ * the replacement. */
+ already_replaced_flag = true;
+ if ((*iter).replacement_text().size() > replacement_text_length) {
+ replacement_text_length = (*iter).replacement_text().size();
+ }
+ m_state1.m_decl_replacement_action_records_log.erase(iter);
+ }
+
+ CDeclReplacementActionRecord action_record(Rewrite, *decl, declaration_replacement_code, "pointer targeting heap allocated array to mse vector iterator");
+ m_state1.m_decl_replacement_action_records_log.push_back(action_record);
+ m_state1.m_dynamic_array_contingent_replacement_map.do_and_dispose_matching_replacements(*decl);
+ }
+ auto adj_decl_source_range = decl_source_range;
+ if (already_replaced_flag) {
+ adj_decl_source_range = clang::SourceRange(decl_source_range.getBegin(), decl_source_range.getBegin().getLocWithOffset(replacement_text_length));
+ }
+ auto res = Rewrite.ReplaceText(decl_source_range, declaration_replacement_code);
+ }
+ int q = 3;
+ } else {
+ int q = 7;
+ }
+ }
+ }
+ int q = 5;
+ }
+ }
+ }
+ } else {
+ int q = 5;
+ }
+ int q = 5;
+ }
+ }
+
+ }
+ }
+ }
+
+private:
+ Rewriter &Rewrite;
+ CState1& m_state1;
+};
+
+class MCSSSFree : public MatchFinder::MatchCallback
+{
+public:
+ MCSSSFree (Rewriter &Rewrite, CState1& state1)
+ : Rewrite(Rewrite), m_state1(state1) {}
+
+ virtual void run(const MatchFinder::MatchResult &MR)
+ {
+ const CallExpr* CE = MR.Nodes.getNodeAs<clang::CallExpr>("mcsssfree1");
+ const DeclRefExpr* DRE = MR.Nodes.getNodeAs<clang::DeclRefExpr>("mcsssfree2");
+ const MemberExpr* ME = MR.Nodes.getNodeAs<clang::MemberExpr>("mcsssfree3");
+
+ if ((CE != nullptr) && (DRE != nullptr))
+ {
+ SourceLocation CESL = CE->getLocStart();
+ SourceLocation CESLMID;
+
+ if (CESL.isMacroID())
+ {
+ CESLMID = Devi::SourceLocationHasMacro(CESL, Rewrite, "start");
+ }
+
+ CESL = Devi::SourceLocationHasMacro(CESL, Rewrite, "start");
+ SourceLocation CESLE = CE->getLocEnd();
+ SourceLocation CESLEMID;
+
+ if (CESLE.isMacroID())
+ {
+ CESLEMID = Devi::SourceLocationHasMacro(CESLE, Rewrite, "end");
+ }
+
+ CESLE = Devi::SourceLocationHasMacro(CESLE, Rewrite, "end");
+
+ 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 (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, CESL))
+ {
+ return void();
+ }
+
+ if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, CESL))
+ {
+ return void();
+ }
+
+ auto function_decl = CE->getDirectCallee();
+ auto num_args = CE->getNumArgs();
+ if (function_decl && (1 == num_args)) {
+ {
+ std::string function_name = function_decl->getNameAsString();
+ static const std::string free_str = "free";
+ auto lc_function_name = tolowerstr(function_name);
+ bool ends_with_free = ((lc_function_name.size() >= free_str.size())
+ && (0 == lc_function_name.compare(lc_function_name.size() - free_str.size(), free_str.size(), free_str)));
+ if (ends_with_free) {
+ auto iter = CE->arg_begin();
+ assert((*iter)->getType().getTypePtrOrNull());
+ auto arg_source_range = (*iter)->getSourceRange();
+ std::string arg_source_text;
+ if (arg_source_range.isValid()) {
+ arg_source_text = Rewrite.getRewrittenText(arg_source_range);
+ //auto arg_source_text_sans_ws = with_whitespace_removed(arg_source_text);
+ QualType QT;
+ std::string element_type_str;
+ clang::SourceRange decl_source_range;
+ std::string variable_name;
+ std::string ce_replacement_code;
+ const clang::DeclaratorDecl* DD = nullptr;
+
+ auto decl = DRE->getDecl();
+ DD = dynamic_cast<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 = DD->getSourceRange();
+ 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 iter = m_state1.m_decl_replacement_action_records_log.find(DD/*decl_source_range.getBegin()*/);
+ if (m_state1.m_decl_replacement_action_records_log.end() != iter) {
+ if ("pointer targeting heap allocated array to mse vector iterator" == (*iter).action_species()) {
+ ce_replacement_code = arg_source_text;
+ ce_replacement_code += ".resize(0)";
+
+ auto CESR = clang::SourceRange(CESL, CESLE);
+ if (ConvertToSCPP && (CESR.isValid())) {
+ auto res2 = Rewrite.ReplaceText(CESR, ce_replacement_code);
+ int q = 3;
+ } else {
+ int q = 7;
+ }
+ }
+ } else {
+ auto cr_shptr = std::make_shared<CFreeDynamicArrayReplacementAction>(Rewrite, MR, *DD, CE, DRE, ME);
+ m_state1.m_dynamic_array_contingent_replacement_map.insert(cr_shptr);
+ }
+ }
+ int q = 5;
+ } else {
+ int q = 5;
+ }
+ int q = 5;
+ }
+ }
+
+ }
+ }
+ }
+
+private:
+ Rewriter &Rewrite;
+ CState1& m_state1;
+};
+
+class MCSSSSetToNull : public MatchFinder::MatchCallback
+{
+public:
+ MCSSSSetToNull (Rewriter &Rewrite, CState1& state1)
+ : Rewrite(Rewrite), m_state1(state1) {}
+
+ virtual void run(const MatchFinder::MatchResult &MR)
+ {
+ const BinaryOperator* BO = MR.Nodes.getNodeAs<clang::BinaryOperator>("mcssssettonull1");
+ 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>("mcssssettonull3");
+ const MemberExpr* ME = MR.Nodes.getNodeAs<clang::MemberExpr>("mcssssettonull4");
+
+ if ((BO != nullptr) && (RHS != nullptr) && (LHS != nullptr) && (DRE != nullptr))
+ {
+ SourceLocation BOSL = BO->getLocStart();
+ SourceLocation BOSLMID;
+
+ if (BOSL.isMacroID())
+ {
+ BOSLMID = Devi::SourceLocationHasMacro(BOSL, Rewrite, "start");
+ }
+
+ BOSL = Devi::SourceLocationHasMacro(BOSL, Rewrite, "start");
+ SourceLocation BOSLE = BO->getLocEnd();
+ SourceLocation BOSLEMID;
+
+ if (BOSLE.isMacroID())
+ {
+ BOSLEMID = Devi::SourceLocationHasMacro(BOSLE, Rewrite, "end");
+ }
+
+ BOSLE = Devi::SourceLocationHasMacro(BOSLE, Rewrite, "end");
+
+ 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 (Devi::IsTheMatchInSysHeader(CheckSystemHeader, MR, BOSL))
+ {
+ return void();
+ }
+
+ if (!Devi::IsTheMatchInMainFile(MainFileOnly, MR, BOSL))
+ {
+ return void();
+ }
+
+ Expr::NullPointerConstantKind kind = RHS->isNullPointerConstant(*ASTC, Expr::NullPointerConstantValueDependence());
+ if (clang::Expr::NPCK_NotNull != kind) {
+ auto lhs_source_range = LHS->getSourceRange();
+ 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);
+
+ QualType QT;
+ std::string element_type_str;
+ clang::SourceRange decl_source_range;
+ std::string variable_name;
+ std::string bo_replacement_code;
+ const clang::DeclaratorDecl* DD = nullptr;
+
+ auto decl = DRE->getDecl();
+ DD = dynamic_cast<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 = DD->getSourceRange();
+ 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;
+ }
+
+ if ((DD->getType() == LHS->getType())) {
+ auto iter = m_state1.m_decl_replacement_action_records_log.find(DD/*decl_source_range.getBegin()*/);
+ if ((m_state1.m_decl_replacement_action_records_log.end() != iter)
+ && ("pointer targeting heap allocated array to mse vector iterator" == (*iter).action_species())
+ && ((*iter).get_ddecl_cptr()->getType() == LHS->getType())) {
+ if (true) {
+ bo_replacement_code = lhs_source_text;
+ bo_replacement_code += ".resize(0)";
+
+ auto BOSR = clang::SourceRange(BOSL, BOSLE);
+ if (ConvertToSCPP && (BOSR.isValid())) {
+ auto res2 = Rewrite.ReplaceText(BOSR, bo_replacement_code);
+ int q = 3;
+ } else {
+ int q = 7;
+ }
+ } else {
+ int q = 5;
+ }
+ } else {
+ auto cr_shptr = std::make_shared<CSetArrayPointerToNullReplacementAction>(Rewrite, MR, *DD, BO, DRE, ME);
+ m_state1.m_dynamic_array_contingent_replacement_map.insert(cr_shptr);
+ }
+ }
+ }
+ int q = 5;
+ } else {
+ int q = 5;
+ }
+ int q = 5;
+ }
+ }
+ }
+
+private:
+ Rewriter &Rewrite;
+ CState1& m_state1;
+};
+
+
/**********************************************************************************************************************/
class MyASTConsumer : public ASTConsumer {
public:
- MyASTConsumer(Rewriter &R)
+ MyASTConsumer(Rewriter &R) : HandlerForSSSNativePointer(R), HandlerForSSSArrayToPointerDecay(R, m_state1), \
+ HandlerForSSSVarDecl(R, m_state1), HandlerForSSSPointerArithmetic(R, m_state1), \
+ HandlerForSSSMalloc(R, m_state1), HandlerForSSSMallocInitializer(R, m_state1), \
+ HandlerForSSSFree(R, m_state1), HandlerForSSSSetToNull(R, m_state1)
{
+ Matcher.addMatcher(varDecl(hasType(pointerType())).bind("mcsssnativepointer"), &HandlerForSSSNativePointer);
+
+ Matcher.addMatcher(castExpr(allOf(hasCastKind(CK_ArrayToPointerDecay), unless(hasParent(arraySubscriptExpr())))).bind("mcsssarraytopointerdecay"), &HandlerForSSSArrayToPointerDecay);
+
+ Matcher.addMatcher(varDecl().bind("mcsssvardecl"), &HandlerForSSSVarDecl);
+
+ Matcher.addMatcher(declRefExpr(allOf(hasParent(expr(anyOf( \
+ unaryOperator(hasOperatorName("++")), unaryOperator(hasOperatorName("--")), \
+ binaryOperator(hasOperatorName("+=")), binaryOperator(hasOperatorName("-=")), \
+ hasParent(expr(anyOf( \
+ binaryOperator(hasOperatorName("+")), binaryOperator(hasOperatorName("+=")), \
+ binaryOperator(hasOperatorName("-")), binaryOperator(hasOperatorName("-=")), \
+ binaryOperator(hasOperatorName("<=")), binaryOperator(hasOperatorName("<")), \
+ binaryOperator(hasOperatorName(">=")), binaryOperator(hasOperatorName(">")), \
+ arraySubscriptExpr(), clang::ast_matchers::castExpr(hasParent(arraySubscriptExpr())) \
+ )))))), to(declaratorDecl(hasType(pointerType()))))).bind("mcssspointerarithmetic"), &HandlerForSSSPointerArithmetic);
+
+ Matcher.addMatcher(memberExpr(allOf(hasDescendant(declRefExpr().bind("mcssspointerarithmetic")), hasParent(expr(anyOf( \
+ unaryOperator(hasOperatorName("++")), unaryOperator(hasOperatorName("--")), \
+ binaryOperator(hasOperatorName("+=")), binaryOperator(hasOperatorName("-=")), \
+ hasParent(expr(anyOf( \
+ binaryOperator(hasOperatorName("+")), binaryOperator(hasOperatorName("+=")), \
+ binaryOperator(hasOperatorName("-")), binaryOperator(hasOperatorName("-=")), \
+ binaryOperator(hasOperatorName("<=")), binaryOperator(hasOperatorName("<")), \
+ binaryOperator(hasOperatorName(">=")), binaryOperator(hasOperatorName(">")), \
+ arraySubscriptExpr(), clang::ast_matchers::castExpr(hasParent(arraySubscriptExpr())) \
+ )))))), member(hasType(pointerType())))).bind("mcssspointerarithmetic2"), &HandlerForSSSPointerArithmetic);
+
+ Matcher.addMatcher(binaryOperator(allOf(
+ hasOperatorName("="),
+ hasRHS(
+ anyOf(
+ cStyleCastExpr(has(callExpr().bind("mcsssmalloc2"))),
+ callExpr().bind("mcsssmalloc2")
+ )
+ ),
+ hasLHS(anyOf(
+ memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssmalloc3")))).bind("mcsssmalloc4"),
+ hasDescendant(memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssmalloc3")))).bind("mcsssmalloc4")),
+ hasDescendant(declRefExpr().bind("mcsssmalloc3")),
+ declRefExpr().bind("mcsssmalloc3")
+ )),
+ hasLHS(expr(hasType(pointerType())))
+ )).bind("mcsssmalloc1"), &HandlerForSSSMalloc);
+
+ Matcher.addMatcher(declStmt(hasDescendant(
+ varDecl(hasInitializer(ignoringImpCasts(
+ anyOf(
+ cStyleCastExpr(has(callExpr().bind("mcsssmallocinitializer2"))),
+ callExpr().bind("mcsssmallocinitializer2")
+ )
+ ))).bind("mcsssmallocinitializer3")
+ )).bind("mcsssmallocinitializer1"), &HandlerForSSSMallocInitializer);
+
+ Matcher.addMatcher(
+ callExpr(allOf(
+ hasAnyArgument(
+ expr(anyOf(
+ memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssfree2")))).bind("mcsssfree3"),
+ hasDescendant(memberExpr(expr(hasDescendant(declRefExpr().bind("mcsssfree2")))).bind("mcsssfree3")),
+ hasDescendant(declRefExpr().bind("mcsssfree2"))
+ ))),
+ argumentCountIs(1),
+ hasAnyArgument(hasType(pointerType()))
+ )).bind("mcsssfree1"), &HandlerForSSSFree);
+
+ Matcher.addMatcher(binaryOperator(allOf(
+ hasOperatorName("="),
+ hasLHS(anyOf(
+ memberExpr(expr(hasDescendant(declRefExpr().bind("mcssssettonull3")))).bind("mcssssettonull4"),
+ hasDescendant(memberExpr(expr(hasDescendant(declRefExpr().bind("mcssssettonull3")))).bind("mcssssettonull4")),
+ hasDescendant(declRefExpr().bind("mcssssettonull3"))
+ )),
+ hasLHS(expr(hasType(pointerType())))
+ )).bind("mcssssettonull1"), &HandlerForSSSSetToNull);
}
void HandleTranslationUnit(ASTContext &Context) override
@@ -66,8 +2172,21 @@ public:
}
private:
+
+ CState1 m_state1;
+
+ MCSSSNativePointer HandlerForSSSNativePointer;
+ MCSSSArrayToPointerDecay HandlerForSSSArrayToPointerDecay;
+ MCSSSVarDecl HandlerForSSSVarDecl;
+ MCSSSPointerArithmetic HandlerForSSSPointerArithmetic;
+ MCSSSMalloc HandlerForSSSMalloc;
+ MCSSSMallocInitializer HandlerForSSSMallocInitializer;
+ MCSSSFree HandlerForSSSFree;
+ MCSSSSetToNull HandlerForSSSSetToNull;
+
MatchFinder Matcher;
};
+
/**********************************************************************************************************************/
class MyFrontendAction : public ASTFrontendAction
{