Skip to content

Commit a8e9dc4

Browse files
committed
Fixing the allocator issue, #8
1 parent 6bdcacd commit a8e9dc4

File tree

6 files changed

+58
-22
lines changed

6 files changed

+58
-22
lines changed

tools/checked-c-convert/CheckedCConvert.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ cl::opt<bool> enablePropThruIType( "enable-itypeprop",
8484
cl::init(false),
8585
cl::cat(ConvertCategory));
8686

87+
cl::opt<bool> considerAllocUnsafe( "alloc-unsafe",
88+
cl::desc("Consider the allocators (i.e., malloc/calloc) as unsafe."),
89+
cl::init(false),
90+
cl::cat(ConvertCategory));
91+
8792
static cl::opt<std::string>
8893
BaseDir("base-dir",
8994
cl::desc("Base directory for the code we're translating"),

tools/checked-c-convert/ConstraintBuilder.cpp

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -278,27 +278,32 @@ class FunctionVisitor : public RecursiveASTVisitor<FunctionVisitor> {
278278
// to a NamedDecl?
279279
FunctionDecl *calleeDecl =
280280
dyn_cast<FunctionDecl>(CA->getCalleeDecl());
281-
if (calleeDecl && calleeDecl->getName() == "malloc") {
282-
// It's a call to malloc. What about the parameter to the call?
283-
if (CA->getNumArgs() > 0) {
284-
UnaryExprOrTypeTraitExpr *arg =
285-
dyn_cast<UnaryExprOrTypeTraitExpr>(CA->getArg(0));
286-
if (arg && arg->isArgumentType()) {
287-
// Check that the argument is a sizeof.
288-
if (arg->getKind() == UETT_SizeOf) {
289-
QualType argTy = arg->getArgumentType();
290-
// argTy should be made a pointer, then compared for
291-
// equality to lhsType and rhsTy.
292-
QualType argPTy = Context->getPointerType(argTy);
293-
294-
if (Info.checkStructuralEquality(V, RHSConstraints, argPTy, lhsType) &&
295-
Info.checkStructuralEquality(V, RHSConstraints, argPTy, rhsTy)) {
296-
rulesFired = true;
297-
// At present, I don't think we need to add an
298-
// implication based constraint since this rule
299-
// only fires if there is a cast from a call to malloc.
300-
// Since malloc is an external, there's no point in
301-
// adding constraints to it.
281+
if (calleeDecl && isFunctionAllocator(calleeDecl->getName())) {
282+
// this is an allocator, should we treat it as safe?
283+
if(!considerAllocUnsafe) {
284+
rulesFired = true;
285+
} else {
286+
// It's a call to allocator. What about the parameter to the call?
287+
if (CA->getNumArgs() > 0) {
288+
UnaryExprOrTypeTraitExpr *arg =
289+
dyn_cast<UnaryExprOrTypeTraitExpr>(CA->getArg(0));
290+
if (arg && arg->isArgumentType()) {
291+
// Check that the argument is a sizeof.
292+
if (arg->getKind() == UETT_SizeOf) {
293+
QualType argTy = arg->getArgumentType();
294+
// argTy should be made a pointer, then compared for
295+
// equality to lhsType and rhsTy.
296+
QualType argPTy = Context->getPointerType(argTy);
297+
298+
if (Info.checkStructuralEquality(V, RHSConstraints, argPTy, lhsType) &&
299+
Info.checkStructuralEquality(V, RHSConstraints, argPTy, rhsTy)) {
300+
rulesFired = true;
301+
// At present, I don't think we need to add an
302+
// implication based constraint since this rule
303+
// only fires if there is a cast from a call to malloc.
304+
// Since malloc is an external, there's no point in
305+
// adding constraints to it.
306+
}
302307
}
303308
}
304309
}

tools/checked-c-convert/Utils.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,12 @@ bool functionHasVarArgs(clang::FunctionDecl *FD) {
181181
return false;
182182
}
183183

184+
bool isFunctionAllocator(std::string funcName) {
185+
return llvm::StringSwitch<bool>(funcName)
186+
.Cases("malloc", "calloc", "realloc", true)
187+
.Default(false);
188+
}
189+
184190
float getTimeSpentInSeconds(clock_t startTime) {
185191
return float(clock() - startTime)/CLOCKS_PER_SEC;
186192
}

tools/checked-c-convert/Utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ extern llvm::cl::opt<bool> DumpIntermediate;
2929
extern llvm::cl::opt<bool> handleVARARGS;
3030
extern llvm::cl::opt<bool> mergeMultipleFuncDecls;
3131
extern llvm::cl::opt<bool> enablePropThruIType;
32+
extern llvm::cl::opt<bool> considerAllocUnsafe;
3233

3334
const clang::Type *getNextTy(const clang::Type *Ty);
3435

@@ -66,6 +67,5 @@ bool isStructOrUnionType(clang::VarDecl *VD);
6667
// Helper method to print a Type in a way that can be represented in the source.
6768
std::string tyToStr(const clang::Type *T);
6869

69-
7070
clang::SourceLocation getFunctionDeclarationEnd(clang::FunctionDecl *FD, clang::SourceManager &S);
7171
#endif
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <stdlib_checked.h>
2+
3+
int main() {
4+
5+
char *ptr1 = NULL;
6+
7+
ptr1 = (char *) calloc(1, sizeof(char));
8+
9+
return 0;
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <stdlib_checked.h>
2+
3+
int main() {
4+
5+
_Ptr<char> ptr1 = NULL;
6+
7+
ptr1 = (char *) calloc(1, sizeof(char));
8+
9+
return 0;
10+
}

0 commit comments

Comments
 (0)