Skip to content

Commit b5b4379

Browse files
authored
Merge branch 'main' into filter-unknown-class-of-address-through-FixAny-method
2 parents bf1838f + 1d5d125 commit b5b4379

File tree

13 files changed

+170
-87
lines changed

13 files changed

+170
-87
lines changed

clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,26 @@ using namespace clang::ast_matchers;
1515
namespace clang::tidy::cppcoreguidelines {
1616

1717
void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) {
18-
if (!getLangOpts().CPlusPlus)
19-
return;
20-
2118
const auto AllPointerTypes =
22-
anyOf(hasType(pointerType()),
19+
anyOf(hasType(hasUnqualifiedDesugaredType(pointerType())),
2320
hasType(autoType(
2421
hasDeducedType(hasUnqualifiedDesugaredType(pointerType())))),
2522
hasType(decltypeType(hasUnderlyingType(pointerType()))));
2623

27-
// Flag all operators +, -, +=, -=, ++, -- that result in a pointer
24+
// Flag all operators +, -, +=, -= that result in a pointer
2825
Finder->addMatcher(
2926
binaryOperator(
3027
hasAnyOperatorName("+", "-", "+=", "-="), AllPointerTypes,
3128
unless(hasLHS(ignoringImpCasts(declRefExpr(to(isImplicit()))))))
3229
.bind("expr"),
3330
this);
3431

32+
// Flag all operators ++, -- that result in a pointer
3533
Finder->addMatcher(
36-
unaryOperator(hasAnyOperatorName("++", "--"), hasType(pointerType()))
34+
unaryOperator(hasAnyOperatorName("++", "--"),
35+
hasType(hasUnqualifiedDesugaredType(pointerType())),
36+
unless(hasUnaryOperand(
37+
ignoringImpCasts(declRefExpr(to(isImplicit()))))))
3738
.bind("expr"),
3839
this);
3940

clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ class ProBoundsPointerArithmeticCheck : public ClangTidyCheck {
2323
public:
2424
ProBoundsPointerArithmeticCheck(StringRef Name, ClangTidyContext *Context)
2525
: ClangTidyCheck(Name, Context) {}
26+
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
27+
return LangOpts.CPlusPlus;
28+
}
2629
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
2730
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
2831
};

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ Changes in existing checks
219219
- Improved :doc:`cppcoreguidelines-pro-bounds-pointer-arithmetic
220220
<clang-tidy/checks/cppcoreguidelines/pro-bounds-pointer-arithmetic>` check by
221221
fixing false positives when calling indexing operators that do not perform
222-
pointer arithmetic in template, for example ``std::map::operator[]``.
222+
pointer arithmetic in template, for example ``std::map::operator[]`` and
223+
when pointer arithmetic was used through type aliases.
223224

224225
- Improved :doc:`cppcoreguidelines-rvalue-reference-param-not-moved
225226
<clang-tidy/checks/cppcoreguidelines/rvalue-reference-param-not-moved>` check

clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic-pr36489.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
// RUN: %check_clang_tidy -std=c++14-or-later %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
22

33
// Fix PR36489 and detect auto-deduced value correctly.
4+
typedef char* charPtr;
5+
46
char *getPtr();
57
auto getPtrAuto() { return getPtr(); }
68
decltype(getPtr()) getPtrDeclType();
79
decltype(auto) getPtrDeclTypeAuto() { return getPtr(); }
810
auto getPtrWithTrailingReturnType() -> char *;
11+
charPtr getCharPtr() { return getPtr(); }
912

1013
void auto_deduction_binary() {
1114
auto p1 = getPtr() + 1;
@@ -28,6 +31,10 @@ void auto_deduction_binary() {
2831
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: do not use pointer arithmetic
2932
auto *p9 = getPtrDeclTypeAuto() + 1;
3033
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: do not use pointer arithmetic
34+
auto p10 = getCharPtr() + 1;
35+
// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: do not use pointer
36+
auto* p11 = getCharPtr() + 1;
37+
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: do not use pointer arithmetic
3138
}
3239

3340
void auto_deduction_subscript() {
@@ -50,4 +57,6 @@ void auto_deduction_subscript() {
5057
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
5158
auto p8 = getPtrDeclTypeAuto()[9];
5259
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
60+
auto p9 = getCharPtr()[10];
61+
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
5362
}

clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-bounds-pointer-arithmetic.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ enum E {
44
ENUM_LITERAL = 1
55
};
66

7+
typedef int* IntPtr;
8+
79
int i = 4;
810
int j = 1;
911
int *p = 0;
1012
int *q = 0;
13+
IntPtr ip = 0;
1114

1215
void fail() {
1316
q = p + 4;
@@ -50,6 +53,32 @@ void fail() {
5053

5154
i = p[1];
5255
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
56+
57+
p = ip + 1;
58+
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: do not use pointer arithmetic
59+
ip++;
60+
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
61+
i = ip[1];
62+
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
63+
}
64+
65+
template <typename T>
66+
void template_fail() {
67+
T* p;
68+
T* q;
69+
70+
p = q + 1;
71+
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
72+
q = p - 1;
73+
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
74+
p++;
75+
// CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
76+
i = p[1];
77+
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
78+
}
79+
80+
void instantiate() {
81+
template_fail<int>();
5382
}
5483

5584
struct S {

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,9 @@ LLVM_ABI bool isGuaranteedToExecuteForEveryIteration(const Instruction *I,
727727
/// getGuaranteedNonPoisonOp.
728728
LLVM_ABI bool propagatesPoison(const Use &PoisonOp);
729729

730+
/// Return whether this intrinsic propagates poison for all operands.
731+
LLVM_ABI bool intrinsicPropagatesPoison(Intrinsic::ID IID);
732+
730733
/// Return true if the given instruction must trigger undefined behavior
731734
/// when I is executed with any operands which appear in KnownPoison holding
732735
/// a poison value at the point of execution.

llvm/lib/Analysis/ConstantFolding.cpp

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2229,17 +2229,6 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
22292229
return nullptr;
22302230
}
22312231

2232-
if (isa<PoisonValue>(Operands[0])) {
2233-
// TODO: All of these operations should probably propagate poison.
2234-
switch (IntrinsicID) {
2235-
case Intrinsic::canonicalize:
2236-
case Intrinsic::sqrt:
2237-
return PoisonValue::get(Ty);
2238-
default:
2239-
break;
2240-
}
2241-
}
2242-
22432232
if (isa<UndefValue>(Operands[0])) {
22442233
// cosine(arg) is between -1 and 1. cosine(invalid arg) is NaN.
22452234
// ctpop() is between 0 and bitwidth, pick 0 for undef.
@@ -3228,11 +3217,6 @@ static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
32283217
case Intrinsic::smin:
32293218
case Intrinsic::umax:
32303219
case Intrinsic::umin:
3231-
// This is the same as for binary ops - poison propagates.
3232-
// TODO: Poison handling should be consolidated.
3233-
if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
3234-
return PoisonValue::get(Ty);
3235-
32363220
if (!C0 && !C1)
32373221
return UndefValue::get(Ty);
32383222
if (!C0 || !C1)
@@ -3245,9 +3229,6 @@ static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
32453229

32463230
case Intrinsic::scmp:
32473231
case Intrinsic::ucmp:
3248-
if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
3249-
return PoisonValue::get(Ty);
3250-
32513232
if (!C0 || !C1)
32523233
return ConstantInt::get(Ty, 0);
32533234

@@ -3314,11 +3295,6 @@ static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
33143295
}
33153296
case Intrinsic::uadd_sat:
33163297
case Intrinsic::sadd_sat:
3317-
// This is the same as for binary ops - poison propagates.
3318-
// TODO: Poison handling should be consolidated.
3319-
if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
3320-
return PoisonValue::get(Ty);
3321-
33223298
if (!C0 && !C1)
33233299
return UndefValue::get(Ty);
33243300
if (!C0 || !C1)
@@ -3329,11 +3305,6 @@ static Constant *ConstantFoldIntrinsicCall2(Intrinsic::ID IntrinsicID, Type *Ty,
33293305
return ConstantInt::get(Ty, C0->sadd_sat(*C1));
33303306
case Intrinsic::usub_sat:
33313307
case Intrinsic::ssub_sat:
3332-
// This is the same as for binary ops - poison propagates.
3333-
// TODO: Poison handling should be consolidated.
3334-
if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
3335-
return PoisonValue::get(Ty);
3336-
33373308
if (!C0 && !C1)
33383309
return UndefValue::get(Ty);
33393310
if (!C0 || !C1)
@@ -3592,11 +3563,6 @@ static Constant *ConstantFoldScalarCall3(StringRef Name,
35923563

35933564
if (IntrinsicID == Intrinsic::smul_fix ||
35943565
IntrinsicID == Intrinsic::smul_fix_sat) {
3595-
// poison * C -> poison
3596-
// C * poison -> poison
3597-
if (isa<PoisonValue>(Operands[0]) || isa<PoisonValue>(Operands[1]))
3598-
return PoisonValue::get(Ty);
3599-
36003566
const APInt *C0, *C1;
36013567
if (!getConstIntOrUndef(Operands[0], C0) ||
36023568
!getConstIntOrUndef(Operands[1], C1))
@@ -3670,6 +3636,11 @@ static Constant *ConstantFoldScalarCall(StringRef Name,
36703636
ArrayRef<Constant *> Operands,
36713637
const TargetLibraryInfo *TLI,
36723638
const CallBase *Call) {
3639+
if (IntrinsicID != Intrinsic::not_intrinsic &&
3640+
any_of(Operands, IsaPred<PoisonValue>) &&
3641+
intrinsicPropagatesPoison(IntrinsicID))
3642+
return PoisonValue::get(Ty);
3643+
36733644
if (Operands.size() == 1)
36743645
return ConstantFoldScalarCall1(Name, IntrinsicID, Ty, Operands, TLI, Call);
36753646

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7879,6 +7879,47 @@ bool llvm::isGuaranteedToExecuteForEveryIteration(const Instruction *I,
78797879
llvm_unreachable("Instruction not contained in its own parent basic block.");
78807880
}
78817881

7882+
bool llvm::intrinsicPropagatesPoison(Intrinsic::ID IID) {
7883+
switch (IID) {
7884+
// TODO: Add more intrinsics.
7885+
case Intrinsic::sadd_with_overflow:
7886+
case Intrinsic::ssub_with_overflow:
7887+
case Intrinsic::smul_with_overflow:
7888+
case Intrinsic::uadd_with_overflow:
7889+
case Intrinsic::usub_with_overflow:
7890+
case Intrinsic::umul_with_overflow:
7891+
// If an input is a vector containing a poison element, the
7892+
// two output vectors (calculated results, overflow bits)'
7893+
// corresponding lanes are poison.
7894+
return true;
7895+
case Intrinsic::ctpop:
7896+
case Intrinsic::ctlz:
7897+
case Intrinsic::cttz:
7898+
case Intrinsic::abs:
7899+
case Intrinsic::smax:
7900+
case Intrinsic::smin:
7901+
case Intrinsic::umax:
7902+
case Intrinsic::umin:
7903+
case Intrinsic::scmp:
7904+
case Intrinsic::ucmp:
7905+
case Intrinsic::bitreverse:
7906+
case Intrinsic::bswap:
7907+
case Intrinsic::sadd_sat:
7908+
case Intrinsic::ssub_sat:
7909+
case Intrinsic::sshl_sat:
7910+
case Intrinsic::uadd_sat:
7911+
case Intrinsic::usub_sat:
7912+
case Intrinsic::ushl_sat:
7913+
case Intrinsic::smul_fix:
7914+
case Intrinsic::smul_fix_sat:
7915+
case Intrinsic::canonicalize:
7916+
case Intrinsic::sqrt:
7917+
return true;
7918+
default:
7919+
return false;
7920+
}
7921+
}
7922+
78827923
bool llvm::propagatesPoison(const Use &PoisonOp) {
78837924
const Operator *I = cast<Operator>(PoisonOp.getUser());
78847925
switch (I->getOpcode()) {
@@ -7889,38 +7930,8 @@ bool llvm::propagatesPoison(const Use &PoisonOp) {
78897930
case Instruction::Select:
78907931
return PoisonOp.getOperandNo() == 0;
78917932
case Instruction::Call:
7892-
if (auto *II = dyn_cast<IntrinsicInst>(I)) {
7893-
switch (II->getIntrinsicID()) {
7894-
// TODO: Add more intrinsics.
7895-
case Intrinsic::sadd_with_overflow:
7896-
case Intrinsic::ssub_with_overflow:
7897-
case Intrinsic::smul_with_overflow:
7898-
case Intrinsic::uadd_with_overflow:
7899-
case Intrinsic::usub_with_overflow:
7900-
case Intrinsic::umul_with_overflow:
7901-
// If an input is a vector containing a poison element, the
7902-
// two output vectors (calculated results, overflow bits)'
7903-
// corresponding lanes are poison.
7904-
return true;
7905-
case Intrinsic::ctpop:
7906-
case Intrinsic::ctlz:
7907-
case Intrinsic::cttz:
7908-
case Intrinsic::abs:
7909-
case Intrinsic::smax:
7910-
case Intrinsic::smin:
7911-
case Intrinsic::umax:
7912-
case Intrinsic::umin:
7913-
case Intrinsic::bitreverse:
7914-
case Intrinsic::bswap:
7915-
case Intrinsic::sadd_sat:
7916-
case Intrinsic::ssub_sat:
7917-
case Intrinsic::sshl_sat:
7918-
case Intrinsic::uadd_sat:
7919-
case Intrinsic::usub_sat:
7920-
case Intrinsic::ushl_sat:
7921-
return true;
7922-
}
7923-
}
7933+
if (auto *II = dyn_cast<IntrinsicInst>(I))
7934+
return intrinsicPropagatesPoison(II->getIntrinsicID());
79247935
return false;
79257936
case Instruction::ICmp:
79267937
case Instruction::FCmp:

llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,8 @@ getOperandLog2EEW(const MachineOperand &MO, const MachineRegisterInfo *MRI) {
517517
case RISCV::VWSUB_VV:
518518
case RISCV::VWSUB_VX:
519519
case RISCV::VWSLL_VI:
520+
case RISCV::VWSLL_VX:
521+
case RISCV::VWSLL_VV:
520522
// Vector Widening Integer Multiply Instructions
521523
// Destination EEW=2*SEW. Source EEW=SEW.
522524
case RISCV::VWMUL_VV:
@@ -1019,6 +1021,8 @@ static bool isSupportedInstr(const MachineInstr &MI) {
10191021

10201022
// Vector Crypto
10211023
case RISCV::VWSLL_VI:
1024+
case RISCV::VWSLL_VX:
1025+
case RISCV::VWSLL_VV:
10221026

10231027
// Vector Mask Instructions
10241028
// Vector Mask-Register Logical Instructions

0 commit comments

Comments
 (0)