|
18 | 18 | #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
|
19 | 19 | #include "llvm/Support/SMTAPI.h"
|
20 | 20 |
|
| 21 | +#include <algorithm> |
| 22 | + |
21 | 23 | namespace clang {
|
22 | 24 | namespace ento {
|
23 | 25 |
|
@@ -570,23 +572,35 @@ class SMTConv {
|
570 | 572 | // TODO: Refactor to put elsewhere
|
571 | 573 | static inline QualType getAPSIntType(ASTContext &Ctx,
|
572 | 574 | const llvm::APSInt &Int) {
|
573 |
| - return Ctx.getIntTypeForBitwidth(Int.getBitWidth(), Int.isSigned()); |
| 575 | + const QualType Ty = |
| 576 | + Ctx.getIntTypeForBitwidth(Int.getBitWidth(), Int.isSigned()); |
| 577 | + if (!Ty.isNull()) |
| 578 | + return Ty; |
| 579 | + // If Ty is Null, could be because the original type was a _BitInt. |
| 580 | + // Get the size of the _BitInt type (expressed in bits) and round it up to |
| 581 | + // the next power of 2 that is at least the bit size of 'char' (usually 8). |
| 582 | + unsigned CharTypeSize = Ctx.getTypeSize(Ctx.CharTy); |
| 583 | + unsigned Pow2DestWidth = |
| 584 | + std::max(llvm::bit_ceil(Int.getBitWidth()), CharTypeSize); |
| 585 | + return Ctx.getIntTypeForBitwidth(Pow2DestWidth, Int.isSigned()); |
574 | 586 | }
|
575 | 587 |
|
576 | 588 | // Get the QualTy for the input APSInt, and fix it if it has a bitwidth of 1.
|
577 | 589 | static inline std::pair<llvm::APSInt, QualType>
|
578 | 590 | fixAPSInt(ASTContext &Ctx, const llvm::APSInt &Int) {
|
579 | 591 | llvm::APSInt NewInt;
|
| 592 | + unsigned APSIntBitwidth = Int.getBitWidth(); |
| 593 | + QualType Ty = getAPSIntType(Ctx, Int); |
580 | 594 |
|
581 | 595 | // FIXME: This should be a cast from a 1-bit integer type to a boolean type,
|
582 | 596 | // but the former is not available in Clang. Instead, extend the APSInt
|
583 | 597 | // directly.
|
584 |
| - if (Int.getBitWidth() == 1 && getAPSIntType(Ctx, Int).isNull()) { |
585 |
| - NewInt = Int.extend(Ctx.getTypeSize(Ctx.BoolTy)); |
586 |
| - } else |
587 |
| - NewInt = Int; |
588 |
| - |
589 |
| - return std::make_pair(NewInt, getAPSIntType(Ctx, NewInt)); |
| 598 | + if (APSIntBitwidth == 1 && Ty.isNull()) |
| 599 | + return {Int.extend(Ctx.getTypeSize(Ctx.BoolTy)), |
| 600 | + getAPSIntType(Ctx, NewInt)}; |
| 601 | + if (llvm::isPowerOf2_32(APSIntBitwidth) || Ty.isNull()) |
| 602 | + return {Int, Ty}; |
| 603 | + return {Int.extend(Ctx.getTypeSize(Ty)), Ty}; |
590 | 604 | }
|
591 | 605 |
|
592 | 606 | // Perform implicit type conversion on binary symbolic expressions.
|
|
0 commit comments