Skip to content

Commit 6bdcacd

Browse files
committed
Fix for the issue: #3
1 parent 76b2cda commit 6bdcacd

File tree

6 files changed

+101
-13
lines changed

6 files changed

+101
-13
lines changed

tools/checked-c-convert/ConstraintVariables.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,6 @@
1616

1717
using namespace clang;
1818

19-
// Helper method to print a Type in a way that can be represented in the source.
20-
static
21-
std::string
22-
tyToStr(const Type *T) {
23-
QualType QT(T, 0);
24-
25-
return QT.getAsString();
26-
}
27-
2819
PointerVariableConstraint::PointerVariableConstraint(DeclaratorDecl *D,
2920
ConstraintKey &K, Constraints &CS, const ASTContext &C) :
3021
PointerVariableConstraint(D->getType(), K, D, D->getName(), CS, C) { }

tools/checked-c-convert/RewriteUtils.cpp

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,83 @@ class DeclArrayVisitor : public clang::RecursiveASTVisitor<DeclArrayVisitor>
758758
ProgramInfo& Info;
759759
};
760760

761+
// This class initializes all the structure variables that
762+
// contains at least one checked pointer?
763+
class StructVariableInitializer : public clang::RecursiveASTVisitor<StructVariableInitializer>
764+
{
765+
public:
766+
explicit StructVariableInitializer(ASTContext *_C, ProgramInfo &_I, RSet &R)
767+
: Context(_C), I(_I), RewriteThese(R)
768+
{
769+
RecordsWithCPointers.clear();
770+
}
771+
772+
bool VariableNeedsInitializer(VarDecl *VD, DeclStmt *S) {
773+
RecordDecl *RD = VD->getType().getTypePtr()->getAsRecordDecl();
774+
if (RecordDecl *Definition = RD->getDefinition()) {
775+
// see if we already know that this structure has a checked pointer.
776+
if(RecordsWithCPointers.find(Definition) != RecordsWithCPointers.end()) {
777+
return true;
778+
}
779+
for (const auto &D : Definition->fields()) {
780+
if (D->getType()->isPointerType() || D->getType()->isArrayType()) {
781+
std::set<ConstraintVariable *> fieldConsVars = I.getVariable(D, Context, false);
782+
for (auto CV: fieldConsVars) {
783+
PVConstraint *PV = dyn_cast<PVConstraint>(CV);
784+
if (PV && PV->anyChanges(I.getConstraints().getVariables())) {
785+
// ok this contains a pointer that is checked.
786+
// store it.
787+
RecordsWithCPointers.insert(Definition);
788+
return true;
789+
}
790+
}
791+
}
792+
}
793+
}
794+
return false;
795+
}
796+
797+
// check to see if this variable require an initialization.
798+
bool VisitDeclStmt(DeclStmt *S) {
799+
800+
std::set<VarDecl*> allDecls;
801+
802+
if (S->isSingleDecl()) {
803+
if (VarDecl *VD = dyn_cast<VarDecl>(S->getSingleDecl())) {
804+
allDecls.insert(VD);
805+
}
806+
} else {
807+
for (const auto &D : S->decls()) {
808+
if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
809+
allDecls.insert(VD);
810+
}
811+
}
812+
}
813+
814+
for(auto VD: allDecls) {
815+
// check if this variable is a structure or union and doesn't have an initializer.
816+
if(!VD->hasInit() && isStructOrUnionType(VD)) {
817+
// check if the variable needs a initializer.
818+
if(VariableNeedsInitializer(VD, S)) {
819+
const clang::Type *Ty = VD->getType().getTypePtr();
820+
std::string OriginalType = tyToStr(Ty);
821+
// create replacement text with an initializer.
822+
std::string toReplace = OriginalType + " " + VD->getName().str() + " = {}";
823+
RewriteThese.insert(DAndReplace(VD, S, toReplace));
824+
}
825+
}
826+
}
827+
828+
return true;
829+
}
830+
private:
831+
ASTContext* Context;
832+
ProgramInfo &I;
833+
RSet &RewriteThese;
834+
std::set<RecordDecl*> RecordsWithCPointers;
835+
836+
};
837+
761838
std::map<std::string, std::string> RewriteConsumer::ModifiedFuncSignatures;
762839

763840
std::string RewriteConsumer::getModifiedFuncSignature(std::string funcName) {
@@ -799,8 +876,11 @@ void RewriteConsumer::HandleTranslationUnit(ASTContext &Context) {
799876
RSet skip(DComp(Context.getSourceManager()));
800877
MappingVisitor V(keys, Context);
801878
TranslationUnitDecl *TUD = Context.getTranslationUnitDecl();
802-
for (const auto &D : TUD->decls())
879+
StructVariableInitializer FV = StructVariableInitializer(&Context, Info, rewriteThese);
880+
for (auto &D : TUD->decls()) {
803881
V.TraverseDecl(D);
882+
FV.TraverseDecl(D);
883+
}
804884

805885
std::tie(PSLMap, VDLToStmtMap) = V.getResults();
806886

tools/checked-c-convert/Utils.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,13 @@ float getTimeSpentInSeconds(clock_t startTime) {
187187

188188
bool isPointerType(clang::VarDecl *VD) {
189189
return VD->getType().getTypePtr()->isPointerType();
190+
}
191+
192+
bool isStructOrUnionType(clang::VarDecl *VD) {
193+
return VD->getType().getTypePtr()->isStructureType() || VD->getType().getTypePtr()->isUnionType();
194+
}
195+
196+
std::string tyToStr(const Type *T) {
197+
QualType QT(T, 0);
198+
return QT.getAsString();
190199
}

tools/checked-c-convert/Utils.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define _UTILS_H
1111
#include <set>
1212
#include "llvm/Support/CommandLine.h"
13+
#include "clang/AST/Type.h"
1314

1415
#include "PersistentSourceLoc.h"
1516

@@ -59,5 +60,12 @@ bool isFunctionAllocator(std::string funcName);
5960
// Is the given variable built in type?
6061
bool isPointerType(clang::VarDecl *VD);
6162

63+
// check if the variable is of a structure or union type.
64+
bool isStructOrUnionType(clang::VarDecl *VD);
65+
66+
// Helper method to print a Type in a way that can be represented in the source.
67+
std::string tyToStr(const clang::Type *T);
68+
69+
6270
clang::SourceLocation getFunctionDeclarationEnd(clang::FunctionDecl *FD, clang::SourceManager &S);
6371
#endif

tools/checked-c-convert/functests/ntarr/basic_field_local.expected.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ typedef struct {
2020
} foo3;
2121

2222
int main() {
23-
foo obj;
23+
foo obj = {};
2424
_Nt_array_ptr<char> bp = NULL;
2525
float b;
2626
foo2 obj2;

tools/checked-c-convert/functests/ptr/basic_field_local.expected.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ typedef struct {
1818
char d;
1919
} foo3;
2020
int main() {
21-
foo obj;
21+
foo obj = {};
2222
float b;
23-
foo2 obj2;
23+
foo2 obj2 = {};
2424
obj2.b = &b;
2525
foo3 obj3;
2626
obj3.p = 0xcafebabe;

0 commit comments

Comments
 (0)