Skip to content

Commit

Permalink
Merge pull request #77 from shubhamnarlawar77/csmith-gcc-c-extension
Browse files Browse the repository at this point in the history
Added support for Common Function Attributes
  • Loading branch information
jxyang committed Sep 7, 2019
2 parents caf0d46 + 061488a commit 948952c
Show file tree
Hide file tree
Showing 12 changed files with 302 additions and 85 deletions.
65 changes: 65 additions & 0 deletions src/Attribute.cpp
@@ -0,0 +1,65 @@
#if HAVE_CONFIG_H
# include <config.h>
#endif

#ifdef WIN32
#pragma warning(disable : 4786) /* Disable annoying warning messages */
#endif

#include "random.h"
#include "OutputMgr.h"
#include "Attribute.h"

void
AttributeGenerator::Output(std::ostream &out)
{
bool attr_emitted = false;
vector<Attribute*>::iterator itr;
for(itr = attributes.begin(); itr != attributes.end(); itr++){
string attr_generated;
attr_generated = (*itr)->make_random();
if(attr_generated != ""){
if(!attr_emitted){
out << " __attribute__((" << attr_generated;
attr_emitted = true;
}
else
out << ", " << attr_generated;
}
}
if(attr_emitted)
out << "))";
}

Attribute::Attribute(string name, int prob)
: name(name), prob(prob)
{
}

BooleanAttribute::BooleanAttribute(string name, int prob)
: Attribute(name, prob)
{
}

string
BooleanAttribute::make_random()
{
if(rnd_flipcoin(prob))
return name;
else
return "";
}

MultiChoiceAttribute::MultiChoiceAttribute(string name, int prob, vector<string> arguments)
: Attribute(name, prob), choices(arguments)
{
}

string
MultiChoiceAttribute::make_random()
{
if(rnd_flipcoin(prob))
return name + "(\"" + choices[rnd_upto(choices.size())] + "\")";
else
return "";
}
49 changes: 49 additions & 0 deletions src/Attribute.h
@@ -0,0 +1,49 @@
#ifndef ATTRIBUTE_H
#define ATTRIBUTE_H

#include <string>
#include <vector>
using namespace std;

class AttributeGenerator;

//Base class with pure virtual methods which will be derived as per different types of attribute generation
class Attribute
{
public:
//Name of attribute
string name;
//Attribute generation probability
int prob;
Attribute(string, int);
//Checks attribute probability and generate is accordingly
virtual string make_random() = 0;
};

//Generates Boolean attributes such as hot, cold, used, unused, deprecated, etc
class BooleanAttribute : public Attribute
{
public:
BooleanAttribute(string, int);
string make_random();
};

//Generates Multi Choice attributes such as visibility("option"), no_sanitize("option"), etc
class MultiChoiceAttribute : public Attribute
{
public:
//stores various options of attributes e.g. visibility options - default, hidden, internal and protected
vector<string> choices;
MultiChoiceAttribute(string, int, vector<string>);
string make_random();
};

class AttributeGenerator
{
public:
//stores instances of Attribute
vector<Attribute*> attributes;
void Output(std::ostream &);
};

#endif
3 changes: 3 additions & 0 deletions src/CGOptions.cpp
Expand Up @@ -195,6 +195,9 @@ DEFINE_GETTER_SETTER_BOOL(lang_cpp);
DEFINE_GETTER_SETTER_BOOL(cpp11);
DEFINE_GETTER_SETTER_BOOL(fast_execution);

//GCC C Extensions
DEFINE_GETTER_SETTER_BOOL(func_attr_flag);

void
CGOptions::set_default_builtin_kinds()
{
Expand Down
6 changes: 6 additions & 0 deletions src/CGOptions.h
Expand Up @@ -457,6 +457,9 @@ class CGOptions {
static bool fast_execution(void);
static bool fast_execution(bool p);

//GCC C Extensions
static bool func_attr_flag(void);
static bool func_attr_flag(bool p);
private:
static bool enabled_builtin_kind(const string &kind);

Expand Down Expand Up @@ -598,6 +601,9 @@ class CGOptions {
// flag to indicate language
static bool lang_cpp_;
static bool cpp11_;

//GCC C Extensions
static bool func_attr_flag_;
private:
CGOptions(void);
CGOptions(CGOptions &cgo);
Expand Down
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Expand Up @@ -53,6 +53,8 @@ set(csmith_SOURCES
AbsRndNumGenerator.h
ArrayVariable.cpp
ArrayVariable.h
Attribute.cpp
Attribute.h
Block.cpp
Block.h
Bookkeeper.cpp
Expand Down
64 changes: 64 additions & 0 deletions src/Function.cpp
Expand Up @@ -66,17 +66,78 @@
#include "DepthSpec.h"
#include "ExtensionMgr.h"
#include "OutputMgr.h"
#include "Attribute.h"

using namespace std;

///////////////////////////////////////////////////////////////////////////////

AttributeGenerator func_attr_generator;
static vector<Function*> FuncList; // List of all functions in the program
static vector<FactMgr*> FMList; // list of fact managers for each function
static long cur_func_idx; // Index into FuncList that we are currently working on
static bool param_first=true; // Flag to track output of commas
static int builtin_functions_cnt;

static std::vector<string> common_func_attributes;
static std::vector<string> visibility_choices;
static std::vector<string> sanitize_choices;

void
InitializeAttributesChoices()
{
//Pushing common function attributes
common_func_attributes.push_back("artificial");
common_func_attributes.push_back("flatten");
common_func_attributes.push_back("no_reorder");
common_func_attributes.push_back("hot");
common_func_attributes.push_back("cold");
common_func_attributes.push_back("noipa");
common_func_attributes.push_back("used");
common_func_attributes.push_back("unused");
common_func_attributes.push_back("nothrow");
common_func_attributes.push_back("deprecated");
common_func_attributes.push_back("no_icf");
common_func_attributes.push_back("no_profile_instrument_function");
common_func_attributes.push_back("no_instrument_function");
common_func_attributes.push_back("no_sanitize_address");
common_func_attributes.push_back("no_sanitize_thread");
common_func_attributes.push_back("no_sanitize_undefined");
common_func_attributes.push_back("no_split_stack");
common_func_attributes.push_back("noinline");
common_func_attributes.push_back("noplt");
common_func_attributes.push_back("stack_protect");

//Pushing visibility choices
visibility_choices.push_back("default");
visibility_choices.push_back("hidden");
visibility_choices.push_back("protected");
visibility_choices.push_back("internal");

//Pushing sanitize choices
sanitize_choices.push_back("address");
sanitize_choices.push_back("thread");
sanitize_choices.push_back("undefined");
sanitize_choices.push_back("kernel-address");
sanitize_choices.push_back("pointer-compare");
sanitize_choices.push_back("pointer-subtract");
sanitize_choices.push_back("leak");
}

void
Function::InitializeAttributes()
{
if(CGOptions::func_attr_flag()){
InitializeAttributesChoices();
vector<string>::iterator itr;
for(itr = common_func_attributes.begin(); itr < common_func_attributes.end(); itr++)
func_attr_generator.attributes.push_back(new BooleanAttribute(*itr, FuncAttrProb));

func_attr_generator.attributes.push_back(new MultiChoiceAttribute("visibility", FuncAttrProb, visibility_choices));
func_attr_generator.attributes.push_back(new MultiChoiceAttribute("no_sanitize", FuncAttrProb, sanitize_choices));
}
}

/*
* find FactMgr for a function
*/
Expand Down Expand Up @@ -481,6 +542,8 @@ Function::make_first(void)

// collect info about global dangling pointers
fm->find_dangling_global_ptrs(f);

f->InitializeAttributes();
return f;
}

Expand Down Expand Up @@ -552,6 +615,7 @@ Function::OutputForwardDecl(std::ostream &out)
if (is_builtin)
return;
OutputHeader(out);
func_attr_generator.Output(out);
out << ";";
outputln(out);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Function.h
Expand Up @@ -122,7 +122,7 @@ class Function
bool is_builtin;
int visited_cnt;
Effect accum_eff_context;

void InitializeAttributes();
private:
static int deleteFunction(Function* func);

Expand Down
2 changes: 2 additions & 0 deletions src/Makefile.am
Expand Up @@ -60,6 +60,8 @@ csmith_SOURCES = \
AbsRndNumGenerator.h \
ArrayVariable.cpp \
ArrayVariable.h \
Attribute.cpp \
Attribute.h \
Block.cpp \
Block.h \
Bookkeeper.cpp \
Expand Down

0 comments on commit 948952c

Please sign in to comment.