|
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,42 @@ 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 | + QualType Ty = Ctx.getIntTypeForBitwidth(Int.getBitWidth(), Int.isSigned()); |
| 576 | + // If Ty is Null, could be because the original type was a _BitInt. |
| 577 | + // Get the bit size and round up to next power of 2, max char size |
| 578 | + if (Ty.isNull()) { |
| 579 | + unsigned CharTypeSize = Ctx.getTypeSize(Ctx.CharTy); |
| 580 | + unsigned pow2DestWidth = |
| 581 | + std::max(llvm::bit_ceil(Int.getBitWidth()), CharTypeSize); |
| 582 | + Ty = Ctx.getIntTypeForBitwidth(pow2DestWidth, Int.isSigned()); |
| 583 | + } |
| 584 | + return Ty; |
| 585 | + } |
| 586 | + |
| 587 | + static inline bool IsPower2(unsigned bits) { |
| 588 | + return bits > 0 && (bits & (bits - 1)) == 0; |
574 | 589 | }
|
575 | 590 |
|
576 | 591 | // Get the QualTy for the input APSInt, and fix it if it has a bitwidth of 1.
|
577 | 592 | static inline std::pair<llvm::APSInt, QualType>
|
578 | 593 | fixAPSInt(ASTContext &Ctx, const llvm::APSInt &Int) {
|
579 | 594 | llvm::APSInt NewInt;
|
| 595 | + unsigned APSIntBitwidth = Int.getBitWidth(); |
| 596 | + QualType Ty = getAPSIntType(Ctx, Int); |
580 | 597 |
|
581 | 598 | // FIXME: This should be a cast from a 1-bit integer type to a boolean type,
|
582 | 599 | // but the former is not available in Clang. Instead, extend the APSInt
|
583 | 600 | // directly.
|
584 |
| - if (Int.getBitWidth() == 1 && getAPSIntType(Ctx, Int).isNull()) { |
| 601 | + if (APSIntBitwidth == 1 && Ty.isNull()) { |
585 | 602 | NewInt = Int.extend(Ctx.getTypeSize(Ctx.BoolTy));
|
| 603 | + Ty = getAPSIntType(Ctx, NewInt); |
| 604 | + } else if (!IsPower2(APSIntBitwidth) && !getAPSIntType(Ctx, Int).isNull()) { |
| 605 | + Ty = getAPSIntType(Ctx, Int); |
| 606 | + NewInt = Int.extend(Ctx.getTypeSize(Ty)); |
586 | 607 | } else
|
587 | 608 | NewInt = Int;
|
588 | 609 |
|
589 |
| - return std::make_pair(NewInt, getAPSIntType(Ctx, NewInt)); |
| 610 | + return std::make_pair(NewInt, Ty); |
590 | 611 | }
|
591 | 612 |
|
592 | 613 | // Perform implicit type conversion on binary symbolic expressions.
|
|
0 commit comments