Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into Select-v_sat_pk
Browse files Browse the repository at this point in the history
  • Loading branch information
Shoreshen committed Jan 9, 2025
2 parents 0e36c0d + cba9bd5 commit e4adc8f
Show file tree
Hide file tree
Showing 455 changed files with 7,803 additions and 4,633 deletions.
10 changes: 6 additions & 4 deletions clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,13 @@ TEST_F(LSPTest, ClangTidyRename) {
Annotations Source(R"cpp(
void [[foo]]() {}
)cpp");
Opts.ClangTidyProvider = [](tidy::ClangTidyOptions &ClangTidyOpts,
llvm::StringRef) {
constexpr auto ClangTidyProvider = [](tidy::ClangTidyOptions &ClangTidyOpts,
llvm::StringRef) {
ClangTidyOpts.Checks = {"-*,readability-identifier-naming"};
ClangTidyOpts.CheckOptions["readability-identifier-naming.FunctionCase"] =
"CamelCase";
};
Opts.ClangTidyProvider = ClangTidyProvider;
auto &Client = start();
Client.didOpen("foo.hpp", Header.code());
Client.didOpen("foo.cpp", Source.code());
Expand Down Expand Up @@ -266,10 +267,11 @@ TEST_F(LSPTest, ClangTidyCrash_Issue109367) {
// This test requires clang-tidy checks to be linked in.
if (!CLANGD_TIDY_CHECKS)
return;
Opts.ClangTidyProvider = [](tidy::ClangTidyOptions &ClangTidyOpts,
llvm::StringRef) {
constexpr auto ClangTidyProvider = [](tidy::ClangTidyOptions &ClangTidyOpts,
llvm::StringRef) {
ClangTidyOpts.Checks = {"-*,boost-use-ranges"};
};
Opts.ClangTidyProvider = ClangTidyProvider;
// Check that registering the boost-use-ranges checker's matchers
// on two different threads does not cause a crash.
auto &Client = start();
Expand Down
3 changes: 2 additions & 1 deletion clang-tools-extra/include-cleaner/lib/Analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ analyze(llvm::ArrayRef<Decl *> ASTRoots,
const auto MainFile = *SM.getFileEntryRefForID(SM.getMainFileID());
llvm::DenseSet<const Include *> Used;
llvm::StringMap<Header> Missing;
constexpr auto DefaultHeaderFilter = [](llvm::StringRef) { return false; };
if (!HeaderFilter)
HeaderFilter = [](llvm::StringRef) { return false; };
HeaderFilter = DefaultHeaderFilter;
OptionalDirectoryEntryRef ResourceDir =
PP.getHeaderSearchInfo().getModuleMap().getBuiltinDir();
walkUsed(ASTRoots, MacroRefs, PI, PP,
Expand Down
75 changes: 73 additions & 2 deletions clang/include/clang/AST/OpenACCClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,18 +327,89 @@ class OpenACCIfClause : public OpenACCClauseWithCondition {
SourceLocation EndLoc);
};

/// A 'self' clause, which has an optional condition expression.
class OpenACCSelfClause : public OpenACCClauseWithCondition {
/// A 'self' clause, which has an optional condition expression, or, in the
/// event of an 'update' directive, contains a 'VarList'.
class OpenACCSelfClause final
: public OpenACCClauseWithParams,
private llvm::TrailingObjects<OpenACCSelfClause, Expr *> {
friend TrailingObjects;
// Holds whether this HAS a condition expression. Lacks a value if this is NOT
// a condition-expr self clause.
std::optional<bool> HasConditionExpr;
// Holds the number of stored expressions. In the case of a condition-expr
// self clause, this is expected to be ONE (and there to be 1 trailing
// object), whether or not that is null.
unsigned NumExprs;

OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
Expr *ConditionExpr, SourceLocation EndLoc);
OpenACCSelfClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> VarList, SourceLocation EndLoc);

// Intentionally internal, meant to be an implementation detail of everything
// else. All non-internal uses should go through getConditionExpr/getVarList.
llvm::ArrayRef<Expr *> getExprs() const {
return {getTrailingObjects<Expr *>(), NumExprs};
}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Self;
}

bool isConditionExprClause() const { return HasConditionExpr.has_value(); }

bool hasConditionExpr() const {
assert(HasConditionExpr.has_value() &&
"VarList Self Clause asked about condition expression");
return *HasConditionExpr;
}

const Expr *getConditionExpr() const {
assert(HasConditionExpr.has_value() &&
"VarList Self Clause asked about condition expression");
assert(getExprs().size() == 1 &&
"ConditionExpr Self Clause with too many Exprs");
return getExprs()[0];
}

Expr *getConditionExpr() {
assert(HasConditionExpr.has_value() &&
"VarList Self Clause asked about condition expression");
assert(getExprs().size() == 1 &&
"ConditionExpr Self Clause with too many Exprs");
return getExprs()[0];
}

ArrayRef<Expr *> getVarList() {
assert(!HasConditionExpr.has_value() &&
"Condition Expr self clause asked about var list");
return getExprs();
}
ArrayRef<Expr *> getVarList() const {
assert(!HasConditionExpr.has_value() &&
"Condition Expr self clause asked about var list");
return getExprs();
}

child_range children() {
return child_range(
reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>()),
reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>() + NumExprs));
}

const_child_range children() const {
child_range Children = const_cast<OpenACCSelfClause *>(this)->children();
return const_child_range(Children.begin(), Children.end());
}

static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc,
SourceLocation LParenLoc,
Expr *ConditionExpr, SourceLocation EndLoc);
static OpenACCSelfClause *Create(const ASTContext &C, SourceLocation BeginLoc,
SourceLocation LParenLoc,
ArrayRef<Expr *> ConditionExpr,
SourceLocation EndLoc);
};

/// Represents a clause that has one or more expressions associated with it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CACHED_CONST_ACCESSORS_LATTICE_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CACHED_CONST_ACCESSORS_LATTICE_H

#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
Expand Down Expand Up @@ -71,10 +73,27 @@ template <typename Base> class CachedConstAccessorsLattice : public Base {
/// Requirements:
///
/// - `CE` should return a location (GLValue or a record type).
///
/// DEPRECATED: switch users to the below overload which takes Callee and Type
/// directly.
StorageLocation *getOrCreateConstMethodReturnStorageLocation(
const RecordStorageLocation &RecordLoc, const CallExpr *CE,
Environment &Env, llvm::function_ref<void(StorageLocation &)> Initialize);

/// Creates or returns a previously created `StorageLocation` associated with
/// a const method call `obj.getFoo()` where `RecordLoc` is the
/// `RecordStorageLocation` of `obj`, `Callee` is the decl for `getFoo`.
///
/// The callback `Initialize` runs on the storage location if newly created.
///
/// Requirements:
///
/// - `Callee` should return a location (return type is a reference type or a
/// record type).
StorageLocation &getOrCreateConstMethodReturnStorageLocation(
const RecordStorageLocation &RecordLoc, const FunctionDecl *Callee,
Environment &Env, llvm::function_ref<void(StorageLocation &)> Initialize);

void clearConstMethodReturnValues(const RecordStorageLocation &RecordLoc) {
ConstMethodReturnValues.erase(&RecordLoc);
}
Expand Down Expand Up @@ -212,6 +231,27 @@ CachedConstAccessorsLattice<Base>::getOrCreateConstMethodReturnStorageLocation(
return &Loc;
}

template <typename Base>
StorageLocation &
CachedConstAccessorsLattice<Base>::getOrCreateConstMethodReturnStorageLocation(
const RecordStorageLocation &RecordLoc, const FunctionDecl *Callee,
Environment &Env, llvm::function_ref<void(StorageLocation &)> Initialize) {
assert(Callee != nullptr);
QualType Type = Callee->getReturnType();
assert(!Type.isNull());
assert(Type->isReferenceType() || Type->isRecordType());
auto &ObjMap = ConstMethodReturnStorageLocations[&RecordLoc];
auto it = ObjMap.find(Callee);
if (it != ObjMap.end())
return *it->second;

StorageLocation &Loc = Env.createStorageLocation(Type.getNonReferenceType());
Initialize(Loc);

ObjMap.insert({Callee, &Loc});
return Loc;
}

} // namespace dataflow
} // namespace clang

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,13 @@ struct UncheckedOptionalAccessModelOptions {
/// can't identify when their results are used safely (across calls),
/// resulting in false positives in all such cases. Note: this option does not
/// cover access through `operator[]`.
/// FIXME: we currently cache and equate the result of const accessors
/// returning pointers, so cover the case of operator-> followed by
/// operator->, which covers the common case of smart pointers. We also cover
/// some limited cases of returning references (if return type is an optional
/// type), so cover some cases of operator* followed by operator*. We don't
/// cover mixing operator-> and operator*. Once we are confident in this const
/// accessor caching, we shouldn't need the IgnoreSmartPointerDereference
/// option anymore.
///
/// FIXME: we now cache and equate the result of const accessors
/// that look like unique_ptr, have both `->` (returning a pointer type) and
/// `*` (returning a reference type). This includes mixing `->` and
/// `*` in a sequence of calls as long as the object is not modified. Once we
/// are confident in this const accessor caching, we shouldn't need the
/// IgnoreSmartPointerDereference option anymore.
bool IgnoreSmartPointerDereference = false;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@
#include <cassert>

#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Stmt.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Analysis/FlowSensitive/MatchSwitch.h"
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
#include "clang/Analysis/FlowSensitive/Value.h"
#include "llvm/ADT/STLFunctionalExtras.h"

namespace clang::dataflow {

Expand Down Expand Up @@ -58,6 +63,107 @@ ast_matchers::StatementMatcher isSmartPointerLikeOperatorArrow();
ast_matchers::StatementMatcher isSmartPointerLikeValueMethodCall();
ast_matchers::StatementMatcher isSmartPointerLikeGetMethodCall();

// Common transfer functions.

/// Returns the "canonical" callee for smart pointer operators (`*` and `->`)
/// as a key for caching.
///
/// We choose `*` as the canonical one, since it needs a
/// StorageLocation anyway.
///
/// Note: there may be multiple `operator*` (one const, one non-const).
/// We pick the const one, which the above provided matchers require to exist.
const FunctionDecl *
getCanonicalSmartPointerLikeOperatorCallee(const CallExpr *CE);

/// A transfer function for `operator*` (and `value`) calls that can be
/// cached. Runs the `InitializeLoc` callback to initialize any new
/// StorageLocations.
///
/// Requirements:
///
/// - LatticeT should use the `CachedConstAccessorsLattice` mixin.
template <typename LatticeT>
void transferSmartPointerLikeCachedDeref(
const CallExpr *DerefExpr, RecordStorageLocation *SmartPointerLoc,
TransferState<LatticeT> &State,
llvm::function_ref<void(StorageLocation &)> InitializeLoc);

/// A transfer function for `operator->` (and `get`) calls that can be cached.
/// Runs the `InitializeLoc` callback to initialize any new StorageLocations.
///
/// Requirements:
///
/// - LatticeT should use the `CachedConstAccessorsLattice` mixin.
template <typename LatticeT>
void transferSmartPointerLikeCachedGet(
const CallExpr *GetExpr, RecordStorageLocation *SmartPointerLoc,
TransferState<LatticeT> &State,
llvm::function_ref<void(StorageLocation &)> InitializeLoc);

template <typename LatticeT>
void transferSmartPointerLikeCachedDeref(
const CallExpr *DerefExpr, RecordStorageLocation *SmartPointerLoc,
TransferState<LatticeT> &State,
llvm::function_ref<void(StorageLocation &)> InitializeLoc) {
if (State.Env.getStorageLocation(*DerefExpr) != nullptr)
return;
if (SmartPointerLoc == nullptr)
return;

const FunctionDecl *Callee = DerefExpr->getDirectCallee();
if (Callee == nullptr)
return;
const FunctionDecl *CanonicalCallee =
getCanonicalSmartPointerLikeOperatorCallee(DerefExpr);
// This shouldn't happen, as we should at least find `Callee` itself.
assert(CanonicalCallee != nullptr);
if (CanonicalCallee != Callee) {
// When using the provided matchers, we should always get a reference to
// the same type.
assert(CanonicalCallee->getReturnType()->isReferenceType() &&
Callee->getReturnType()->isReferenceType());
assert(CanonicalCallee->getReturnType()
.getNonReferenceType()
->getCanonicalTypeUnqualified() ==
Callee->getReturnType()
.getNonReferenceType()
->getCanonicalTypeUnqualified());
}

StorageLocation &LocForValue =
State.Lattice.getOrCreateConstMethodReturnStorageLocation(
*SmartPointerLoc, CanonicalCallee, State.Env, InitializeLoc);
State.Env.setStorageLocation(*DerefExpr, LocForValue);
}

template <typename LatticeT>
void transferSmartPointerLikeCachedGet(
const CallExpr *GetExpr, RecordStorageLocation *SmartPointerLoc,
TransferState<LatticeT> &State,
llvm::function_ref<void(StorageLocation &)> InitializeLoc) {
if (SmartPointerLoc == nullptr)
return;

const FunctionDecl *CanonicalCallee =
getCanonicalSmartPointerLikeOperatorCallee(GetExpr);

if (CanonicalCallee != nullptr) {
auto &LocForValue =
State.Lattice.getOrCreateConstMethodReturnStorageLocation(
*SmartPointerLoc, CanonicalCallee, State.Env, InitializeLoc);
State.Env.setValue(*GetExpr,
State.Env.template create<PointerValue>(LocForValue));
} else {
// Otherwise, just cache the pointer value as if it was a const accessor.
Value *Val = State.Lattice.getOrCreateConstMethodReturnValue(
*SmartPointerLoc, GetExpr, State.Env);
if (Val == nullptr)
return;
State.Env.setValue(*GetExpr, *Val);
}
}

} // namespace clang::dataflow

#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_SMARTPOINTERACCESSORCACHING_H
10 changes: 0 additions & 10 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -4335,16 +4335,6 @@ def HLSLLoopHint: StmtAttr {
let Documentation = [HLSLLoopHintDocs, HLSLUnrollHintDocs];
}

def HLSLControlFlowHint: StmtAttr {
/// [branch]
/// [flatten]
let Spellings = [Microsoft<"branch">, Microsoft<"flatten">];
let Subjects = SubjectList<[IfStmt],
ErrorDiag, "'if' statements">;
let LangOpts = [HLSL];
let Documentation = [InternalOnly];
}

def CapturedRecord : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly.
let Spellings = [];
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -1531,7 +1531,7 @@ class TargetInfo : public TransferrableTargetInfo,

// Return the target-specific priority for features/cpus/vendors so
// that they can be properly sorted for checking.
virtual unsigned getFMVPriority(ArrayRef<StringRef> Features) const {
virtual uint64_t getFMVPriority(ArrayRef<StringRef> Features) const {
return 0;
}

Expand Down
Loading

0 comments on commit e4adc8f

Please sign in to comment.