Skip to content

Commit

Permalink
Fix handling of undef integer values. (#158)
Browse files Browse the repository at this point in the history
* Fix handling of undef integer values. This caused a segfault in rellic previously

* Fix handling for undef integers

* PR Updates

* Fix typos

* Fix unit tests
  • Loading branch information
artemdinaburg authored Jul 16, 2021
1 parent 4832195 commit 7dbd01d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 16 deletions.
10 changes: 8 additions & 2 deletions rellic/AST/ASTBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,16 @@ clang::Expr *ASTBuilder::CreateNull() {
return CreateCStyleCast(ctx.VoidPtrTy, lit);
};

clang::Expr *ASTBuilder::CreateUndef(clang::QualType type) {
clang::Expr *ASTBuilder::CreateUndefInteger(clang::QualType type) {
auto val{llvm::APInt::getNullValue(ctx.getTypeSize(type))};
auto lit{CreateIntLit(val)};
return lit;
};

clang::Expr *ASTBuilder::CreateUndefPointer(clang::QualType type) {
auto null{CreateNull()};
auto cast{CreateCStyleCast(ctx.getPointerType(type), null)};
return CreateDeref(cast);
return cast;
};

clang::IdentifierInfo *ASTBuilder::CreateIdentifier(std::string name) {
Expand Down
3 changes: 2 additions & 1 deletion rellic/AST/ASTBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ class ASTBuilder {
};
// Special values
clang::Expr *CreateNull();
clang::Expr *CreateUndef(clang::QualType type);
clang::Expr *CreateUndefPointer(clang::QualType type);
clang::Expr *CreateUndefInteger(clang::QualType type);
// Identifiers
clang::IdentifierInfo *CreateIdentifier(std::string name);
// Variable declaration
Expand Down
17 changes: 12 additions & 5 deletions rellic/AST/IRToASTVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,26 @@ clang::Expr *IRToASTVisitor::CreateLiteralExpr(llvm::Constant *constant) {
} break;
// Integers
case llvm::Type::IntegerTyID: {
auto val{llvm::cast<llvm::ConstantInt>(constant)->getValue()};
if (val.getBitWidth() == 1U) {
result = ast.CreateIntLit(val);
if (llvm::isa<llvm::ConstantInt>(constant)) {
auto ci = llvm::cast<llvm::ConstantInt>(constant);
auto val{ci->getValue()};
if (val.getBitWidth() == 1U) {
result = ast.CreateIntLit(val);
} else {
result = ast.CreateAdjustedIntLit(val);
}
} else if (llvm::isa<llvm::UndefValue>(constant)) {
result = ast.CreateUndefInteger(c_type);
} else {
result = ast.CreateAdjustedIntLit(val);
LOG(FATAL) << "Unsupported integer constant";
}
} break;

case llvm::Type::PointerTyID: {
if (llvm::isa<llvm::ConstantPointerNull>(constant)) {
result = ast.CreateNull();
} else if (llvm::isa<llvm::UndefValue>(constant)) {
result = ast.CreateUndef(c_type);
result = ast.CreateUndefPointer(c_type);
} else {
LOG(FATAL) << "Unsupported pointer constant";
}
Expand Down
24 changes: 16 additions & 8 deletions unittests/AST/ASTBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,21 +268,29 @@ TEST_SUITE("ASTBuilder::CreateNull") {
}

TEST_SUITE("ASTBuilder::CreateUndef") {
SCENARIO("Create clang::Expr whose value is undefined") {
SCENARIO("Create clang::Expr to stand in for LLVM's 'undef' values") {
GIVEN("Empty clang::ASTContext") {
auto unit{GetASTUnit()};
auto &ctx{unit->getASTContext()};
rellic::ASTBuilder ast(*unit);
GIVEN("an unsigned integer type") {
auto type{ctx.UnsignedIntTy};
THEN(
"return a value that satisfied LLVM's undef semantics (aka "
"anything)") {
auto expr{ast.CreateUndefInteger(type)};
REQUIRE(expr != nullptr);
CHECK(expr->getType() == ctx.UnsignedIntTy);
}
}
GIVEN("an arbitrary type t") {
auto type{ctx.DoubleTy};
THEN("return a null pointer dereference of type t") {
auto expr{ast.CreateUndef(type)};
THEN("return an undef pointer (we use null pointers) of type t") {
auto expr{ast.CreateUndefPointer(type)};
REQUIRE(expr != nullptr);
CHECK(expr->getType() == ctx.DoubleTy);
auto deref{clang::dyn_cast<clang::UnaryOperator>(expr)};
REQUIRE(deref != nullptr);
CHECK(deref->getOpcode() == clang::UO_Deref);
IsNullPtrExprCheck(ctx, deref->getSubExpr()->IgnoreCasts());
auto double_ptr_ty{ctx.getPointerType(ctx.DoubleTy)};
CHECK(expr->getType() == double_ptr_ty);
IsNullPtrExprCheck(ctx, expr->IgnoreCasts());
}
}
}
Expand Down

0 comments on commit 7dbd01d

Please sign in to comment.