GP-2436_fixed_args_varags_functions

This commit is contained in:
James 2022-08-09 16:56:18 +00:00
parent c523b2b9d4
commit 109696fad1
3 changed files with 34 additions and 1 deletions

View file

@ -1443,6 +1443,9 @@ void ActionFuncLink::funcLinkInput(FuncCallSpecs *fc,Funcdata &data)
ProtoParameter *param = fc->getParam(i); ProtoParameter *param = fc->getParam(i);
active->registerTrial(param->getAddress(),param->getSize()); active->registerTrial(param->getAddress(),param->getSize());
active->getTrial(i).markActive(); // Parameter is not optional active->getTrial(i).markActive(); // Parameter is not optional
if (varargs){
active->getTrial(i).setFixedPosition(i);
}
AddrSpace *spc = param->getAddress().getSpace(); AddrSpace *spc = param->getAddress().getSpace();
uintb off = param->getAddress().getOffset(); uintb off = param->getAddress().getOffset();
int4 sz = param->getSize(); int4 sz = param->getSize();

View file

@ -1701,6 +1701,25 @@ bool ParamTrial::operator<(const ParamTrial &b) const
return (size < b.size); return (size < b.size);
} }
/// Sort by fixed position then by ParamTrial::operator<
/// \param a trial
/// \param b trial
/// \return \b true if \b a should be ordered before \b b
bool ParamTrial::fixedPositionCompare(const ParamTrial &a, const ParamTrial &b)
{
if (a.fixedPosition == -1 && b.fixedPosition == -1){
return a < b;
}
if (a.fixedPosition == -1){
return false;
}
if (b.fixedPosition == -1){
return true;
}
return a.fixedPosition < b.fixedPosition;
}
/// \param recoversub selects whether a sub-function or the active function is being tested /// \param recoversub selects whether a sub-function or the active function is being tested
ParamActive::ParamActive(bool recoversub) ParamActive::ParamActive(bool recoversub)
@ -5326,6 +5345,12 @@ void FuncCallSpecs::buildInputFromTrials(Funcdata &data)
newparam.push_back(op->getIn(0)); // Preserve the fspec parameter newparam.push_back(op->getIn(0)); // Preserve the fspec parameter
if (isDotdotdot() && isInputLocked()){
//if varargs, move the fixed args to the beginning of the list in order
//preserve relative order of variable args
activeinput.sortFixedPosition();
}
for(int4 i=0;i<activeinput.getNumTrials();++i) { for(int4 i=0;i<activeinput.getNumTrials();++i) {
const ParamTrial &paramtrial( activeinput.getTrial(i) ); const ParamTrial &paramtrial( activeinput.getTrial(i) );
if (!paramtrial.isUsed()) continue; // Don't keep unused parameters if (!paramtrial.isUsed()) continue; // Don't keep unused parameters

View file

@ -221,9 +221,10 @@ private:
int4 slot; ///< Slot assigned to this trial int4 slot; ///< Slot assigned to this trial
const ParamEntry *entry; ///< PrototypeModel entry matching this trial const ParamEntry *entry; ///< PrototypeModel entry matching this trial
int4 offset; ///< "justified" offset into entry int4 offset; ///< "justified" offset into entry
int4 fixedPosition; ///< argument position if a fixed arg of a varargs function, else -1
public: public:
/// \brief Construct from components /// \brief Construct from components
ParamTrial(const Address &ad,int4 sz,int4 sl) { addr = ad; size = sz; slot = sl; flags=0; entry=(ParamEntry *)0; offset=-1; } ParamTrial(const Address &ad,int4 sz,int4 sl) { addr = ad; size = sz; slot = sl; flags=0; entry=(ParamEntry *)0; offset=-1; fixedPosition = -1; }
const Address &getAddress(void) const { return addr; } ///< Get the starting address of \b this trial const Address &getAddress(void) const { return addr; } ///< Get the starting address of \b this trial
int4 getSize(void) const { return size; } ///< Get the number of bytes in \b this trial int4 getSize(void) const { return size; } ///< Get the number of bytes in \b this trial
int4 getSlot(void) const { return slot; } ///< Get the \e slot associated with \b this trial int4 getSlot(void) const { return slot; } ///< Get the \e slot associated with \b this trial
@ -259,6 +260,8 @@ public:
ParamTrial splitLo(int4 sz) const; ///< Create a trial representing the last part of \b this ParamTrial splitLo(int4 sz) const; ///< Create a trial representing the last part of \b this
bool testShrink(const Address &newaddr,int4 sz) const; ///< Test if \b this trial can be made smaller bool testShrink(const Address &newaddr,int4 sz) const; ///< Test if \b this trial can be made smaller
bool operator<(const ParamTrial &b) const; ///< Sort trials in formal parameter order bool operator<(const ParamTrial &b) const; ///< Sort trials in formal parameter order
void setFixedPosition(int4 pos) { fixedPosition = pos; } ///< Set fixed position
static bool fixedPositionCompare(const ParamTrial &a, const ParamTrial &b); ///< Sort by fixed position; stable for fixedPosition = -1
}; };
/// \brief Container class for ParamTrial objects /// \brief Container class for ParamTrial objects
@ -319,6 +322,8 @@ public:
/// \param addr is the new range's starting address /// \param addr is the new range's starting address
/// \param sz is the new range's size in bytes /// \param sz is the new range's size in bytes
void shrink(int4 i,const Address &addr,int4 sz) { trial[i].setAddress(addr,sz); } void shrink(int4 i,const Address &addr,int4 sz) { trial[i].setAddress(addr,sz); }
void sortFixedPosition(void) {sort(trial.begin(),trial.end(),ParamTrial::fixedPositionCompare);} ///< sort the trials by fixed position then <
}; };
/// \brief A special space for encoding FuncCallSpecs /// \brief A special space for encoding FuncCallSpecs