Skip to content

Commit

Permalink
[analyzer] Fix wrong builtin_*_overflow return type (llvm#111253)
Browse files Browse the repository at this point in the history
`builtin_*_overflow` functions return `_Bool` according to [1].
`BuiltinFunctionChecker` was using `makeTruthVal` w/o specifying
explicit type, which creates an `int` value, since it's the type of any
compassion according to C standard.

Fix it by directly passing `BoolTy` to `makeTruthVal`

Closes: llvm#111147

[1]
https://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins
  • Loading branch information
pskrgag authored Oct 5, 2024
1 parent 1789534 commit fba6c88
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
11 changes: 6 additions & 5 deletions clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ void BuiltinFunctionChecker::handleOverflowBuiltin(const CallEvent &Call,
ProgramStateRef State = C.getState();
SValBuilder &SVB = C.getSValBuilder();
const Expr *CE = Call.getOriginExpr();
auto BoolTy = C.getASTContext().BoolTy;

SVal Arg1 = Call.getArgSVal(0);
SVal Arg2 = Call.getArgSVal(1);
Expand All @@ -193,8 +194,8 @@ void BuiltinFunctionChecker::handleOverflowBuiltin(const CallEvent &Call,

auto [Overflow, NotOverflow] = checkOverflow(C, RetValMax, ResultType);
if (NotOverflow) {
ProgramStateRef StateNoOverflow =
State->BindExpr(CE, C.getLocationContext(), SVB.makeTruthVal(false));
ProgramStateRef StateNoOverflow = State->BindExpr(
CE, C.getLocationContext(), SVB.makeTruthVal(false, BoolTy));

if (auto L = Call.getArgSVal(2).getAs<Loc>()) {
StateNoOverflow =
Expand All @@ -212,9 +213,9 @@ void BuiltinFunctionChecker::handleOverflowBuiltin(const CallEvent &Call,
}

if (Overflow) {
C.addTransition(
State->BindExpr(CE, C.getLocationContext(), SVB.makeTruthVal(true)),
createBuiltinOverflowNoteTag(C));
C.addTransition(State->BindExpr(CE, C.getLocationContext(),
SVB.makeTruthVal(true, BoolTy)),
createBuiltinOverflowNoteTag(C));
}
}

Expand Down
11 changes: 10 additions & 1 deletion clang/test/Analysis/builtin_overflow.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -verify %s \
// RUN: -analyzer-checker=core,debug.ExprInspection
// RUN: -analyzer-checker=core,debug.ExprInspection,alpha.core.BoolAssignment

#define __UINT_MAX__ (__INT_MAX__ * 2U + 1U)
#define __INT_MIN__ (-__INT_MAX__ - 1)
Expand Down Expand Up @@ -155,3 +155,12 @@ void test_uadd_overflow_contraints(unsigned a, unsigned b)
return;
}
}

void test_bool_assign(void)
{
int res;

// Reproduce issue from GH#111147. __builtin_*_overflow funcions
// should return _Bool, but not int.
_Bool ret = __builtin_mul_overflow(10, 20, &res); // no crash
}

0 comments on commit fba6c88

Please sign in to comment.