Skip to content

Commit a6a0725

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:e069434afcd21911ad36c55971bb8f754854c09f into amd-gfx:2c74854f7595
Local branch amd-gfx 2c74854 Merged main:139688a699f6db784bd559b147334f1d51314f9c into amd-gfx:cf8fb1be1ea5 Remote branch main e069434 [rtsan][NFC] Remove unncessary namespace specifiers (llvm#110197)
2 parents 2c74854 + e069434 commit a6a0725

File tree

65 files changed

+4854
-3536
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+4854
-3536
lines changed

clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,52 +7,58 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "PosixReturnCheck.h"
10-
#include "../utils/Matchers.h"
1110
#include "clang/AST/ASTContext.h"
1211
#include "clang/ASTMatchers/ASTMatchFinder.h"
12+
#include "clang/ASTMatchers/ASTMatchers.h"
1313
#include "clang/Lex/Lexer.h"
1414

1515
using namespace clang::ast_matchers;
1616

1717
namespace clang::tidy::bugprone {
1818

19-
static StringRef getFunctionSpelling(const MatchFinder::MatchResult &Result,
20-
const char *BindingStr) {
21-
const CallExpr *MatchedCall = cast<CallExpr>(
22-
(Result.Nodes.getNodeAs<BinaryOperator>(BindingStr))->getLHS());
19+
static StringRef getFunctionSpelling(const MatchFinder::MatchResult &Result) {
20+
const auto *MatchedCall = Result.Nodes.getNodeAs<CallExpr>("call");
2321
const SourceManager &SM = *Result.SourceManager;
2422
return Lexer::getSourceText(CharSourceRange::getTokenRange(
2523
MatchedCall->getCallee()->getSourceRange()),
2624
SM, Result.Context->getLangOpts());
2725
}
2826

2927
void PosixReturnCheck::registerMatchers(MatchFinder *Finder) {
28+
const auto PosixCall =
29+
callExpr(callee(functionDecl(
30+
anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
31+
unless(hasName("::posix_openpt")))))
32+
.bind("call");
33+
const auto ZeroIntegerLiteral = integerLiteral(equals(0));
34+
const auto NegIntegerLiteral =
35+
unaryOperator(hasOperatorName("-"), hasUnaryOperand(integerLiteral()));
36+
3037
Finder->addMatcher(
3138
binaryOperator(
32-
hasOperatorName("<"),
33-
hasLHS(callExpr(callee(functionDecl(
34-
anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
35-
unless(hasName("::posix_openpt")))))),
36-
hasRHS(integerLiteral(equals(0))))
39+
anyOf(allOf(hasOperatorName("<"), hasLHS(PosixCall),
40+
hasRHS(ZeroIntegerLiteral)),
41+
allOf(hasOperatorName(">"), hasLHS(ZeroIntegerLiteral),
42+
hasRHS(PosixCall))))
3743
.bind("ltzop"),
3844
this);
3945
Finder->addMatcher(
4046
binaryOperator(
41-
hasOperatorName(">="),
42-
hasLHS(callExpr(callee(functionDecl(
43-
anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
44-
unless(hasName("::posix_openpt")))))),
45-
hasRHS(integerLiteral(equals(0))))
47+
anyOf(allOf(hasOperatorName(">="), hasLHS(PosixCall),
48+
hasRHS(ZeroIntegerLiteral)),
49+
allOf(hasOperatorName("<="), hasLHS(ZeroIntegerLiteral),
50+
hasRHS(PosixCall))))
4651
.bind("atop"),
4752
this);
53+
Finder->addMatcher(binaryOperator(hasAnyOperatorName("==", "!="),
54+
hasOperands(PosixCall, NegIntegerLiteral))
55+
.bind("binop"),
56+
this);
4857
Finder->addMatcher(
49-
binaryOperator(
50-
hasAnyOperatorName("==", "!=", "<=", "<"),
51-
hasLHS(callExpr(callee(functionDecl(
52-
anyOf(matchesName("^::posix_"), matchesName("^::pthread_")),
53-
unless(hasName("::posix_openpt")))))),
54-
hasRHS(unaryOperator(hasOperatorName("-"),
55-
hasUnaryOperand(integerLiteral()))))
58+
binaryOperator(anyOf(allOf(hasAnyOperatorName("<=", "<"),
59+
hasLHS(PosixCall), hasRHS(NegIntegerLiteral)),
60+
allOf(hasAnyOperatorName(">", ">="),
61+
hasLHS(NegIntegerLiteral), hasRHS(PosixCall))))
5662
.bind("binop"),
5763
this);
5864
}
@@ -61,23 +67,26 @@ void PosixReturnCheck::check(const MatchFinder::MatchResult &Result) {
6167
if (const auto *LessThanZeroOp =
6268
Result.Nodes.getNodeAs<BinaryOperator>("ltzop")) {
6369
SourceLocation OperatorLoc = LessThanZeroOp->getOperatorLoc();
70+
StringRef NewBinOp =
71+
LessThanZeroOp->getOpcode() == BinaryOperator::Opcode::BO_LT ? ">"
72+
: "<";
6473
diag(OperatorLoc, "the comparison always evaluates to false because %0 "
6574
"always returns non-negative values")
66-
<< getFunctionSpelling(Result, "ltzop")
67-
<< FixItHint::CreateReplacement(OperatorLoc, Twine(">").str());
75+
<< getFunctionSpelling(Result)
76+
<< FixItHint::CreateReplacement(OperatorLoc, NewBinOp);
6877
return;
6978
}
7079
if (const auto *AlwaysTrueOp =
7180
Result.Nodes.getNodeAs<BinaryOperator>("atop")) {
7281
diag(AlwaysTrueOp->getOperatorLoc(),
7382
"the comparison always evaluates to true because %0 always returns "
7483
"non-negative values")
75-
<< getFunctionSpelling(Result, "atop");
84+
<< getFunctionSpelling(Result);
7685
return;
7786
}
7887
const auto *BinOp = Result.Nodes.getNodeAs<BinaryOperator>("binop");
7988
diag(BinOp->getOperatorLoc(), "%0 only returns non-negative values")
80-
<< getFunctionSpelling(Result, "binop");
89+
<< getFunctionSpelling(Result);
8190
}
8291

8392
} // namespace clang::tidy::bugprone

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ Changes in existing checks
125125
<clang-tidy/checks/bugprone/forwarding-reference-overload>` check by fixing
126126
a crash when determining if an ``enable_if[_t]`` was found.
127127

128+
- Improved :doc:`bugprone-posix-return
129+
<clang-tidy/checks/bugprone/posix-return>` check to support integer literals
130+
as LHS and posix call as RHS of comparison.
131+
128132
- Improved :doc:`bugprone-sizeof-expression
129133
<clang-tidy/checks/bugprone/sizeof-expression>` check to find suspicious
130134
usages of ``sizeof()``, ``alignof()``, and ``offsetof()`` when adding or

clang-tools-extra/test/clang-tidy/checkers/bugprone/posix-return.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ void warningLessThanZero() {
7474
if (pthread_yield() < 0) {}
7575
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning:
7676
// CHECK-FIXES: pthread_yield() > 0
77+
if (0 > pthread_yield() ) {}
78+
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning:
79+
// CHECK-FIXES: 0 < pthread_yield()
7780

7881
}
7982

@@ -90,7 +93,8 @@ void warningAlwaysTrue() {
9093
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning:
9194
if (pthread_yield() >= 0) {}
9295
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning:
93-
96+
if (0 <= pthread_yield()) {}
97+
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning:
9498
}
9599

96100
void warningEqualsNegative() {
@@ -120,7 +124,14 @@ void warningEqualsNegative() {
120124
// CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
121125
if (pthread_create(NULL, NULL, NULL, NULL) < -1) {}
122126
// CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
123-
127+
if (-1 == pthread_create(NULL, NULL, NULL, NULL)) {}
128+
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning:
129+
if (-1 != pthread_create(NULL, NULL, NULL, NULL)) {}
130+
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning:
131+
if (-1 >= pthread_create(NULL, NULL, NULL, NULL)) {}
132+
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning:
133+
if (-1 > pthread_create(NULL, NULL, NULL, NULL)) {}
134+
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning:
124135
}
125136

126137
void WarningWithMacro() {
@@ -162,6 +173,16 @@ void noWarning() {
162173
if (posix_openpt(0) < -1) {}
163174
if (posix_fadvise(0, 0, 0, 0) <= 0) {}
164175
if (posix_fadvise(0, 0, 0, 0) == 1) {}
176+
if (0 > posix_openpt(0)) {}
177+
if (0 >= posix_openpt(0)) {}
178+
if (-1 == posix_openpt(0)) {}
179+
if (-1 != posix_openpt(0)) {}
180+
if (-1 >= posix_openpt(0)) {}
181+
if (-1 > posix_openpt(0)) {}
182+
if (posix_fadvise(0, 0, 0, 0) <= 0) {}
183+
if (posix_fadvise(0, 0, 0, 0) == 1) {}
184+
if (0 >= posix_fadvise(0, 0, 0, 0)) {}
185+
if (1 == posix_fadvise(0, 0, 0, 0)) {}
165186
}
166187

167188
namespace i {

clang/docs/ReleaseNotes.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,24 @@ C++ Specific Potentially Breaking Changes
8181
template <typename T>
8282
void f();
8383

84+
- During constant evaluation, comparisons between different evaluations of the
85+
same string literal are now correctly treated as non-constant, and comparisons
86+
between string literals that cannot possibly overlap in memory are now treated
87+
as constant. This updates Clang to match the anticipated direction of open core
88+
issue `CWG2765 <http://wg21.link/CWG2765>`, but is subject to change once that
89+
issue is resolved.
90+
91+
.. code-block:: c++
92+
93+
constexpr const char *f() { return "hello"; }
94+
constexpr const char *g() { return "world"; }
95+
// Used to evaluate to false, now error: non-constant comparison.
96+
constexpr bool a = f() == f();
97+
// Might evaluate to true or false, as before.
98+
bool at_runtime() { return f() == f(); }
99+
// Was error, now evaluates to false.
100+
constexpr bool b = f() == g();
101+
84102
ABI Changes in This Version
85103
---------------------------
86104

clang/include/clang/AST/ASTContext.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,14 @@ class ASTContext : public RefCountedBase<ASTContext> {
324324
/// This is lazily created. This is intentionally not serialized.
325325
mutable llvm::StringMap<StringLiteral *> StringLiteralCache;
326326

327+
/// The next string literal "version" to allocate during constant evaluation.
328+
/// This is used to distinguish between repeated evaluations of the same
329+
/// string literal.
330+
///
331+
/// We don't need to serialize this because constants get re-evaluated in the
332+
/// current file before they are compared locally.
333+
unsigned NextStringLiteralVersion = 0;
334+
327335
/// MD5 hash of CUID. It is calculated when first used and cached by this
328336
/// data member.
329337
mutable std::string CUIDHash;
@@ -3300,6 +3308,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
33003308
/// PredefinedExpr to cache evaluated results.
33013309
StringLiteral *getPredefinedStringLiteralFromCache(StringRef Key) const;
33023310

3311+
/// Return the next version number to be used for a string literal evaluated
3312+
/// as part of constant evaluation.
3313+
unsigned getNextStringLiteralVersion() { return NextStringLiteralVersion++; }
3314+
33033315
/// Return a declaration for the global GUID object representing the given
33043316
/// GUID value.
33053317
MSGuidDecl *getMSGuidDecl(MSGuidDeclParts Parts) const;

clang/include/clang/Basic/DiagnosticASTKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ def note_constexpr_pointer_constant_comparison : Note<
9696
"at runtime">;
9797
def note_constexpr_literal_comparison : Note<
9898
"comparison of addresses of literals has unspecified value">;
99+
def note_constexpr_opaque_call_comparison : Note<
100+
"comparison against opaque constant address '%0' can only be performed at "
101+
"runtime">;
99102
def note_constexpr_pointer_weak_comparison : Note<
100103
"comparison against address of weak declaration '%0' can only be performed "
101104
"at runtime">;

0 commit comments

Comments
 (0)