Skip to content

Commit b2d8f0d

Browse files
committed
Fixing the allocator issue, #8
1 parent c0d51dd commit b2d8f0d

File tree

6 files changed

+61
-21
lines changed

6 files changed

+61
-21
lines changed

tools/checked-c-convert/CheckedCConvert.cpp

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

88+
cl::opt<bool> considerAllocUnsafe( "alloc-unsafe",
89+
cl::desc("Consider the allocators (i.e., malloc/calloc) as unsafe."),
90+
cl::init(false),
91+
cl::cat(ConvertCategory));
92+
8893
static cl::opt<std::string>
8994
BaseDir("base-dir",
9095
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
@@ -285,27 +285,32 @@ class FunctionVisitor : public RecursiveASTVisitor<FunctionVisitor> {
285285
// to a NamedDecl?
286286
FunctionDecl *calleeDecl =
287287
dyn_cast<FunctionDecl>(CA->getCalleeDecl());
288-
if (calleeDecl && calleeDecl->getName() == "malloc") {
289-
// It's a call to malloc. What about the parameter to the call?
290-
if (CA->getNumArgs() > 0) {
291-
UnaryExprOrTypeTraitExpr *arg =
292-
dyn_cast<UnaryExprOrTypeTraitExpr>(CA->getArg(0));
293-
if (arg && arg->isArgumentType()) {
294-
// Check that the argument is a sizeof.
295-
if (arg->getKind() == UETT_SizeOf) {
296-
QualType argTy = arg->getArgumentType();
297-
// argTy should be made a pointer, then compared for
298-
// equality to lhsType and rhsTy.
299-
QualType argPTy = Context->getPointerType(argTy);
300-
301-
if (Info.checkStructuralEquality(V, RHSConstraints, argPTy, lhsType) &&
302-
Info.checkStructuralEquality(V, RHSConstraints, argPTy, rhsTy)) {
303-
rulesFired = true;
304-
// At present, I don't think we need to add an
305-
// implication based constraint since this rule
306-
// only fires if there is a cast from a call to malloc.
307-
// Since malloc is an external, there's no point in
308-
// adding constraints to it.
288+
if (calleeDecl && isFunctionAllocator(calleeDecl->getName())) {
289+
// this is an allocator, should we treat it as safe?
290+
if(!considerAllocUnsafe) {
291+
rulesFired = true;
292+
} else {
293+
// It's a call to allocator. What about the parameter to the call?
294+
if (CA->getNumArgs() > 0) {
295+
UnaryExprOrTypeTraitExpr *arg =
296+
dyn_cast<UnaryExprOrTypeTraitExpr>(CA->getArg(0));
297+
if (arg && arg->isArgumentType()) {
298+
// Check that the argument is a sizeof.
299+
if (arg->getKind() == UETT_SizeOf) {
300+
QualType argTy = arg->getArgumentType();
301+
// argTy should be made a pointer, then compared for
302+
// equality to lhsType and rhsTy.
303+
QualType argPTy = Context->getPointerType(argTy);
304+
305+
if (Info.checkStructuralEquality(V, RHSConstraints, argPTy, lhsType) &&
306+
Info.checkStructuralEquality(V, RHSConstraints, argPTy, rhsTy)) {
307+
rulesFired = true;
308+
// At present, I don't think we need to add an
309+
// implication based constraint since this rule
310+
// only fires if there is a cast from a call to malloc.
311+
// Since malloc is an external, there's no point in
312+
// adding constraints to it.
313+
}
309314
}
310315
}
311316
}

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: 4 additions & 0 deletions
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

@@ -54,5 +55,8 @@ float getTimeSpentInSeconds(clock_t startTime);
5455
// check if the function has varargs i.e., foo(<named_arg>,...)
5556
bool functionHasVarArgs(clang::FunctionDecl *FD);
5657

58+
// check if the function is a allocator.
59+
bool isFunctionAllocator(std::string funcName);
60+
5761
clang::SourceLocation getFunctionDeclarationEnd(clang::FunctionDecl *FD, clang::SourceManager &S);
5862
#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)