I 'm trying to create a function in llvm IR which re-assigns all llvm::GlobalVariable to their initial values.
I tried to tackle the problem by first iterating over all llvm::GlobalVariable of an llvm::Module and then, for each llvm::GlobalVariable which has an initializer and isn't a constant, to add to my new function an llvm::StoreInst which will perform the assignment.
My problem is that llvm::GlobalVariable::getInitializer() returns an *llvm::Constant which is a base class and I am unsure of how to get access to the initialization values especially for custom structs and classes. Should I use some sort of downcasting or is there any cleaner solution ?
This is my code so far which compiles well but crashes on runtime: (Assertion `getOperand(1)->getType()->isPointerTy() && "Ptr must have pointer type!"' failed.)
Module::GlobalListType* glist = &M.getGlobalList();
for(auto it=glist->begin(); it!=glist->end(); ++it){
if(it->hasInitializer() && !it->isConstant()){
Constant* con = it->getInitializer();
StoreInst(it, con, RET);//RET is a pointer to an existing instruction.
}
}
Thanks for your time!
Related
I have a Function pass, called firstPass, which does some analysis and populates:
A a;
where
typedef std::map< std::string, B* > A;
class firstPass : public FunctionPass {
A a;
}
typedef std::vector< C* > D;
class B {
D d;
}
class C {
// some class packing information about basic blocks;
}
Hence I have a map of vectors traversed by std::string.
I wrote associated destructors for these classes. This pass works successfully on its own.
I have another Function pass, called secondPass, needing this structure of type A to make some transformations. I used
bool secondPass::doInitialization(Module &M) {
errs() << "now running secondPass\n";
a = getAnalysis<firstPass>().getA();
return false;
}
void secondPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<firstPass>();
AU.setPreservesAll();
}
The whole code compiles fine, but I get a segmentation fault when printing this structure at the end of my first pass only if I call my second pass (since B* is null).
To be clear:
opt -load ./libCustomLLVMPasses.so -passA < someCode.bc
prints in doFinalization() and exits successfully
opt -load ./libCustomLLVMPasses.so -passA -passB < someCode.bc
gives a segmentation fault.
How should I wrap this data structure and pass it to the second pass without issues? I tried std::unique_ptr instead of raw ones but I couldn't make it work. I'm not sure if this is the correct approach anyway, so any help will be appreciated.
EDIT:
I solved the problem of seg. fault. It was basically me calling getAnalysis in doInitialization(). I wrote a ModulePass to combine my firstPass and secondPass whose runOnModule is shown below.
bool MPass::runOnModule(Module &M) {
for(Function& F : M) {
errs() << "F: " << F.getName() << "\n";
if(!F.getName().equals("main") && !F.isDeclaration())
getAnalysis<firstPass>(F);
}
StringRef main = StringRef("main");
A& a = getAnalysis<firstPass>(*(M.getFunction(main))).getA();
return false;
}
This also gave me to control the order of the functions processed.
Now I can get the output of a pass but cannot use it as an input to another pass. I think this shows that the passes in llvm are self-contained.
I'm not going to comment on the quality of the data structures based on their C++ merit (it's hard to comment on that just by this minimal example).
Moreover, I wouldn't use the doInitialization method, if the actual initialization is that simple, but this is a side comment too. (The doc does not mention anything explicitly about it, but if it is ran once per Module while the runOn method is ran on every Function of that module, it might be an issue).
I suspect that the main issue seems to stem from the fact A a in your firstPass is bound to the lifetime of the pass object, which is over once the pass is done. The simplest change would be to allocate that object on the heap (e.g. new) and return a pointer to it when calling getAnalysis<firstPass>().getA();.
Please note that using this approach might require manual cleanup if you decide to use a raw pointer.
I was porting some legacy code to VS 2015 when this compiler error halted the build:
error C3867: 'OptDlg::GetFullModel': non-standard syntax; use '&' to create a pointer to member
Going to the corresponding file and line, I saw this:
Manager mgr = GetDocument()->GetManager();
OptDlg dlg;
...
mgr->SetFullModel(dlg.GetFullModel);
if ( dlg.GetFullModel )
mgr->SetSymm(...
GetFullModeland SetFullModel are the getter/setter pair for a member variable in two different classes:
class Manager {
...
bool GetFullModel() { return m_bFullModel; }
void SetFullModel(bool bFlag) { m_bFullModel = bFlag; }
....
};
class OptDlg {
...
void GetFullModel() { return m_bFullModel; }
void SetFullModel(bool bValue) { m_bFullModel = bValue; if ( bValue ) m_bInside = 0;}
Yep, something's wrong. Was dlg.GetFullModel supposed to be a pointer to a member function? I thought those use the class name, not an instance. Not to mention what that would mean for execution semantics...
C++ is still relatively new to me, so I tried Google. It had a lot on function pointers, but they all looked different from what I had:
&OptDlg::GetFullModel // Standard-compliant
vs
OptDlg::GetFullModel // The "normal" way to mess up getting a pointer to member, it seems
vs
dlg.GetFullModel // ?
Is dlg.GetFullModel just another way of getting a pointer to member function? If not, what is the "standard C++ version", if there is one? Is this just another one of those VS 6 "extensions"?
&OptDlg::GetFullModel // Standard-compliant
If your parameter types were supposed to be taking member functions, that's what you'd use. But they take booleans. It looks like you're just missing parentheses on your function calls, and it should be:
mgr->SetFullModel(dlg.GetFullModel());
if (dlg.GetFullModel())
mgr->SetSymm(...
Probably someone was ignoring warnings (or didn't have them on) and hence a pointer value (being produced through whatever shady means) was always being interpreted as non-NULL, hence boolean true.
Is this just another one of those VS 6 "extensions"?
It would appear to be the case, although this comment is the only documented evidence I can find it was an intentional/advertised "feature". Don't see any formal announcement of it being added or taken out.
It strongly looks to me like someone mis-typed dlg.GetFullModel() (which would call the function), not that they were trying to get a member function pointer.
Presumably the legacy compiler let it slide, taking the address of the function without using & and converting the non-null function pointer to bool (with value true) to pass into the set function.
I have a data structure defined up here called this:
typedef list <classSpec*> ClassSpecList;
I'm trying to add stuff into the list here based on functions that return certain values of that match the same data type. In one function, I have a list pointer object defined here and I have another statement that calls a function.
ClassSpecList *answer = 0;
classSpec *thisanswer = parseClass(br);
Basically I'm trying to add the results of what thisanswer returns into my main ClassSpecList. Problem is, when I try
answer->push_back(new classSpec (*thisanswer));
It compiles but I get a seg fault
When I try somethign else like:
answer->insert(ClassSpecList.begin(), *thisanswer);
I keep getting primary expression errors and I do not know why. I even tried it with other list made without typedef and I still get those.
Thank you.
You should initialize the pointer answer first, like :
ClassSpecList *answer = new ClassSpecList;
then you can add thisAnswer into this list.
This should work:
ClassSpecList *answer = new ClassSpecList;
answer->push_back(thisAnswer);
as should this, which is usually recommended:
ClassSpecList answer;
answer.push_back(thisAnswer);
If possible, parseClass shouldn't return a pointer, and you should use typedef list <classSpec> ClassSpecList;.
Alright, I'm trying to write a program in C++ that deals with a double-linked list. Specifically, the list contains a collection of artwork objects as its nodes. In this particular function, I'm trying to remove nodes through the "sell" command, but I'm getting this error on several lines:
Error: lvalue required as left operand of assignment
I've done my research and I've found that this type of error commonly arises when you try to assign values when you actually want to compare them, or if you're trying to assign values to a constant. However, I don't think that's my problem. Here's the problem code:
// Sell At Function: This function sells the specified artwork.
void CR_ArtCollection::sell_at(string title, ostream& log)
{
CR_ArtWorks* walker = first;
while(walker != NULL)
{
if(title == walker->get_title())
{
walker->get_next()->get_prev() = walker->get_prev(); // Error
walker->get_prev()->get_next() = walker->get_next(); // Error
delete walker;
walker = NULL;
}
else walker = walker->get_next();
}
}
If anyone can point me in the right direction, I would be incredibly appreciative.
It's quite obvious - get_prev and get_next return r-values. That means you can't assign to them.
Check your interface for a method similar to set_next and set_prev and call it as:
walker->get_next()->set_prev(walker->get_prev());
walker->get_prev()->set_next(walker->get_next());
As the names suggest - get_xxxx, those methods are there so you can get the values, not also set them.
Alright, if a function returns a primitive type such as a integer or a pointer it is not legal to assign to the result of the function. That's the error you have.
One possibility would be to change your get_prev and get_next function to return references to pointers.
But I don't suggest you do that. Your code clearly needs redesigning. You should add an erase function to your linked list class. That way the pointer manipulation code will be in the CR_ArtWorks class where it belongs, instead of the CR_ArtCollection class where it doesn't.
(Disclaimer: I have removed the Qt tag in case the problem is in my syntax / understanding of the references involved here)
I have a foreach loop with an object Member. When I enumerate through the list and try to access a member field, the debugger stops and I get a message:
Stopped: 'signal-received' -
The assert failure is:
inline QString::QString(const QString &other) : d(other.d)
{ Q_ASSERT(&other != this); d->ref.ref(); }
I have checked if the member is NULL, and it isn't. I have tried re-working the code, but I keep failing on this simple call.
Some thing's I missed out. MemberList is a singleton (definitely initialized and returns a valid pointer) that is created as the application launches and populates the MemberList with Members from a file. When this is created, there are definitely values, as I print them to qDebug(). This page is literally the next page. I am unsure as to how the List items can be destroyed.
The code is as follows:
int i = 0;
QList<Member*> members = ml->getMembers();
foreach (Member* mem, members)
{
QString memID = mem->getMemberID(); // Crash happens here
QListWidgetItem *lstItem = new QListWidgetItem(memID, lsvMembers);
lsvMembers->insertItem(i, lstItem);
i++;
}
The Member classes get is as follows:
QString getMemberID() const;
and the actual function is:
QString Member::getMemberID() const
{
return MemberID;
}
The ml variable is received as follows:
QList<Member*> MemberList::getMembers()
{
return MemberList::getInstance()->memberList;
}
Where memberList is a private variable.
Final answer:
I decided to rework the singleton completely and found that I was not instantiating a new Member, rather reusing the previous object over and over. This caused the double reference. S'pose thats pointers for you. Special thanks to Troubadour for the effort!
If mem is not null it could still be the case that the pointer is dangling i.e. the Member it was pointing to has been deleted.
If Member inherits from QObject then you could temporarily change your QList<Member*> that is stored in ml (assuming that's what's stored in ml) into a QList< QPointer<Member> >. If you then get a null QPointer in the list after calling getMembers or at any point during the loop then the object must have been destroyed at some point.
Edit
As regards the singleton, are you sure it's initiliased properly? In other words does MemberList::getInstance() return a valid pointer or just a random uninitialised one?
Edit2
Since we've exhausted most possibilities I guess it must be in the singleton somewhere. All I can suggest is to keep querying the first item in the list to find out exactly where it goes bad.