Skip to content

Commit 564d7a9

Browse files
authored
Merge pull request #266 from plum-umd/255FixMacros
Fix macro expansion bug
2 parents 5993971 + 107e85d commit 564d7a9

23 files changed

+551
-482
lines changed

clang/include/clang/CConv/AVarBoundsInfo.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,11 @@ class AVarBoundsInfo {
174174
clang::Expr *R,
175175
ASTContext *C,
176176
ConstraintResolver *CR);
177-
bool handleAssignment(clang::Expr *L, CVarSet &LCVars,
178-
clang::Expr *R, CVarSet &RCVars,
177+
bool handleAssignment(clang::Expr *L, const CVarSet &LCVars,
178+
clang::Expr *R, const CVarSet &RCVars,
179179
ASTContext *C, ConstraintResolver *CR);
180-
bool handleAssignment(clang::Decl *L, CVarSet &LCVars,
181-
clang::Expr *R, CVarSet &RCVars,
180+
bool handleAssignment(clang::Decl *L, CVarOption LCVar,
181+
clang::Expr *R, const CVarSet &RCVars,
182182
ASTContext *C, ConstraintResolver *CR);
183183
// Handle context sensitive assignment.
184184
bool handleContextSensitiveAssignment(CallExpr *CE, clang::Decl *L,

clang/include/clang/CConv/CheckedRegions.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ class CheckedRegionFinder : public clang::RecursiveASTVisitor<CheckedRegionFinde
8585
bool containsUncheckedPtr(clang::QualType Qt);
8686
bool containsUncheckedPtrAcc(clang::QualType Qt, std::set<std::string> &Seen);
8787
bool isUncheckedStruct(clang::QualType Qt, std::set<std::string> &Seen);
88-
bool isWild(const std::set<ConstraintVariable*>&);
89-
bool isWild(const std::set<FVConstraint*>*);
88+
bool isWild(CVarOption CVar);
9089

9190
clang::ASTContext* Context;
9291
clang::Rewriter& Writer;

clang/include/clang/CConv/ConstraintResolver.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ class ConstraintResolver {
2626

2727
virtual ~ConstraintResolver();
2828

29-
void constraintAllCVarsToWild(CVarSet &CSet,
30-
std::string rsn,
29+
void constraintAllCVarsToWild(const CVarSet &CSet, const std::string &Rsn,
3130
Expr *AtExpr = nullptr);
31+
void constraintCVarToWild(CVarOption CVar, const std::string &Rsn,
32+
Expr *AtExpr = nullptr);
3233

3334
// Returns a set of ConstraintVariables which represent the result of
3435
// evaluating the expression E. Will explore E recursively, but will
@@ -48,8 +49,8 @@ class ConstraintResolver {
4849
bool containsValidCons(const CVarSet &CVs);
4950
bool isValidCons(ConstraintVariable *CV);
5051
// Try to get the bounds key from the constraint variable set.
51-
bool resolveBoundsKey(CVarSet &CVs, BoundsKey &BK);
52-
bool resolveBoundsKey(ConstraintVariable *CV, BoundsKey &BK);
52+
bool resolveBoundsKey(const CVarSet &CVs, BoundsKey &BK);
53+
bool resolveBoundsKey(CVarOption CV, BoundsKey &BK);
5354

5455
static bool canFunctionBeSkipped(const std::string &FN);
5556

@@ -69,9 +70,7 @@ class ConstraintResolver {
6970

7071
CVarSet getAllSubExprConstraintVars(std::vector<Expr *> &Exprs);
7172
CVarSet getBaseVarPVConstraint(DeclRefExpr *Decl);
72-
bool hasPersistentConstraints(clang::Expr *E);
73-
CVarSet getPersistentConstraints(clang::Expr *E);
74-
void storePersistentConstraints(clang::Expr *E, CVarSet &Vars);
73+
7574
PVConstraint *getRewritablePVConstraint(Expr *E);
7675
};
7776

clang/include/clang/CConv/ConstraintVariables.h

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class ConstraintVariable {
8888
// the name of the variable, false for just the type.
8989
// The 'forIType' parameter is true when the generated string is expected
9090
// to be used inside an itype
91-
virtual std::string mkString(EnvironmentMap &E,
91+
virtual std::string mkString(const EnvironmentMap &E,
9292
bool emitName=true, bool forItype=false,
9393
bool emitPointee=false) const = 0;
9494

@@ -123,20 +123,20 @@ class ConstraintVariable {
123123
// have a binding in E other than top. E should be the EnvironmentMap that
124124
// results from running unification on the set of constraints and the
125125
// environment.
126-
bool isChecked(EnvironmentMap &E) const;
126+
bool isChecked(const EnvironmentMap &E) const;
127127

128128
// Returns true if this constraint variable has a different checked type after
129129
// running unification. Note that if the constraint variable had a checked
130130
// type in the input program, it will have the same checked type after solving
131131
// so, the type will not have changed. To test if the type is checked, use
132132
// isChecked instead.
133-
virtual bool anyChanges(EnvironmentMap &E) const = 0;
133+
virtual bool anyChanges(const EnvironmentMap &E) const = 0;
134134

135135
// Here, AIdx is the pointer level which needs to be checked.
136136
// By default, we check for all pointer levels (or VarAtoms)
137-
virtual bool hasWild(EnvironmentMap &E, int AIdx = -1) const = 0;
138-
virtual bool hasArr(EnvironmentMap &E, int AIdx = -1) const = 0;
139-
virtual bool hasNtArr(EnvironmentMap &E, int AIdx = -1) const = 0;
137+
virtual bool hasWild(const EnvironmentMap &E, int AIdx = -1) const = 0;
138+
virtual bool hasArr(const EnvironmentMap &E, int AIdx = -1) const = 0;
139+
virtual bool hasNtArr(const EnvironmentMap &E, int AIdx = -1) const = 0;
140140

141141
// Force use of equality constraints in function calls for this CV
142142
virtual void equateArgumentConstraints(ProgramInfo &I) = 0;
@@ -158,14 +158,11 @@ class ConstraintVariable {
158158

159159
virtual ~ConstraintVariable() {};
160160

161-
// Sometimes, constraint variables can be produced that are empty. This
162-
// tests for the existence of those constraint variables.
163-
virtual bool isEmpty(void) const = 0;
164-
165161
virtual bool getIsOriginallyChecked() const = 0;
166162
};
167163

168164
typedef std::set<ConstraintVariable *> CVarSet;
165+
typedef Option<ConstraintVariable> CVarOption;
169166

170167
enum ConsAction {
171168
Safe_to_Wild,
@@ -239,6 +236,12 @@ class PointerVariableConstraint : public ConstraintVariable {
239236
bool &AllArray, bool &ArrayRun, bool Nt) const;
240237
void addArrayAnnotations(std::stack<std::string> &CheckedArrs,
241238
std::deque<std::string> &EndStrs) const;
239+
240+
// Utility used by the constructor to extract string representation of the
241+
// base type that preserves macros where possible.
242+
static std::string extractBaseType(DeclaratorDecl *D, QualType QT,
243+
const Type *Ty, const ASTContext &C);
244+
242245
// Flag to indicate that this constraint is a part of function prototype
243246
// e.g., Parameters or Return.
244247
bool partOFFuncPrototype;
@@ -247,7 +250,7 @@ class PointerVariableConstraint : public ConstraintVariable {
247250
// the values used as arguments.
248251
std::set<ConstraintVariable *> argumentConstraints;
249252
// Get solution for the atom of a pointer.
250-
const ConstAtom *getSolution(const Atom *A, EnvironmentMap &E) const;
253+
const ConstAtom *getSolution(const Atom *A, const EnvironmentMap &E) const;
251254

252255
PointerVariableConstraint(PointerVariableConstraint *Ot, Constraints &CS);
253256
PointerVariableConstraint *Parent;
@@ -341,7 +344,7 @@ class PointerVariableConstraint : public ConstraintVariable {
341344
return S->getKind() == PointerVariable;
342345
}
343346

344-
std::string mkString(EnvironmentMap &E, bool EmitName =true,
347+
std::string mkString(const EnvironmentMap &E, bool EmitName =true,
345348
bool ForItype = false,
346349
bool EmitPointee = false) const override;
347350

@@ -355,11 +358,11 @@ class PointerVariableConstraint : public ConstraintVariable {
355358
void constrainToWild(Constraints &CS, const std::string &Rsn,
356359
PersistentSourceLoc *PL) const override;
357360
void constrainOuterTo(Constraints &CS, ConstAtom *C, bool doLB = false);
358-
bool anyChanges(EnvironmentMap &E) const override;
359-
bool anyArgumentIsWild(EnvironmentMap &E);
360-
bool hasWild(EnvironmentMap &E, int AIdx = -1) const override;
361-
bool hasArr(EnvironmentMap &E, int AIdx = -1) const override;
362-
bool hasNtArr(EnvironmentMap &E, int AIdx = -1) const override;
361+
bool anyChanges(const EnvironmentMap &E) const override;
362+
bool anyArgumentIsWild(const EnvironmentMap &E);
363+
bool hasWild(const EnvironmentMap &E, int AIdx = -1) const override;
364+
bool hasArr(const EnvironmentMap &E, int AIdx = -1) const override;
365+
bool hasNtArr(const EnvironmentMap &E, int AIdx = -1) const override;
363366

364367
void equateArgumentConstraints(ProgramInfo &I) override;
365368

@@ -369,8 +372,6 @@ class PointerVariableConstraint : public ConstraintVariable {
369372
// Get the set of constraint variables corresponding to the arguments.
370373
const std::set<ConstraintVariable *> &getArgumentConstraints() const;
371374

372-
bool isEmpty(void) const override { return vars.size() == 0; }
373-
374375
ConstraintVariable *getCopy(Constraints &CS) override;
375376

376377
// Retrieve the atom at the specified index. This function includes special
@@ -461,7 +462,7 @@ class FunctionVariableConstraint : public ConstraintVariable {
461462
bool solutionEqualTo(Constraints &CS,
462463
const ConstraintVariable *CV) const override;
463464

464-
std::string mkString(EnvironmentMap &E, bool EmitName =true,
465+
std::string mkString(const EnvironmentMap &E, bool EmitName =true,
465466
bool ForItype = false,
466467
bool EmitPointee = false) const override;
467468
void print(llvm::raw_ostream &O) const override;
@@ -471,28 +472,15 @@ class FunctionVariableConstraint : public ConstraintVariable {
471472
void constrainToWild(Constraints &CS, const std::string &Rsn) const override;
472473
void constrainToWild(Constraints &CS, const std::string &Rsn,
473474
PersistentSourceLoc *PL) const override;
474-
bool anyChanges(EnvironmentMap &E) const override;
475-
bool hasWild(EnvironmentMap &E, int AIdx = -1) const override;
476-
bool hasArr(EnvironmentMap &E, int AIdx = -1) const override;
477-
bool hasNtArr(EnvironmentMap &E, int AIdx = -1) const override;
475+
bool anyChanges(const EnvironmentMap &E) const override;
476+
bool hasWild(const EnvironmentMap &E, int AIdx = -1) const override;
477+
bool hasArr(const EnvironmentMap &E, int AIdx = -1) const override;
478+
bool hasNtArr(const EnvironmentMap &E, int AIdx = -1) const override;
478479

479480
void equateArgumentConstraints(ProgramInfo &P) override;
480481

481482
ConstraintVariable *getCopy(Constraints &CS) override;
482483

483-
// An FVConstraint is empty if every constraint associated is empty.
484-
bool isEmpty(void) const override {
485-
486-
if (ReturnVar != nullptr)
487-
return false;
488-
489-
for (const auto &u : ParamVars)
490-
if (!u->isEmpty())
491-
return false;
492-
493-
return true;
494-
}
495-
496484
bool getIsOriginallyChecked() const override;
497485

498486
~FunctionVariableConstraint() override {};

clang/include/clang/CConv/Constraints.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ class ConstraintsEnv {
528528

529529
public:
530530
ConstraintsEnv() : consFreeKey(0), useChecked(true) { environment.clear(); }
531-
EnvironmentMap &getVariables() { return environment; }
531+
const EnvironmentMap &getVariables() const { return environment; }
532532
void dump() const;
533533
void print(llvm::raw_ostream &) const;
534534
void dump_json(llvm::raw_ostream &) const;
@@ -572,10 +572,10 @@ class Constraints {
572572
// It's important to return these by reference. Programs can have
573573
// 10-100-100000 constraints and variables, and copying them each time
574574
// a client wants to examine the environment is untenable.
575-
ConstraintSet &getConstraints() { return constraints; }
576-
EnvironmentMap &getVariables() { return environment.getVariables(); }
577-
578-
EnvironmentMap &getitypeVarMap() { return itypeConstraintVars; }
575+
const ConstraintSet &getConstraints() const { return constraints; }
576+
const EnvironmentMap &getVariables() const {
577+
return environment.getVariables();
578+
}
579579

580580
void editConstraintHook(Constraint *C);
581581

@@ -617,11 +617,6 @@ class Constraints {
617617
ConstraintsGraph *PtrTypCG;
618618
std::map<std::string, ConstraintSet> constraintsByReason;
619619
ConstraintsEnv environment;
620-
// Map of constraint variables, which are identified
621-
// as itype pointers
622-
// These should be the constraint variables of only
623-
// function parameters or returns.
624-
EnvironmentMap itypeConstraintVars;
625620

626621
// Confirm a constraint is well-formed
627622
bool check(Constraint *C);

clang/include/clang/CConv/ProgramInfo.h

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,21 @@ class ProgramInfo : public ProgramVariableAdder {
6868
// should all be empty.
6969
void exitCompilationUnit();
7070

71-
CVarSet &getPersistentConstraintVars(Expr *E, ASTContext *AstContext);
71+
bool hasPersistentConstraints(clang::Expr *E, ASTContext *C) const;
72+
const CVarSet &getPersistentConstraints(clang::Expr *E, ASTContext *C) const;
73+
void storePersistentConstraints(clang::Expr *E, const CVarSet &Vars,
74+
ASTContext *C);
75+
7276
// Get constraint variable for the provided Decl
73-
CVarSet getVariable(clang::Decl *D, clang::ASTContext *C);
77+
CVarOption getVariable(clang::Decl *D, clang::ASTContext *C);
7478

7579
// Retrieve a function's constraints by decl, or by name; nullptr if not found
7680
FVConstraint *getFuncConstraint (FunctionDecl *D, ASTContext *C) const;
7781
FVConstraint *getExtFuncDefnConstraint (std::string FuncName) const;
7882
FVConstraint *getStaticFuncConstraint(std::string FuncName,
7983
std::string FileName) const;
8084

85+
8186
// Check if the given function is an extern function.
8287
bool isAnExternFunction(const std::string &FName);
8388

@@ -86,7 +91,7 @@ class ProgramInfo : public ProgramVariableAdder {
8691
// constraints where appropriate.
8792
bool link();
8893

89-
VariableMap &getVarMap() { return Variables; }
94+
const VariableMap &getVarMap() const { return Variables; }
9095
Constraints &getConstraints() { return CS; }
9196
AVarBoundsInfo &getABoundsInfo() { return ArrBInfo; }
9297

@@ -109,13 +114,18 @@ class ProgramInfo : public ProgramVariableAdder {
109114
const CallTypeParamBindingsT &getTypeParamBindings(CallExpr *CE,
110115
ASTContext *C) const;
111116

112-
void constrainWildIfMacro(CVarSet &S, SourceLocation Location);
117+
void constrainWildIfMacro(ConstraintVariable *CV, SourceLocation Location);
113118

114119
private:
115-
// List of all constraint variables, indexed by their location in the source.
116-
// This information persists across invocations of the constraint analysis
117-
// from compilation unit to compilation unit.
120+
// List of constraint variables for declarations, indexed by their location in
121+
// the source. This information persists across invocations of the constraint
122+
// analysis from compilation unit to compilation unit.
118123
VariableMap Variables;
124+
125+
// Map with the same purpose as the Variables map, this stores constraint
126+
// variables for non-declaration expressions.
127+
std::map<PersistentSourceLoc, CVarSet> ExprConstraintVars;
128+
119129
// Constraint system.
120130
Constraints CS;
121131
// Is the ProgramInfo persisted? Only tested in asserts. Starts at true.
@@ -132,8 +142,7 @@ class ProgramInfo : public ProgramVariableAdder {
132142
StaticFunctionMapType StaticFunctionFVCons;
133143
std::map<std::string, std::set<PVConstraint *>> GlobalVariableSymbols;
134144

135-
// Object that contains all the bounds information of various
136-
// array variables.
145+
// Object that contains all the bounds information of various array variables.
137146
AVarBoundsInfo ArrBInfo;
138147
// Constraints state.
139148
ConstraintsInfo CState;
@@ -142,9 +151,8 @@ class ProgramInfo : public ProgramVariableAdder {
142151
// instantiated so they can be inserted during rewriting.
143152
TypeParamBindingsT TypeParamBindings;
144153

145-
// Function to check if an external symbol is okay to leave
146-
// constrained.
147-
bool isExternOkay(std::string Ext);
154+
// Function to check if an external symbol is okay to leave constrained.
155+
bool isExternOkay(const std::string &Ext);
148156

149157
// Insert the given FVConstraint* set into the provided Map.
150158
// Returns true if successful else false.
@@ -175,7 +183,7 @@ class ProgramInfo : public ProgramVariableAdder {
175183

176184
// For each pointer type in the declaration of D, add a variable to the
177185
// constraint system for that pointer type.
178-
void addVariable(clang::DeclaratorDecl *D, clang::ASTContext *astContext);
186+
void addVariable(clang::DeclaratorDecl *D, clang::ASTContext *AstContext);
179187
};
180188

181189
#endif

clang/include/clang/CConv/RewriteUtils.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class DeclReplacement {
2828

2929
std::string getReplacement() const { return Replacement; }
3030

31-
virtual SourceRange getSourceRange() const {
31+
virtual SourceRange getSourceRange(SourceManager &SM) const {
3232
return getDecl()->getSourceRange();
3333
}
3434

@@ -93,10 +93,13 @@ class FunctionDeclReplacement :
9393
&& (RewriteReturn || RewriteParams));
9494
}
9595

96-
SourceRange getSourceRange() const override {
97-
FunctionTypeLoc TypeLoc =
98-
getBaseTypeLoc(Decl->getTypeSourceInfo()->getTypeLoc())
99-
.getAs<clang::FunctionTypeLoc>();
96+
SourceRange getSourceRange(SourceManager &SM) const override {
97+
TypeSourceInfo *TSInfo = Decl->getTypeSourceInfo();
98+
if (!TSInfo)
99+
return SourceRange(Decl->getBeginLoc(),
100+
getFunctionDeclarationEnd(Decl, SM));
101+
FunctionTypeLoc TypeLoc = getBaseTypeLoc(TSInfo->getTypeLoc())
102+
.getAs<clang::FunctionTypeLoc>();
100103

101104
assert("FunctionDecl doesn't have function type?" && !TypeLoc.isNull());
102105

clang/include/clang/CConv/Utils.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,32 @@ class ConstraintVariable;
2626
class ProgramInfo;
2727

2828
// Maps a Decl to the set of constraint variables for that Decl.
29-
typedef std::map<PersistentSourceLoc,
30-
std::set<ConstraintVariable *>> VariableMap;
29+
typedef std::map<PersistentSourceLoc, ConstraintVariable *> VariableMap;
3130

3231
// Maps a Decl to the DeclStmt that defines the Decl.
3332
typedef std::map<clang::Decl *, clang::DeclStmt *> VariableDecltoStmtMap;
3433

34+
template<typename ValueT>
35+
class Option {
36+
public:
37+
Option() : Value(nullptr), HasValue(false) {}
38+
Option(ValueT &V) : Value(&V), HasValue(true) {}
39+
40+
ValueT &getValue() const {
41+
assert("Inconsistent option!" && HasValue && Value != nullptr);
42+
return *Value;
43+
}
44+
45+
bool hasValue() const {
46+
assert("Inconsistent option!" && HasValue == (Value != nullptr));
47+
return HasValue;
48+
}
49+
50+
private:
51+
ValueT *Value;
52+
bool HasValue;
53+
};
54+
3555
// Replacement for boost:bimap. A wrapper class around two std::maps to enable
3656
// map lookup from key to value or from value to key.
3757
template <typename KeyT, typename ValueT>

0 commit comments

Comments
 (0)