Skip to content

Commit

Permalink
merge internal development externally
Browse files Browse the repository at this point in the history
  • Loading branch information
searlmc1 committed Jun 12, 2024
2 parents a45f8a9 + 096ed0c commit e144409
Show file tree
Hide file tree
Showing 412 changed files with 23,266 additions and 5,689 deletions.
115 changes: 70 additions & 45 deletions clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ SizeofExpressionCheck::SizeofExpressionCheck(StringRef Name,
WarnOnSizeOfCompareToConstant(
Options.get("WarnOnSizeOfCompareToConstant", true)),
WarnOnSizeOfPointerToAggregate(
Options.get("WarnOnSizeOfPointerToAggregate", true)) {}
Options.get("WarnOnSizeOfPointerToAggregate", true)),
WarnOnSizeOfPointer(Options.get("WarnOnSizeOfPointer", false)) {}

void SizeofExpressionCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "WarnOnSizeOfConstant", WarnOnSizeOfConstant);
Expand All @@ -78,6 +79,7 @@ void SizeofExpressionCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
WarnOnSizeOfCompareToConstant);
Options.store(Opts, "WarnOnSizeOfPointerToAggregate",
WarnOnSizeOfPointerToAggregate);
Options.store(Opts, "WarnOnSizeOfPointer", WarnOnSizeOfPointer);
}

void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {
Expand Down Expand Up @@ -127,17 +129,30 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {
const auto ConstStrLiteralDecl =
varDecl(isDefinition(), hasType(hasCanonicalType(CharPtrType)),
hasInitializer(ignoringParenImpCasts(stringLiteral())));
const auto VarWithConstStrLiteralDecl = expr(
hasType(hasCanonicalType(CharPtrType)),
ignoringParenImpCasts(declRefExpr(hasDeclaration(ConstStrLiteralDecl))));
Finder->addMatcher(
sizeOfExpr(has(ignoringParenImpCasts(
expr(hasType(hasCanonicalType(CharPtrType)),
ignoringParenImpCasts(declRefExpr(
hasDeclaration(ConstStrLiteralDecl)))))))
sizeOfExpr(has(ignoringParenImpCasts(VarWithConstStrLiteralDecl)))
.bind("sizeof-charp"),
this);

// Detect sizeof(ptr) where ptr points to an aggregate (i.e. sizeof(&S)).
// Do not find it if RHS of a 'sizeof(arr) / sizeof(arr[0])' expression.
if (WarnOnSizeOfPointerToAggregate) {
// Detect sizeof(ptr) where ptr is a pointer (CWE-467).
//
// In WarnOnSizeOfPointerToAggregate mode only report cases when ptr points
// to an aggregate type or ptr is an expression that (implicitly or
// explicitly) casts an array to a pointer type. (These are more suspicious
// than other sizeof(ptr) expressions because they can appear as distorted
// forms of the common sizeof(aggregate) expressions.)
//
// To avoid false positives, the check doesn't report expressions like
// 'sizeof(pp[0])' and 'sizeof(*pp)' where `pp` is a pointer-to-pointer or
// array of pointers. (This filters out both `sizeof(arr) / sizeof(arr[0])`
// expressions and other cases like `p = realloc(p, newsize * sizeof(*p));`.)
//
// Moreover this generic message is suppressed in cases that are also matched
// by the more concrete matchers 'sizeof-this' and 'sizeof-charp'.
if (WarnOnSizeOfPointerToAggregate || WarnOnSizeOfPointer) {
const auto ArrayExpr =
ignoringParenImpCasts(hasType(hasCanonicalType(arrayType())));
const auto ArrayCastExpr = expr(anyOf(
Expand All @@ -149,32 +164,31 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {

const auto PointerToStructType =
hasUnqualifiedDesugaredType(pointerType(pointee(recordType())));
const auto PointerToStructExpr = expr(
hasType(hasCanonicalType(PointerToStructType)), unless(cxxThisExpr()));

const auto ArrayOfPointersExpr = ignoringParenImpCasts(
hasType(hasCanonicalType(arrayType(hasElementType(pointerType()))
.bind("type-of-array-of-pointers"))));
const auto ArrayOfSamePointersExpr =
ignoringParenImpCasts(hasType(hasCanonicalType(
arrayType(equalsBoundNode("type-of-array-of-pointers")))));
const auto PointerToStructTypeWithBinding =
type(PointerToStructType).bind("struct-type");
const auto PointerToStructExpr =
expr(hasType(hasCanonicalType(PointerToStructType)));

const auto PointerToDetectedExpr =
WarnOnSizeOfPointer
? expr(hasType(hasUnqualifiedDesugaredType(pointerType())))
: expr(anyOf(ArrayCastExpr, PointerToArrayExpr,
PointerToStructExpr));

const auto ZeroLiteral = ignoringParenImpCasts(integerLiteral(equals(0)));
const auto ArrayOfSamePointersZeroSubscriptExpr =
ignoringParenImpCasts(arraySubscriptExpr(
hasBase(ArrayOfSamePointersExpr), hasIndex(ZeroLiteral)));
const auto ArrayLengthExprDenom =
expr(hasParent(binaryOperator(hasOperatorName("/"),
hasLHS(ignoringParenImpCasts(sizeOfExpr(
has(ArrayOfPointersExpr)))))),
sizeOfExpr(has(ArrayOfSamePointersZeroSubscriptExpr)));
const auto SubscriptExprWithZeroIndex =
arraySubscriptExpr(hasIndex(ZeroLiteral));
const auto DerefExpr =
ignoringParenImpCasts(unaryOperator(hasOperatorName("*")));

Finder->addMatcher(
expr(sizeOfExpr(anyOf(
has(ignoringParenImpCasts(anyOf(
ArrayCastExpr, PointerToArrayExpr, PointerToStructExpr))),
has(PointerToStructType))),
unless(ArrayLengthExprDenom))
.bind("sizeof-pointer-to-aggregate"),
expr(sizeOfExpr(anyOf(has(ignoringParenImpCasts(
expr(PointerToDetectedExpr, unless(DerefExpr),
unless(SubscriptExprWithZeroIndex),
unless(VarWithConstStrLiteralDecl),
unless(cxxThisExpr())))),
has(PointerToStructTypeWithBinding))))
.bind("sizeof-pointer"),
this);
}

Expand Down Expand Up @@ -292,11 +306,17 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
diag(E->getBeginLoc(),
"suspicious usage of 'sizeof(char*)'; do you mean 'strlen'?")
<< E->getSourceRange();
} else if (const auto *E =
Result.Nodes.getNodeAs<Expr>("sizeof-pointer-to-aggregate")) {
diag(E->getBeginLoc(),
"suspicious usage of 'sizeof(A*)'; pointer to aggregate")
<< E->getSourceRange();
} else if (const auto *E = Result.Nodes.getNodeAs<Expr>("sizeof-pointer")) {
if (Result.Nodes.getNodeAs<Type>("struct-type")) {
diag(E->getBeginLoc(),
"suspicious usage of 'sizeof(A*)' on pointer-to-aggregate type; did "
"you mean 'sizeof(A)'?")
<< E->getSourceRange();
} else {
diag(E->getBeginLoc(), "suspicious usage of 'sizeof()' on an expression "
"that results in a pointer")
<< E->getSourceRange();
}
} else if (const auto *E = Result.Nodes.getNodeAs<BinaryOperator>(
"sizeof-compare-constant")) {
diag(E->getOperatorLoc(),
Expand Down Expand Up @@ -332,18 +352,23 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
" numerator is not a multiple of denominator")
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
} else if (NumTy && DenomTy && NumTy == DenomTy) {
// FIXME: This message is wrong, it should not refer to sizeof "pointer"
// usage (and by the way, it would be to clarify all the messages).
diag(E->getOperatorLoc(),
"suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'")
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
} else if (PointedTy && DenomTy && PointedTy == DenomTy) {
diag(E->getOperatorLoc(),
"suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'")
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
} else if (NumTy && DenomTy && NumTy->isPointerType() &&
DenomTy->isPointerType()) {
diag(E->getOperatorLoc(),
"suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)'")
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
} else if (!WarnOnSizeOfPointer) {
// When 'WarnOnSizeOfPointer' is enabled, these messages become redundant:
if (PointedTy && DenomTy && PointedTy == DenomTy) {
diag(E->getOperatorLoc(),
"suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'")
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
} else if (NumTy && DenomTy && NumTy->isPointerType() &&
DenomTy->isPointerType()) {
diag(E->getOperatorLoc(),
"suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)'")
<< E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
}
}
} else if (const auto *E =
Result.Nodes.getNodeAs<Expr>("sizeof-sizeof-expr")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class SizeofExpressionCheck : public ClangTidyCheck {
const bool WarnOnSizeOfThis;
const bool WarnOnSizeOfCompareToConstant;
const bool WarnOnSizeOfPointerToAggregate;
const bool WarnOnSizeOfPointer;
};

} // namespace clang::tidy::bugprone
Expand Down
6 changes: 5 additions & 1 deletion clang-tools-extra/clangd/index/remote/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ if (CLANGD_ENABLE_REMOTE)
clangdRemoteIndexProto
clangdRemoteIndexServiceProto
clangdRemoteMarshalling
clangBasic
clangDaemon
clangdSupport

Expand All @@ -35,6 +34,11 @@ if (CLANGD_ENABLE_REMOTE)
clangdRemoteIndexServiceProto
)

clang_target_link_libraries(clangdRemoteIndex
PRIVATE
clangBasic
)

add_subdirectory(marshalling)
add_subdirectory(server)
add_subdirectory(monitor)
Expand Down
10 changes: 10 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,12 @@ Changes in existing checks
<clang-tidy/checks/bugprone/optional-value-conversion>` check by eliminating
false positives resulting from use of optionals in unevaluated context.

- Improved :doc:`bugprone-sizeof-expression
<clang-tidy/checks/bugprone/sizeof-expression>` check by eliminating some
false positives and adding a new (off-by-default) option
`WarnOnSizeOfPointer` that reports all ``sizeof(pointer)`` expressions
(except for a few that are idiomatic).

- Improved :doc:`bugprone-suspicious-include
<clang-tidy/checks/bugprone/suspicious-include>` check by replacing the local
options `HeaderFileExtensions` and `ImplementationFileExtensions` by the
Expand Down Expand Up @@ -331,6 +337,10 @@ Changes in existing checks
<clang-tidy/checks/misc/header-include-cycle>` check by avoiding crash for self
include cycles.

- Improved :doc:`misc-include-cleaner
<clang-tidy/checks/misc/include-cleaner>` check by avoiding false positives for
the functions with the same name as standard library functions.

- Improved :doc:`misc-unused-using-decls
<clang-tidy/checks/misc/unused-using-decls>` check by replacing the local
option `HeaderFileExtensions` by the global option of the same name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,15 @@ Options

.. option:: WarnOnSizeOfPointerToAggregate

When `true`, the check will warn on an expression like
``sizeof(expr)`` where the expression is a pointer
to aggregate. Default is `true`.
When `true`, the check will warn when the argument of ``sizeof`` is either a
pointer-to-aggregate type, an expression returning a pointer-to-aggregate
value or an expression that returns a pointer from an array-to-pointer
conversion (that may be implicit or explicit, for example ``array + 2`` or
``(int *)array``). Default is `true`.

.. option:: WarnOnSizeOfPointer

When `true`, the check will report all expressions where the argument of
``sizeof`` is an expression that produces a pointer (except for a few
idiomatic expressions that are probably intentional and correct).
This detects occurrences of CWE 467. Default is `false`.
8 changes: 6 additions & 2 deletions clang-tools-extra/include-cleaner/lib/LocateSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/Tooling/Inclusions/StandardLibrary.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
#include <utility>
#include <vector>

Expand All @@ -40,8 +41,11 @@ Hints declHints(const Decl *D) {
std::vector<Hinted<SymbolLocation>> locateDecl(const Decl &D) {
std::vector<Hinted<SymbolLocation>> Result;
// FIXME: Should we also provide physical locations?
if (auto SS = tooling::stdlib::Recognizer()(&D))
return {{*SS, Hints::CompleteSymbol}};
if (auto SS = tooling::stdlib::Recognizer()(&D)) {
Result.push_back({*SS, Hints::CompleteSymbol});
if (!D.hasBody())
return Result;
}
// FIXME: Signal foreign decls, e.g. a forward declaration not owned by a
// library. Some useful signals could be derived by checking the DeclContext.
// Most incidental forward decls look like:
Expand Down
11 changes: 11 additions & 0 deletions clang-tools-extra/include-cleaner/unittests/FindHeadersTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,17 @@ TEST_F(HeadersForSymbolTest, StandardHeaders) {
tooling::stdlib::Header::named("<assert.h>")));
}

TEST_F(HeadersForSymbolTest, NonStandardHeaders) {
Inputs.Code = "void assert() {}";
buildAST();
EXPECT_THAT(
headersFor("assert"),
// Respect the ordering from the stdlib mapping.
UnorderedElementsAre(physicalHeader("input.mm"),
tooling::stdlib::Header::named("<cassert>"),
tooling::stdlib::Header::named("<assert.h>")));
}

TEST_F(HeadersForSymbolTest, ExporterNoNameMatch) {
Inputs.Code = R"cpp(
#include "exporter/foo.h"
Expand Down
8 changes: 6 additions & 2 deletions clang-tools-extra/pseudo/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ add_clang_library(clangPseudo
Token.cpp

LINK_LIBS
clangBasic
clangLex
clangPseudoGrammar

DEPENDS
Expand All @@ -25,3 +23,9 @@ add_clang_library(clangPseudo
target_include_directories(clangPseudo INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
)

clang_target_link_libraries(clangPseudo
PRIVATE
clangBasic
clangLex
)
6 changes: 5 additions & 1 deletion clang-tools-extra/pseudo/lib/cxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ add_clang_library(clangPseudoCXX
cxx_gen

LINK_LIBS
clangBasic
clangPseudo
clangPseudoGrammar
)

clang_target_link_libraries(clangPseudoCXX
PRIVATE
clangBasic
)
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,24 @@ int Test5() {

int sum = 0;
sum += sizeof(&S);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(__typeof(&S));
sum += sizeof(&TS);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(__typeof(&TS));
sum += sizeof(STRKWD MyStruct*);
sum += sizeof(__typeof(STRKWD MyStruct*));
sum += sizeof(TypedefStruct*);
sum += sizeof(__typeof(TypedefStruct*));
sum += sizeof(PTTS);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(PMyStruct);
sum += sizeof(PS);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(PS2);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer
sum += sizeof(&A10);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in a pointer

#ifdef __cplusplus
MyStruct &rS = S;
Expand Down
Loading

0 comments on commit e144409

Please sign in to comment.