Skip to content

Commit f44b67d

Browse files
authored
Remove brainTransplant (#463)
* split variable adder and constraint adder passes * populate typedef map during variable adder phase * avoid numparam crash * Add ReasonFailed to brainTransplant; Refactor insertNewFVConstraint * another assert * add tests proto vs body * formatting, clarity * remove xfail from tests, add grep * wording: 'new'->'seen' * more mergefailure reasons * remove calls to braintransplant (regression fail: 80) * split add variable phase at higher level * only save merged FVC (regression fail: 24) * make special case match description * remove code for braintransplant * restore the safety of PragramVariableAdder * first pass comments; assert for backwards merge * second comment pass - usage and defn * add test for #427, now solved
1 parent f4768db commit f44b67d

20 files changed

+280
-244
lines changed

clang/include/clang/3C/3C.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ class _3CInterface {
106106

107107
// Constraint Building.
108108

109+
// Create ConstraintVariables to hold constraints
110+
bool addVariables();
111+
109112
// Build initial constraints.
110113
bool buildInitialConstraints();
111114

clang/include/clang/3C/AVarBoundsInfo.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,6 @@ class AVarBoundsInfo {
214214
// Get the ProgramVar for the provided VarKey.
215215
ProgramVar *getProgramVar(BoundsKey VK);
216216

217-
// Function that does brain transplant of the provided bounds key (NewBK)
218-
// with existing bounds key (OldBK).
219-
void brainTransplant(BoundsKey NewBK, BoundsKey OldBK);
220-
221217
// Propagate the array bounds information for all array ptrs.
222218
bool performFlowAnalysis(ProgramInfo *PI);
223219

clang/include/clang/3C/ConstraintBuilder.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@
1515
#include "clang/3C/TypeVariableAnalysis.h"
1616
#include "clang/AST/ASTConsumer.h"
1717

18+
// First step in generating initial constraints is to collect functions
19+
// and variables the need to be analysed. This will also merge
20+
// function definitions together.
21+
class VariableAdderConsumer : public clang::ASTConsumer {
22+
public:
23+
explicit VariableAdderConsumer(ProgramInfo &I, clang::ASTContext *C)
24+
: Info(I) {}
25+
26+
virtual void HandleTranslationUnit(clang::ASTContext &);
27+
28+
private:
29+
ProgramInfo &Info;
30+
};
31+
32+
// Final step in generating initial constraints is to scan type variables and
33+
// function bodies for relationships that generate the constraints.
1834
class ConstraintBuilderConsumer : public clang::ASTConsumer {
1935
public:
2036
explicit ConstraintBuilderConsumer(ProgramInfo &I, clang::ASTContext *C)

clang/include/clang/3C/ConstraintVariables.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,9 @@ class ConstraintVariable {
136136
// Force use of equality constraints in function calls for this CV
137137
virtual void equateArgumentConstraints(ProgramInfo &I) = 0;
138138

139-
// Update this CV with information from duplicate declaration CVs
140-
virtual void brainTransplant(ConstraintVariable *, ProgramInfo &) = 0;
139+
// Internally combine the constraints and other data from the first parameter
140+
// with this constraint variable. Used with redeclarations, especially of
141+
// functions declared in multiple files.
141142
virtual void mergeDeclaration(ConstraintVariable *, ProgramInfo &,
142143
std::string &ReasonFailed) = 0;
143144

@@ -378,7 +379,7 @@ class PointerVariableConstraint : public ConstraintVariable {
378379

379380
const CAtoms &getCvars() const { return Vars; }
380381

381-
void brainTransplant(ConstraintVariable *From, ProgramInfo &I) override;
382+
// Include new ConstAtoms, supplemental info, and merge function pointers
382383
void mergeDeclaration(ConstraintVariable *From, ProgramInfo &I,
383384
std::string &ReasonFailed) override;
384385

@@ -459,8 +460,6 @@ class FVComponentVariable {
459460

460461
void mergeDeclaration(FVComponentVariable *From, ProgramInfo &I,
461462
std::string &ReasonFailed);
462-
void brainTransplant(FVComponentVariable *From, ProgramInfo &I);
463-
464463
std::string mkItypeStr(const EnvironmentMap &E) const;
465464
std::string mkTypeStr(const EnvironmentMap &E) const;
466465
std::string mkString(const EnvironmentMap &E) const;
@@ -530,7 +529,7 @@ class FunctionVariableConstraint : public ConstraintVariable {
530529
return S->getKind() == FunctionVariable;
531530
}
532531

533-
void brainTransplant(ConstraintVariable *From, ProgramInfo &I) override;
532+
// Merge return value and all params
534533
void mergeDeclaration(ConstraintVariable *FromCV, ProgramInfo &I,
535534
std::string &ReasonFailed) override;
536535

clang/include/clang/3C/ProgramInfo.h

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ class ProgramVariableAdder {
3131
getABoundsInfo().insertVariable(D);
3232
}
3333

34+
virtual bool seenTypedef(PersistentSourceLoc PSL) = 0;
35+
36+
virtual void addTypedef(PersistentSourceLoc PSL, bool ShouldCheck) = 0;
37+
38+
3439
protected:
3540
virtual AVarBoundsInfo &getABoundsInfo() = 0;
3641
};
@@ -166,49 +171,33 @@ class ProgramInfo : public ProgramVariableAdder {
166171
// For each call to a generic function, remember how the type parameters were
167172
// instantiated so they can be inserted during rewriting.
168173
TypeParamBindingsT TypeParamBindings;
169-
170-
// Insert the given FVConstraint* set into the provided Map.
171-
void insertIntoExternalFunctionMap(ExternalFunctionMapType &Map,
172-
const std::string &FuncName,
173-
FVConstraint *NewC, FunctionDecl *FD,
174-
ASTContext *C);
175-
176-
// Inserts the given FVConstraint* set into the provided static map.
177-
void insertIntoStaticFunctionMap(StaticFunctionMapType &Map,
178-
const std::string &FuncName,
179-
const std::string &FileName,
180-
FVConstraint *ToIns, FunctionDecl *FD,
181-
ASTContext *C);
182-
174+
183175
// Special-case handling for decl introductions. For the moment this covers:
184176
// * void-typed variables
185177
// * va_list-typed variables
186178
void specialCaseVarIntros(ValueDecl *D, ASTContext *Context);
187179

188180
// Inserts the given FVConstraint set into the extern or static function map.
189-
// Note: This can trigger a brainTransplant from an existing FVConstraint into
190-
// the argument FVConstraint. The brainTransplant copies the atoms of the
191-
// existing FVConstraint into the argument. This effectively throws out any
192-
// constraints that may been applied to the argument FVConstraint, so do not
193-
// call this function any time other than immediately after constructing an
194-
// FVConstraint.
195-
void insertNewFVConstraint(FunctionDecl *FD, FVConstraint *FVCon,
196-
ASTContext *C);
181+
// Returns the merged version if it was a redeclaration, or the constraint
182+
// parameter if it was new.
183+
FunctionVariableConstraint *
184+
insertNewFVConstraint(FunctionDecl *FD, FVConstraint *FVCon, ASTContext *C);
197185

198186
// Retrieves a FVConstraint* from a Decl (which could be static, or global)
199187
FVConstraint *getFuncFVConstraint(FunctionDecl *FD, ASTContext *C);
200188

201-
// For each pointer type in the declaration of D, add a variable to the
202-
// constraint system for that pointer type.
203-
void addVariable(clang::DeclaratorDecl *D, clang::ASTContext *AstContext);
204-
205189
void insertIntoPtrSourceMap(const PersistentSourceLoc *PSL,
206190
ConstraintVariable *CV);
207191

208192
void computePtrLevelStats();
209193

210194
void insertCVAtoms(ConstraintVariable *CV,
211195
std::map<ConstraintKey, ConstraintVariable *> &AtomMap);
196+
197+
// For each pointer type in the declaration of D, add a variable to the
198+
// constraint system for that pointer type.
199+
void addVariable(clang::DeclaratorDecl *D, clang::ASTContext *AstContext);
200+
212201
};
213202

214203
#endif

clang/lib/3C/3C.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,13 +345,33 @@ _3CInterface::_3CInterface(const struct _3COptions &CCopt,
345345
CurrCompDB = CompDB;
346346
}
347347

348+
bool _3CInterface::addVariables() {
349+
350+
std::lock_guard<std::mutex> Lock(InterfaceMutex);
351+
352+
ClangTool &Tool = getGlobalClangTool();
353+
354+
// 1a. Add Variables.
355+
std::unique_ptr<ToolAction> AdderTool = newFrontendActionFactoryA<
356+
GenericAction<VariableAdderConsumer, ProgramInfo>>(GlobalProgramInfo);
357+
358+
if (AdderTool) {
359+
int ToolExitCode = Tool.run(AdderTool.get());
360+
if (ToolExitCode != 0)
361+
return false;
362+
} else
363+
llvm_unreachable("No action");
364+
365+
return true;
366+
}
367+
348368
bool _3CInterface::buildInitialConstraints() {
349369

350370
std::lock_guard<std::mutex> Lock(InterfaceMutex);
351371

352372
ClangTool &Tool = getGlobalClangTool();
353373

354-
// 1. Gather constraints.
374+
// 1b. Gather constraints.
355375
std::unique_ptr<ToolAction> ConstraintTool = newFrontendActionFactoryA<
356376
GenericAction<ConstraintBuilderConsumer, ProgramInfo>>(GlobalProgramInfo);
357377

clang/lib/3C/AVarBoundsInfo.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -481,14 +481,6 @@ ProgramVar *AVarBoundsInfo::getProgramVar(BoundsKey VK) {
481481
return Ret;
482482
}
483483

484-
void AVarBoundsInfo::brainTransplant(BoundsKey NewBK, BoundsKey OldBK) {
485-
// Here, we use the ProgramVar of NewBK and use it for OldBK.
486-
if (NewBK != OldBK) {
487-
ProgramVar *NewPVar = getProgramVar(NewBK);
488-
insertProgramVar(OldBK, NewPVar);
489-
}
490-
}
491-
492484
bool AVarBoundsInfo::hasVarKey(PersistentSourceLoc &PSL) {
493485
return DeclVarMap.left().find(PSL) != DeclVarMap.left().end();
494486
}

clang/lib/3C/ConstraintBuilder.cpp

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ class FunctionVisitor : public RecursiveASTVisitor<FunctionVisitor> {
269269
constrainConsVarGeq(ParameterDC, ArgumentConstraints, CS, &PL,
270270
Wild_to_Safe, false, &Info, false);
271271

272-
if (AllTypes && TFD != nullptr) {
272+
if (AllTypes && TFD != nullptr && I < TFD->getNumParams()) {
273273
auto *PVD = TFD->getParamDecl(I);
274274
auto &ABI = Info.getABoundsInfo();
275275
// Here, we need to handle context-sensitive assignment.
@@ -479,20 +479,6 @@ class ConstraintGenVisitor : public RecursiveASTVisitor<ConstraintGenVisitor> {
479479
TypeVarInfo &TVI)
480480
: Context(Context), Info(I), CB(Info, Context), TVInfo(TVI), ISD() {}
481481

482-
bool VisitTypedefDecl(TypedefDecl *TD) {
483-
CVarSet Empty;
484-
auto PSL = PersistentSourceLoc::mkPSL(TD, *Context);
485-
// If we haven't seen this typedef before, initialize it's entry in the
486-
// typedef map. If we have seen it before, and we need to preserve the
487-
// constraints contained within it.
488-
if (!Info.seenTypedef(PSL))
489-
// Add this typedef to the program info, if it contains a ptr to
490-
// an anonymous struct we mark as not being rewritable.
491-
Info.addTypedef(PSL, !PtrToStructDef::containsPtrToStructDef(TD));
492-
493-
return true;
494-
}
495-
496482
bool VisitVarDecl(VarDecl *G) {
497483

498484
if (G->hasGlobalStorage() && isPtrOrArrayType(G->getType())) {
@@ -564,7 +550,22 @@ class ConstraintGenVisitor : public RecursiveASTVisitor<ConstraintGenVisitor> {
564550
class VariableAdderVisitor : public RecursiveASTVisitor<VariableAdderVisitor> {
565551
public:
566552
explicit VariableAdderVisitor(ASTContext *Context, ProgramVariableAdder &VA)
567-
: Context(Context), VarAdder(VA) {}
553+
: Context(Context), VarAdder(VA) {}
554+
555+
556+
bool VisitTypedefDecl(TypedefDecl* TD) {
557+
CVarSet empty;
558+
auto PSL = PersistentSourceLoc::mkPSL(TD, *Context);
559+
// If we haven't seen this typedef before, initialize it's entry in the
560+
// typedef map. If we have seen it before, and we need to preserve the
561+
// constraints contained within it
562+
if (!VarAdder.seenTypedef(PSL))
563+
// Add this typedef to the program info, if it contains a ptr to
564+
// an anonymous struct we mark as not being rewritable
565+
VarAdder.addTypedef(PSL, !PtrToStructDef::containsPtrToStructDef(TD));
566+
567+
return true;
568+
}
568569

569570
bool VisitVarDecl(VarDecl *D) {
570571
FullSourceLoc FL = Context->getFullLoc(D->getBeginLoc());
@@ -604,7 +605,7 @@ class VariableAdderVisitor : public RecursiveASTVisitor<VariableAdderVisitor> {
604605
}
605606
};
606607

607-
void ConstraintBuilderConsumer::HandleTranslationUnit(ASTContext &C) {
608+
void VariableAdderConsumer::HandleTranslationUnit(ASTContext &C) {
608609
Info.enterCompilationUnit(C);
609610
if (Verbose) {
610611
SourceManager &SM = C.getSourceManager();
@@ -617,19 +618,45 @@ void ConstraintBuilderConsumer::HandleTranslationUnit(ASTContext &C) {
617618
}
618619

619620
VariableAdderVisitor VAV = VariableAdderVisitor(&C, Info);
621+
TranslationUnitDecl *TUD = C.getTranslationUnitDecl();
622+
// Collect Variables.
623+
for (const auto &D : TUD->decls()) {
624+
VAV.TraverseDecl(D);
625+
}
626+
627+
if (Verbose)
628+
errs() << "Done analyzing\n";
629+
630+
Info.exitCompilationUnit();
631+
return;
632+
}
633+
634+
void ConstraintBuilderConsumer::HandleTranslationUnit(ASTContext &C) {
635+
Info.enterCompilationUnit(C);
636+
if (Verbose) {
637+
SourceManager &SM = C.getSourceManager();
638+
FileID MainFileId = SM.getMainFileID();
639+
const FileEntry *FE = SM.getFileEntryForID(MainFileId);
640+
if (FE != nullptr)
641+
errs() << "Analyzing file " << FE->getName() << "\n";
642+
else
643+
errs() << "Analyzing\n";
644+
}
645+
646+
620647
TypeVarVisitor TV = TypeVarVisitor(&C, Info);
621648
ConstraintResolver CSResolver(Info, &C);
622649
ContextSensitiveBoundsKeyVisitor CSBV =
623650
ContextSensitiveBoundsKeyVisitor(&C, Info);
624651
ConstraintGenVisitor GV = ConstraintGenVisitor(&C, Info, TV);
625652
TranslationUnitDecl *TUD = C.getTranslationUnitDecl();
653+
626654
// Generate constraints.
627655
for (const auto &D : TUD->decls()) {
628-
// The order of these traversals CANNOT be changed because both the type
629-
// variable and constraint gen visitor require that variables have been
630-
// added to ProgramInfo, and the constraint gen visitor requires the type
631-
// variable information gathered in the type variable traversal.
632-
VAV.TraverseDecl(D);
656+
// The order of these traversals CANNOT be changed because the constraint
657+
// gen visitor requires the type variable information gathered in the type
658+
// variable traversal.
659+
633660
CSBV.TraverseDecl(D);
634661
TV.TraverseDecl(D);
635662
GV.TraverseDecl(D);

0 commit comments

Comments
 (0)