Skip to content

Commit

Permalink
merge main into amd-staging
Browse files Browse the repository at this point in the history
Change-Id: I39d8f8870f1cc604f2549430b8b20565d3a14a29
  • Loading branch information
Jenkins committed Nov 25, 2024
2 parents b94cd44 + bb5bbe5 commit 4a96fd8
Show file tree
Hide file tree
Showing 160 changed files with 10,490 additions and 8,082 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ void InfiniteLoopCheck::check(const MatchFinder::MatchResult &Result) {
}
}

if (ExprMutationAnalyzer::isUnevaluated(LoopStmt, *LoopStmt, *Result.Context))
if (ExprMutationAnalyzer::isUnevaluated(LoopStmt, *Result.Context))
return;

if (isAtLeastOneCondVarChanged(Func, LoopStmt, Cond, Result.Context))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,79 +13,88 @@
using namespace clang::ast_matchers;

namespace clang::tidy::cppcoreguidelines {
namespace {

AST_MATCHER(FieldDecl, isMemberOfLambda) {
return Node.getParent()->isLambda();
static bool isCopyConstructible(CXXRecordDecl const &Node) {
if (Node.needsOverloadResolutionForCopyConstructor() &&
Node.needsImplicitCopyConstructor()) {
// unresolved
for (CXXBaseSpecifier const &BS : Node.bases()) {
CXXRecordDecl const *BRD = BS.getType()->getAsCXXRecordDecl();
if (BRD != nullptr && !isCopyConstructible(*BRD))
return false;
}
}
if (Node.hasSimpleCopyConstructor())
return true;
for (CXXConstructorDecl const *Ctor : Node.ctors())
if (Ctor->isCopyConstructor())
return !Ctor->isDeleted();
return false;
}

struct MemberFunctionInfo {
bool Declared{};
bool Deleted{};
};

struct MemberFunctionPairInfo {
MemberFunctionInfo Copy{};
MemberFunctionInfo Move{};
};

MemberFunctionPairInfo getConstructorsInfo(CXXRecordDecl const &Node) {
MemberFunctionPairInfo Constructors{};

for (CXXConstructorDecl const *Ctor : Node.ctors()) {
if (Ctor->isCopyConstructor()) {
Constructors.Copy.Declared = true;
if (Ctor->isDeleted())
Constructors.Copy.Deleted = true;
}
if (Ctor->isMoveConstructor()) {
Constructors.Move.Declared = true;
if (Ctor->isDeleted())
Constructors.Move.Deleted = true;
static bool isMoveConstructible(CXXRecordDecl const &Node) {
if (Node.needsOverloadResolutionForMoveConstructor() &&
Node.needsImplicitMoveConstructor()) {
// unresolved
for (CXXBaseSpecifier const &BS : Node.bases()) {
CXXRecordDecl const *BRD = BS.getType()->getAsCXXRecordDecl();
if (BRD != nullptr && !isMoveConstructible(*BRD))
return false;
}
}

return Constructors;
if (Node.hasSimpleMoveConstructor())
return true;
for (CXXConstructorDecl const *Ctor : Node.ctors())
if (Ctor->isMoveConstructor())
return !Ctor->isDeleted();
return false;
}

MemberFunctionPairInfo getAssignmentsInfo(CXXRecordDecl const &Node) {
MemberFunctionPairInfo Assignments{};

for (CXXMethodDecl const *Method : Node.methods()) {
if (Method->isCopyAssignmentOperator()) {
Assignments.Copy.Declared = true;
if (Method->isDeleted())
Assignments.Copy.Deleted = true;
static bool isCopyAssignable(CXXRecordDecl const &Node) {
if (Node.needsOverloadResolutionForCopyAssignment() &&
Node.needsImplicitCopyAssignment()) {
// unresolved
for (CXXBaseSpecifier const &BS : Node.bases()) {
CXXRecordDecl const *BRD = BS.getType()->getAsCXXRecordDecl();
if (BRD != nullptr && !isCopyAssignable(*BRD))
return false;
}
}
if (Node.hasSimpleCopyAssignment())
return true;
for (CXXMethodDecl const *Method : Node.methods())
if (Method->isCopyAssignmentOperator())
return !Method->isDeleted();
return false;
}

if (Method->isMoveAssignmentOperator()) {
Assignments.Move.Declared = true;
if (Method->isDeleted())
Assignments.Move.Deleted = true;
static bool isMoveAssignable(CXXRecordDecl const &Node) {
if (Node.needsOverloadResolutionForMoveAssignment() &&
Node.needsImplicitMoveAssignment()) {
// unresolved
for (CXXBaseSpecifier const &BS : Node.bases()) {
CXXRecordDecl const *BRD = BS.getType()->getAsCXXRecordDecl();
if (BRD != nullptr && !isMoveAssignable(*BRD))
return false;
}
}

return Assignments;
if (Node.hasSimpleMoveAssignment())
return true;
for (CXXMethodDecl const *Method : Node.methods())
if (Method->isMoveAssignmentOperator())
return !Method->isDeleted();
return false;
}

AST_MATCHER(CXXRecordDecl, isCopyableOrMovable) {
MemberFunctionPairInfo Constructors = getConstructorsInfo(Node);
MemberFunctionPairInfo Assignments = getAssignmentsInfo(Node);
namespace {

if (Node.hasSimpleCopyConstructor() ||
(Constructors.Copy.Declared && !Constructors.Copy.Deleted))
return true;
if (Node.hasSimpleMoveConstructor() ||
(Constructors.Move.Declared && !Constructors.Move.Deleted))
return true;
if (Node.hasSimpleCopyAssignment() ||
(Assignments.Copy.Declared && !Assignments.Copy.Deleted))
return true;
if (Node.hasSimpleMoveAssignment() ||
(Assignments.Move.Declared && !Assignments.Move.Deleted))
return true;
AST_MATCHER(FieldDecl, isMemberOfLambda) {
return Node.getParent()->isLambda();
}

return false;
AST_MATCHER(CXXRecordDecl, isCopyableOrMovable) {
return isCopyConstructible(Node) || isMoveConstructible(Node) ||
isCopyAssignable(Node) || isMoveAssignable(Node);
}

} // namespace
Expand Down
6 changes: 3 additions & 3 deletions clang-tools-extra/clang-tidy/misc/UseInternalLinkageCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@

#include "UseInternalLinkageCheck.h"
#include "../utils/FileExtensionsUtils.h"
#include "../utils/LexerUtils.h"
#include "clang/AST/Decl.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/STLExtras.h"

Expand Down Expand Up @@ -47,6 +45,8 @@ namespace {

AST_MATCHER(Decl, isFirstDecl) { return Node.isFirstDecl(); }

AST_MATCHER(FunctionDecl, hasBody) { return Node.hasBody(); }

static bool isInMainFile(SourceLocation L, SourceManager &SM,
const FileExtensionsSet &HeaderFileExtensions) {
for (;;) {
Expand Down Expand Up @@ -103,7 +103,7 @@ void UseInternalLinkageCheck::registerMatchers(MatchFinder *Finder) {
// 4. friend
hasAncestor(friendDecl()))));
Finder->addMatcher(
functionDecl(Common, unless(cxxMethodDecl()), unless(isMain()))
functionDecl(Common, hasBody(), unless(cxxMethodDecl()), unless(isMain()))
.bind("fn"),
this);
Finder->addMatcher(varDecl(Common, hasGlobalStorage()).bind("var"), this);
Expand Down
9 changes: 7 additions & 2 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ Changes in existing checks
fix false positive that floating point variable is only used in increment
expression.

- Improved :doc:`cppcoreguidelines-avoid-const-or-ref-data-members
<clang-tidy/checks/cppcoreguidelines/avoid-const-or-ref-data-members>` check to
avoid false positives when detecting a templated class with inheritance.

- Improved :doc:`cppcoreguidelines-init-variables
<clang-tidy/checks/cppcoreguidelines/init-variables>` check by fixing the
insertion location for function pointers.
Expand All @@ -229,8 +233,9 @@ Changes in existing checks
false positive for C++23 deducing this.

- Improved :doc:`misc-use-internal-linkage
<clang-tidy/checks/misc/use-internal-linkage>` check to insert ``static`` keyword
before type qualifiers such as ``const`` and ``volatile``.
<clang-tidy/checks/misc/use-internal-linkage>` check to insert ``static``
keyword before type qualifiers such as ``const`` and ``volatile`` and fix
false positives for function declaration without body.

- Improved :doc:`modernize-avoid-c-arrays
<clang-tidy/checks/modernize/avoid-c-arrays>` check to suggest using
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Example:

int v1; // can be marked as static

void fn1(); // can be marked as static
void fn1() {} // can be marked as static

namespace {
// already in anonymous namespace
Expand All @@ -26,6 +26,9 @@ Example:
// already declared as extern
extern int v2;

void fn3(); // without function body in all declaration, maybe external linkage
void fn3();

Options
-------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,28 @@ struct InheritBothFromNonCopyableAndNonMovable : NonCopyable, NonMovable
int& x; // OK, non copyable nor movable
};

template<class T> struct TemplateInheritFromNonCopyable : NonCopyable
{
int& x;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'x' of type 'int &' is a reference
};

template<class T> struct TemplateInheritFromNonMovable : NonMovable
{
int& x;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: member 'x' of type 'int &' is a reference
};

template<class T> struct TemplateInheritFromNonCopyableNonMovable : NonCopyableNonMovable
{
int& x; // OK, non copyable nor movable
};

template<class T> struct TemplateInheritBothFromNonCopyableAndNonMovable : NonCopyable, NonMovable
{
int& x; // OK, non copyable nor movable
};

// Test composition
struct ContainsNonCopyable
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,59 +13,59 @@ void func_template() {}
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_template'
// CHECK-FIXES: static void func_template() {}

void func_cpp_inc();
void func_cpp_inc() {}
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_cpp_inc'
// CHECK-FIXES: static void func_cpp_inc();
// CHECK-FIXES: static void func_cpp_inc() {}

int* func_cpp_inc_return_ptr();
int* func_cpp_inc_return_ptr() {}
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_cpp_inc_return_ptr'
// CHECK-FIXES: static int* func_cpp_inc_return_ptr();
// CHECK-FIXES: static int* func_cpp_inc_return_ptr() {}

const int* func_cpp_inc_return_const_ptr();
const int* func_cpp_inc_return_const_ptr() {}
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: function 'func_cpp_inc_return_const_ptr'
// CHECK-FIXES: static const int* func_cpp_inc_return_const_ptr();
// CHECK-FIXES: static const int* func_cpp_inc_return_const_ptr() {}

int const* func_cpp_inc_return_ptr_const();
int const* func_cpp_inc_return_ptr_const() {}
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: function 'func_cpp_inc_return_ptr_const'
// CHECK-FIXES: static int const* func_cpp_inc_return_ptr_const();
// CHECK-FIXES: static int const* func_cpp_inc_return_ptr_const() {}

int * const func_cpp_inc_return_const();
int * const func_cpp_inc_return_const() {}
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: function 'func_cpp_inc_return_const'
// CHECK-FIXES: static int * const func_cpp_inc_return_const();
// CHECK-FIXES: static int * const func_cpp_inc_return_const() {}

volatile const int* func_cpp_inc_return_volatile_const_ptr();
volatile const int* func_cpp_inc_return_volatile_const_ptr() {}
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: function 'func_cpp_inc_return_volatile_const_ptr'
// CHECK-FIXES: static volatile const int* func_cpp_inc_return_volatile_const_ptr();
// CHECK-FIXES: static volatile const int* func_cpp_inc_return_volatile_const_ptr() {}

[[nodiscard]] void func_nodiscard();
[[nodiscard]] void func_nodiscard() {}
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: function 'func_nodiscard'
// CHECK-FIXES: {{\[\[nodiscard\]\]}} static void func_nodiscard();
// CHECK-FIXES: {{\[\[nodiscard\]\]}} static void func_nodiscard() {}

#define NDS [[nodiscard]]
#define NNDS

NDS void func_nds();
NDS void func_nds() {}
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: function 'func_nds'
// CHECK-FIXES: NDS static void func_nds();
// CHECK-FIXES: NDS static void func_nds() {}

NNDS void func_nnds();
NNDS void func_nnds() {}
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: function 'func_nnds'
// CHECK-FIXES: NNDS static void func_nnds();
// CHECK-FIXES: NNDS static void func_nnds() {}

#include "func_cpp.inc"

void func_h_inc();
void func_h_inc() {}

struct S {
void method();
};
void S::method() {}

void func_header();
extern void func_extern();
static void func_static();
void func_header() {}
extern void func_extern() {}
static void func_static() {}
namespace {
void func_anonymous_ns();
void func_anonymous_ns() {}
} // namespace

int main(int argc, const char*argv[]) {}
Expand All @@ -75,3 +75,13 @@ void func_extern_c_1() {}
}

extern "C" void func_extern_c_2() {}

namespace gh117488 {
void func_with_body();
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'func_with_body'
// CHECK-FIXES: static void func_with_body();
void func_with_body() {}

void func_without_body();
void func_without_body();
}
13 changes: 4 additions & 9 deletions clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ class ExprMutationAnalyzer {

const Stmt *findPointeeMutation(const Expr *Exp);
const Stmt *findPointeeMutation(const Decl *Dec);
static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
ASTContext &Context);

private:
using MutationFinder = const Stmt *(Analyzer::*)(const Expr *);
Expand All @@ -58,8 +56,6 @@ class ExprMutationAnalyzer {
Memoized::ResultMap &MemoizedResults);
const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);

bool isUnevaluated(const Expr *Exp);

const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
const Stmt *
Expand All @@ -83,6 +79,10 @@ class ExprMutationAnalyzer {
ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
: Memorized(), A(Stm, Context, Memorized) {}

/// check whether stmt is unevaluated. mutation analyzer will ignore the
/// content in unevaluated stmt.
static bool isUnevaluated(const Stmt *Stm, ASTContext &Context);

bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
const Stmt *findMutation(const Expr *Exp) { return A.findMutation(Exp); }
Expand All @@ -101,11 +101,6 @@ class ExprMutationAnalyzer {
return A.findPointeeMutation(Dec);
}

static bool isUnevaluated(const Stmt *Smt, const Stmt &Stm,
ASTContext &Context) {
return Analyzer::isUnevaluated(Smt, Stm, Context);
}

private:
Memoized Memorized;
Analyzer A;
Expand Down
Loading

0 comments on commit 4a96fd8

Please sign in to comment.