diff --git a/src/Makefile.am b/src/Makefile.am old mode 100644 new mode 100755 index 73b6606c0..b7bd1f5a0 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -163,6 +163,8 @@ csmith_SOURCES = \ StringUtils.h \ Type.cpp \ Type.h \ + TypeConfig.cpp \ + TypeConfig.h \ PointerType.cpp \ PointerType.h \ AggregateType.cpp \ diff --git a/src/Makefile.in b/src/Makefile.in old mode 100644 new mode 100755 index 324c58856..7e26d4223 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -137,9 +137,9 @@ am_csmith_OBJECTS = csmith-AbsExtension.$(OBJEXT) \ csmith-StatementExpr.$(OBJEXT) csmith-StatementFor.$(OBJEXT) \ csmith-StatementGoto.$(OBJEXT) csmith-StatementIf.$(OBJEXT) \ csmith-StatementReturn.$(OBJEXT) csmith-StringUtils.$(OBJEXT) \ - csmith-Type.$(OBJEXT) csmith-PointerType.$(OBJEXT) \ - csmith-AggregateType.$(OBJEXT) csmith-Variable.$(OBJEXT) \ - csmith-VariableSelector.$(OBJEXT) \ + csmith-Type.$(OBJEXT) csmith-TypeConfig.$(OBJEXT) \ + csmith-PointerType.$(OBJEXT) csmith-AggregateType.$(OBJEXT) \ + csmith-Variable.$(OBJEXT) csmith-VariableSelector.$(OBJEXT) \ csmith-VectorFilter.$(OBJEXT) csmith-platform.$(OBJEXT) \ csmith-random.$(OBJEXT) csmith-util.$(OBJEXT) \ csmith-tinyxml.$(OBJEXT) csmith-tinyxmlerror.$(OBJEXT) \ @@ -490,6 +490,8 @@ csmith_SOURCES = \ StringUtils.h \ Type.cpp \ Type.h \ + TypeConfig.cpp \ + TypeConfig.h \ PointerType.cpp \ PointerType.h \ AggregateType.cpp \ @@ -687,6 +689,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csmith-StatementReturn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csmith-StringUtils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csmith-Type.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csmith-TypeConfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csmith-Variable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csmith-VariableSelector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csmith-VectorFilter.Po@am__quote@ @@ -1601,6 +1604,20 @@ csmith-Type.obj: Type.cpp @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(csmith_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o csmith-Type.obj `if test -f 'Type.cpp'; then $(CYGPATH_W) 'Type.cpp'; else $(CYGPATH_W) '$(srcdir)/Type.cpp'; fi` +csmith-TypeConfig.o: TypeConfig.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(csmith_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT csmith-TypeConfig.o -MD -MP -MF $(DEPDIR)/csmith-TypeConfig.Tpo -c -o csmith-TypeConfig.o `test -f 'TypeConfig.cpp' || echo '$(srcdir)/'`TypeConfig.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/csmith-TypeConfig.Tpo $(DEPDIR)/csmith-TypeConfig.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TypeConfig.cpp' object='csmith-TypeConfig.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(csmith_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o csmith-TypeConfig.o `test -f 'TypeConfig.cpp' || echo '$(srcdir)/'`TypeConfig.cpp + +csmith-TypeConfig.obj: TypeConfig.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(csmith_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT csmith-TypeConfig.obj -MD -MP -MF $(DEPDIR)/csmith-TypeConfig.Tpo -c -o csmith-TypeConfig.obj `if test -f 'TypeConfig.cpp'; then $(CYGPATH_W) 'TypeConfig.cpp'; else $(CYGPATH_W) '$(srcdir)/TypeConfig.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/csmith-TypeConfig.Tpo $(DEPDIR)/csmith-TypeConfig.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TypeConfig.cpp' object='csmith-TypeConfig.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(csmith_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o csmith-TypeConfig.obj `if test -f 'TypeConfig.cpp'; then $(CYGPATH_W) 'TypeConfig.cpp'; else $(CYGPATH_W) '$(srcdir)/TypeConfig.cpp'; fi` + csmith-PointerType.o: PointerType.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(csmith_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT csmith-PointerType.o -MD -MP -MF $(DEPDIR)/csmith-PointerType.Tpo -c -o csmith-PointerType.o `test -f 'PointerType.cpp' || echo '$(srcdir)/'`PointerType.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/csmith-PointerType.Tpo $(DEPDIR)/csmith-PointerType.Po diff --git a/src/TypeConfig.cpp b/src/TypeConfig.cpp new file mode 100644 index 000000000..0be4c9d22 --- /dev/null +++ b/src/TypeConfig.cpp @@ -0,0 +1,617 @@ +// -*- mode: C++ -*- +// +// Copyright (c) 2015-2016 Huawei Technologies Co., Ltd +// All rights reserved. +// +// This file is part of `csmith', a random generator of C programs. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#include "TypeConfig.h" + +using namespace std; + +TypeConfig * TypeConfig::type_config_ = NULL; + +TypeConfig * +TypeConfig::create_instance( std::string file_path ) +{ + std::string file_name = file_path + "/Syntax.xml"; + TypeConfig::type_config_ = new TypeConfig(); + TypeConfig::type_config_->initialize(file_name); + return TypeConfig::type_config_; +} + +TypeConfig * +TypeConfig::get_instance() +{ + assert(TypeConfig::type_config_); + return TypeConfig::type_config_; +} + +void +TypeConfig::initialize( std::string file_name ) +{ + parse_config(file_name); +} + +void +TypeConfig::parse_config( std::string file_name ) +{ + TiXmlDocument doc(file_name.c_str()); + bool load_okay = doc.LoadFile(); + if (load_okay) + { + parse_config( &doc ); + } + else + { + cout << "Failed to load file " << file_name << "\n"; + } +} + +void +TypeConfig::parse_config( TiXmlNode* node) +{ + assert(node); + std::string tag = ""; + int type = node->Type(); + static int config_flags = 0; + + switch ( type ) { + case TiXmlNode::TINYXML_ELEMENT: + { + tag = node->Value(); + + if((tag == "types") || (tag == "request") || (tag == "convert") || (tag == "unaryop") || (tag == "binaryop") || (tag == "assignop") ) + config_flags++; + else + { + switch (config_flags) + { + case 1: + set_extend_types(node); + break; + case 2: + set_type_request_map(node); + break; + case 3: + set_type_convert_map(node); + break; + case 4: + set_unary_operators_map(node); + break; + case 5: + set_binary_operators_map(node); + break; + case 6: + set_assign_operators_map(node); + break; + default: + break; + } + } + } + case TiXmlNode::TINYXML_DOCUMENT: + break; + case TiXmlNode::TINYXML_COMMENT: + break; + case TiXmlNode::TINYXML_UNKNOWN: + break; + case TiXmlNode::TINYXML_TEXT: + break; + case TiXmlNode::TINYXML_DECLARATION: + break; + default: + break; + } + TiXmlNode * child = node->FirstChild(); + for (; child != 0; child = child->NextSibling()) + { + parse_config( child ); + } +} + +void +TypeConfig::set_extend_types(TiXmlNode* node) +{ + assert(node); + + TiXmlAttribute* attr = node->ToElement()->FirstAttribute(); + + std::string tag = node->Value(); + + if(tag == "type") + { + std::string type_name = ""; + int type_id = -1; + int type_size = -1; + + while(attr) + { + tag = attr->Name(); + if(tag == "name") + type_name = attr->Value(); + + else if(tag == "id") + type_id = attr->IntValue(); + + else if(tag == "size") + type_size = attr->IntValue(); + + attr = attr->Next(); + } + Type::find_type(type_name, type_id, type_size); + } +} + +void +TypeConfig::set_type_request_map(TiXmlNode* node) +{ + assert(node); + + TiXmlAttribute* attr = node->ToElement()->FirstAttribute(); + + std::string tag = node->Value(); + std::string attr_name, attr_value; + + if(tag == "type") + { + int simple_type = -1; + + while(attr) + { + attr_name = attr->Name(); + attr_value = attr->Value(); + if(attr_name == "name") + simple_type = Type::find_type(attr_value); + + else if(attr_name == "asGlobal" && attr_value == "false") + (types_excluded_by_request[asGlobal]).push_back(simple_type); + + else if(attr_name == "asLocal" && attr_value == "false") + (types_excluded_by_request[asLocal]).push_back(simple_type); + + else if(attr_name == "asParam" && attr_value == "false") + (types_excluded_by_request[asParam]).push_back(simple_type); + + else if(attr_name == "asReturn" && attr_value == "false") + (types_excluded_by_request[asReturn]).push_back(simple_type); + + else if(attr_name == "asStructMember" && attr_value == "false") + (types_excluded_by_request[asStructMember]).push_back(simple_type); + + else if(attr_name == "asUnionMember" && attr_value == "false") + (types_excluded_by_request[asUnionMember]).push_back(simple_type); + + else if(attr_name == "asPointer" && attr_value == "false") + (types_excluded_by_request[asPointer]).push_back(simple_type); + + else if(attr_name == "asArray" && attr_value == "false") + (types_excluded_by_request[asArray]).push_back(simple_type); + + else if(attr_name == "asUnaryExprRv" && attr_value == "false") + (types_excluded_by_request[asUnaryExprRv]).push_back(simple_type); + + else if(attr_name == "asBinaryExprRv" && attr_value == "false") + (types_excluded_by_request[asBinaryExprRv]).push_back(simple_type); + + else if(attr_name == "asAssignExprRv" && attr_value == "false") + (types_excluded_by_request[asAssignExprRv]).push_back(simple_type); + + else if(attr_name == "asGlobalInit" && attr_value == "false") + (types_excluded_by_request[asGlobalInit]).push_back(simple_type); + + attr = attr->Next(); + } + } +} + +void +TypeConfig::set_type_convert_map(TiXmlNode* node) +{ + assert(node); + + int src_type = -1; + int dest_type = -1; + bool is_symmetrical = false; + std::string tag = node->Value(); + std::string attr_name, attr_value; + + TiXmlAttribute* attr = node->ToElement()->FirstAttribute(); + + if(tag == "cast") + { + while(attr) + { + attr_name = attr->Name(); + attr_value = attr->Value(); + if(attr_name == "src") + src_type = Type::find_type(attr_value); + if(attr_name == "dest") + dest_type = Type::find_type(attr_value); + if(attr_name == "symmetrical") + is_symmetrical = (attr_value == "true") ? true : false; + attr = attr->Next(); + } + + if(is_symmetrical) + (types_excluded_by_convert[src_type]).push_back(dest_type); + (types_excluded_by_convert[dest_type]).push_back(src_type); + } +} + +int +TypeConfig::get_op_from_string(std::string op_string, SafeOpKind op_kind) +{ + int op_index = -1; + std::string op_str = ""; + switch (op_kind) + { + case sOpUnary: + for(op_index = 0; op_index < MAX_UNARY_OP; op_index++) + { + op_str = FunctionInvocationUnary::get_op((eUnaryOps)op_index); + if( op_str == op_string ) + return op_index; + } + break; + case sOpBinary: + for(op_index = 0; op_index < MAX_BINARY_OP; op_index++) + { + op_str = FunctionInvocationBinary::get_op((eBinaryOps)op_index); + if( op_str == op_string ) + return op_index; + } + break; + case sOpAssign: + for(op_index = 0; op_index < MAX_ASSIGN_OP; op_index++) + { + op_str = StatementAssign::get_op((eAssignOps)op_index); + if( op_str == op_string ) + return op_index; + } + break; + } + + return -1; +} + +void +TypeConfig::set_unary_operators_map(TiXmlNode* node) +{ + assert(node); + + int op = -1; + int lhs_type = -1; + int rhs_type = -1; + bool additional = false; + pair op_type; + + TiXmlAttribute* attr = node->ToElement()->FirstAttribute(); + + std::string tag = node->Value(); + std::string attr_name, attr_value; + + if(tag == "op") + { + while(attr) + { + attr_name = attr->Name(); + attr_value = attr->Value(); + if(attr_name == "name") + op = get_op_from_string(attr_value, sOpUnary); + + else if(attr_name == "rhs") + rhs_type = Type::find_type(attr_value); + + else if(attr_name == "lhs" ) + lhs_type = Type::find_type(attr_value); + + else if(attr_name == "additional") + additional = true; + + attr = attr->Next(); + } + assert((lhs_type != -1) && (op != -1) && "imcomplete operator settings"); + if(additional) + { + assert((rhs_type != -1) && "imcomplete operator settings"); + op_type = std::make_pair(op, lhs_type); + types_additional_by_unaryop[op_type].push_back(rhs_type); + } + else + types_excluded_by_unaryop[op].push_back(lhs_type); + } +} + +void +TypeConfig::set_binary_operators_map(TiXmlNode* node) +{ + assert(node); + + int op = -1; + int lhs_type = -1; + int rhs1_type = -1; + int rhs2_type = -1; + bool additional = false; + pair op_type; + pair rhs_types; + + TiXmlAttribute* attr = node->ToElement()->FirstAttribute(); + + std::string tag = node->Value(); + std::string attr_name, attr_value; + + if(tag == "op") + { + while(attr) + { + attr_name = attr->Name(); + attr_value = attr->Value(); + if(attr_name == "name") + op = get_op_from_string(attr_value, sOpBinary); + + else if(attr_name == "rhs1") + rhs1_type = Type::find_type(attr_value); + + else if(attr_name == "rhs2") + rhs2_type = Type::find_type(attr_value); + + else if(attr_name == "lhs" ) + lhs_type = Type::find_type(attr_value); + + else if(attr_name == "additional") + additional = true; + + attr = attr->Next(); + } + assert((lhs_type != -1) && (op != -1) && "imcomplete operator settings"); + if(additional) + { + assert((rhs1_type != -1) && (rhs2_type != -1) && "imcomplete operator settings"); + op_type = std::make_pair(op, lhs_type); + rhs_types = std::make_pair(rhs1_type, rhs2_type); + types_additional_by_binaryop[op_type].push_back(rhs_types); + } + else + types_excluded_by_binaryop[op].push_back(lhs_type); + } +} + +void +TypeConfig::set_assign_operators_map(TiXmlNode* node) +{ + assert(node); + + int op = -1; + int lhs_type = -1; + int rhs_type = -1; + bool additional = false; + pair op_type; + + TiXmlAttribute* attr = node->ToElement()->FirstAttribute(); + + std::string tag = node->Value(); + std::string attr_name, attr_value; + + if(tag == "op") + { + while(attr) + { + attr_name = attr->Name(); + attr_value = attr->Value(); + if(attr_name == "name") + op = get_op_from_string(attr_value, sOpAssign); + + else if(attr_name == "rhs") + rhs_type = Type::find_type(attr_value); + + else if(attr_name == "lhs" ) + lhs_type = Type::find_type(attr_value); + + else if(attr_name == "additional") + additional = true; + + attr = attr->Next(); + } + assert((lhs_type != -1) && (op != -1) && "imcomplete operator settings"); + if(additional) + { + assert((rhs_type != -1) && "imcomplete operator settings"); + op_type = std::make_pair(op, lhs_type); + types_additional_by_assignop[op_type].push_back(rhs_type); + } + else + types_excluded_by_assignop[op].push_back(lhs_type); + } +} + +Filter* +TypeConfig::get_filter_for_request(eTypeRequestType request) +{ + VectorFilter * filter = new VectorFilter(); + vector exclude_types = types_excluded_by_request[static_cast(request)]; + + vector::iterator iter; + for(iter = exclude_types.begin(); iter != exclude_types.end(); ++iter) + { + filter->add(Type::get_simple_type((eSimpleType)*iter).type_index); + } + + return filter; +} + +bool +TypeConfig::check_exclude_by_request(const Type * type, eTypeRequestType request) +{ + if(type->eType == eSimple) + { + int type_index = type->simple_type; + vector types = types_excluded_by_request[request]; + vector::iterator iter = types.begin(); + for(;iter != types.end(); ++iter) + { + if(*iter == type_index) + return true; + } + } + return false; +} + +Filter* +TypeConfig::get_filter_for_convert(const Type* dest_type) +{ + assert(dest_type->eType == eSimple); + + VectorFilter * filter = new VectorFilter(); + vector exclude_types = types_excluded_by_convert[static_cast(dest_type->simple_type)]; + + vector::iterator iter; + for(iter = exclude_types.begin(); iter != exclude_types.end(); ++iter) + { + filter->add(Type::get_simple_type((eSimpleType)*iter).type_index); + } + + return filter; +} + +bool +TypeConfig::check_exclude_by_convert(const Type * src_type, const Type * dest_type) +{ + if((src_type->eType == eSimple) && (dest_type->eType == eSimple)) + { + int type_src_index = src_type->simple_type; + int type_dest_index = dest_type->simple_type; + vector types = types_excluded_by_convert[type_dest_index]; + vector::iterator iter = types.begin(); + for(;iter != types.end(); ++iter) + { + if(*iter == type_src_index) + return true; + } + } + return false; +} + +Filter* +TypeConfig::get_filter_for_assignop(int op) +{ + pair op_type; + VectorFilter * filter = new VectorFilter(); + vector exclude_types = types_excluded_by_assignop[op]; + + vector::iterator iter; + for(iter = exclude_types.begin(); iter != exclude_types.end(); ++iter) + { + op_type = std::make_pair(op, *iter); + if ( types_additional_by_assignop.count(op_type) > 0 ) + continue; + filter->add(Type::get_simple_type((eSimpleType)*iter).type_index); + } + + for(iter = types_excluded_by_request[asAssignExprRv].begin(); iter != types_excluded_by_request[asAssignExprRv].end(); ++iter) + { + filter->add(Type::get_simple_type((eSimpleType)*iter).type_index); + } + + return filter; +} + +void +TypeConfig::get_filter_for_assignop(const Type * type, VectorFilter * filter) +{ + pair op_type; + int op_id = 0; + int max_op = MAX_ASSIGN_OP; + + for(; op_id < max_op; ++op_id) + { + op_type = std::make_pair(op_id, type->simple_type); + if ( types_additional_by_assignop.count(op_type) > 0 ) + continue; + + vector exclude_types = types_excluded_by_assignop[op_id]; + + if(std::find(exclude_types.begin(), exclude_types.end(), type->simple_type) != exclude_types.end()) + filter->add(op_id); + } +} + +bool +TypeConfig::check_exclude_by_unaryop(const Type * type, int op) +{ + pair op_type = std::make_pair(op, type->simple_type); + + if ( types_additional_by_unaryop.count(op_type) > 0 ) + return false; + + vector exclude_types = types_excluded_by_unaryop[op]; + + if( std::find(exclude_types.begin(), exclude_types.end(), type->simple_type) == exclude_types.end()) + return false; + + return true; +} + +bool +TypeConfig::check_exclude_by_binaryop(const Type * type, int op) +{ + pair op_type = std::make_pair(op, type->simple_type); + + if ( types_additional_by_binaryop.count(op_type) > 0 ) + return false; + + vector exclude_types = types_excluded_by_binaryop[op]; + + if( std::find(exclude_types.begin(), exclude_types.end(), type->simple_type) == exclude_types.end()) + return false; + + return true; +} + +bool +TypeConfig::check_additional_by_unaryop(const Type * type, int op, std::vector& rhs ) +{ + pair op_type = std::make_pair(op, type->simple_type); + if ( types_additional_by_unaryop.count(op_type) > 0 ) + { + rhs = types_additional_by_unaryop[op_type]; + return true; + } + return false; +} + +bool +TypeConfig::check_additional_by_binaryop(const Type * type, int op, std::vector< std::pair >& rhs ) +{ + pair op_type = std::make_pair(op, type->simple_type); + if ( types_additional_by_binaryop.count(op_type) > 0 ) + { + rhs = types_additional_by_binaryop[op_type]; + return true; + } + return false; + +} \ No newline at end of file diff --git a/src/TypeConfig.h b/src/TypeConfig.h new file mode 100644 index 000000000..3758920ff --- /dev/null +++ b/src/TypeConfig.h @@ -0,0 +1,133 @@ +// -*- mode: C++ -*- +// +// Copyright (c) 2015-2016 Huawei Technologies Co., Ltd +// All rights reserved. +// +// This file is part of `csmith', a random generator of C programs. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef TYPE_CONFIG_H +#define TYPE_CONFIG_H + +#include +#include +#include +#include "Filter.h" +#include "Type.h" +#include "SafeOpFlags.h" +#include "FunctionInvocation.h" +#include "FunctionInvocationBinary.h" +#include "FunctionInvocationUnary.h" +#include "StatementAssign.h" +#include "tinyxml.h" + +/* +* The restrict of type using +*/ +enum eTypeRequestType +{ +asGlobal, +asLocal, +asParam, +asReturn, +asStructMember, +asUnionMember, +asPointer, +asArray, +asUnaryExprRv, +asBinaryExprRv, +asAssignExprRv, +asGlobalInit + +}; +#define MAX_TYPE_REQUEST ((eTypeRequestType)(asGlobalInit+1)) + +/* +* This class packages the restrict of type using, include: +* 1 some restrict of type using, such as "Is the type able to be used as global variable or struct member " +* 2 the restrict of type convert; +* 3 some new types don't support some unary ops; +* 4 some new types don't support some binary ops +*/ +class TypeConfig +{ +public: + static TypeConfig * create_instance( std::string file_path); + static TypeConfig * get_instance(); + + Filter* get_filter_for_request(eTypeRequestType request); + + Filter* get_filter_for_convert(const Type* type); + + Filter* get_filter_for_assignop(int op); + + void get_filter_for_assignop(const Type * type, VectorFilter * filter); + + bool check_exclude_by_request(const Type * type, eTypeRequestType request); + + bool check_exclude_by_convert(const Type * src_type, const Type * dest_type); + + bool check_exclude_by_unaryop(const Type * type, int op = MAX_UNARY_OP); + + bool check_exclude_by_binaryop(const Type * type, int op = MAX_BINARY_OP); + + bool check_additional_by_unaryop(const Type * type, int op, std::vector& rhs ); + + bool check_additional_by_binaryop(const Type * type, int op, std::vector< std::pair >& rhs); + +private: + TypeConfig() { /* do nothing */ } + ~TypeConfig() { /* do nothing */ } + + void initialize( std::string file_name ); + void parse_config( std::string file_name ); + void parse_config( TiXmlNode* node); + + void set_extend_types(TiXmlNode* node); + void set_type_request_map(TiXmlNode* node); + void set_type_convert_map(TiXmlNode* node); + + void set_unary_operators_map(TiXmlNode* node); + void set_binary_operators_map(TiXmlNode* node); + void set_assign_operators_map(TiXmlNode* node); + + int get_op_from_string(std::string op_string, SafeOpKind op_kind); + + std::map > types_excluded_by_request; /* map */ + std::map > types_excluded_by_convert; /* map */ + + std::map > types_excluded_by_unaryop; /* map */ + std::map > types_excluded_by_binaryop; /* map */ + std::map > types_excluded_by_assignop; /* map */ + + std::map, vector > types_additional_by_unaryop; + std::map, vector > > types_additional_by_binaryop; + std::map, vector > types_additional_by_assignop; + + static TypeConfig * type_config_; + +}; + +#endif //TYPE_CONFIG_H