Skip to content

Commit dab6115

Browse files
author
Jenkins
committed
merge main into amd-staging
Change-Id: I523d4fde2b9e511fa85cb38723110d8e901bb78b
2 parents 5010bcc + 97088b2 commit dab6115

File tree

154 files changed

+5651
-2764
lines changed

Some content is hidden

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

154 files changed

+5651
-2764
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ void UnusedLocalNonTrivialVariableCheck::registerMatchers(MatchFinder *Finder) {
6060
varDecl(isLocalVarDecl(), unless(isReferenced()),
6161
unless(isExceptionVariable()), hasLocalStorage(), isDefinition(),
6262
unless(hasType(isReferenceType())), unless(hasType(isTrivial())),
63+
unless(hasAttr(attr::Kind::Unused)),
6364
hasType(hasUnqualifiedDesugaredType(
6465
anyOf(recordType(hasDeclaration(namedDecl(
6566
matchesAnyListedName(IncludeTypes),

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ Changes in existing checks
121121
<clang-tidy/checks/bugprone/too-small-loop-variable>` check by incorporating
122122
better support for ``const`` loop boundaries.
123123

124+
- Improved :doc:`bugprone-unused-local-non-trivial-variable
125+
<clang-tidy/checks/bugprone/unused-local-non-trivial-variable>` check by
126+
ignoring local variable with ``[maybe_unused]`` attribute.
127+
124128
- Cleaned up :doc:`cppcoreguidelines-prefer-member-initializer
125129
<clang-tidy/checks/cppcoreguidelines/prefer-member-initializer>`
126130
by removing enforcement of rule `C.48

clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-local-non-trivial-variable.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The following types of variables are excluded from this check:
1111
* exception variables in catch clauses
1212
* static or thread local
1313
* structured bindings
14+
* variables with ``[[maybe_unused]]`` attribute
1415

1516
This check can be configured to warn on all non-trivial variables by setting
1617
`IncludeTypes` to `.*`, and excluding specific types using `ExcludeTypes`.

clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ T qux(T Generic) {
7777
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unused local variable 'TemplateType' of type 'async::Future<T>' [bugprone-unused-local-non-trivial-variable]
7878
a::Future<T> AliasTemplateType;
7979
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unused local variable 'AliasTemplateType' of type 'a::Future<T>' (aka 'Future<type-parameter-0-0>') [bugprone-unused-local-non-trivial-variable]
80+
[[maybe_unused]] async::Future<Units> MaybeUnused;
8081
return Generic;
8182
}
8283

clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ class DataflowAnalysisContext {
100100
/// to add to a `RecordStorageLocation` of a given type.
101101
/// Typically, this is called from the constructor of a `DataflowAnalysis`
102102
///
103+
/// The field types returned by the callback may not have reference type.
104+
///
103105
/// To maintain the invariant that all `RecordStorageLocation`s of a given
104106
/// type have the same fields:
105107
/// * The callback must always return the same result for a given type
@@ -205,8 +207,17 @@ class DataflowAnalysisContext {
205207
/// type.
206208
llvm::StringMap<QualType> getSyntheticFields(QualType Type) {
207209
assert(Type->isRecordType());
208-
if (SyntheticFieldCallback)
209-
return SyntheticFieldCallback(Type);
210+
if (SyntheticFieldCallback) {
211+
llvm::StringMap<QualType> Result = SyntheticFieldCallback(Type);
212+
// Synthetic fields are not allowed to have reference type.
213+
assert([&Result] {
214+
for (const auto &Entry : Result)
215+
if (Entry.getValue()->isReferenceType())
216+
return false;
217+
return true;
218+
}());
219+
return Result;
220+
}
210221
return {};
211222
}
212223

clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,14 @@ class Environment {
681681
llvm::DenseSet<QualType> &Visited,
682682
int Depth, int &CreatedValuesCount);
683683

684+
/// Initializes the fields (including synthetic fields) of `Loc` with values,
685+
/// unless values of the field type are not supported or we hit one of the
686+
/// limits at which we stop producing values (controlled by `Visited`,
687+
/// `Depth`, and `CreatedValuesCount`).
688+
void initializeFieldsWithValues(RecordStorageLocation &Loc,
689+
llvm::DenseSet<QualType> &Visited, int Depth,
690+
int &CreatedValuesCount);
691+
684692
/// Shared implementation of `createObject()` overloads.
685693
/// `D` and `InitExpr` may be null.
686694
StorageLocation &createObjectInternal(const ValueDecl *D, QualType Ty,

clang/include/clang/Driver/Options.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4497,7 +4497,7 @@ def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=
44974497
def march_EQ : Joined<["-"], "march=">, Group<m_Group>,
44984498
Flags<[TargetSpecific]>, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
44994499
HelpText<"For a list of available architectures for the target use '-mcpu=help'">;
4500-
def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>;
4500+
def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Visibility<[ClangOption, FlangOption]>;
45014501
def inline_asm_EQ : Joined<["-"], "inline-asm=">, Group<m_Group>,
45024502
Visibility<[ClangOption, CC1Option]>,
45034503
Values<"att,intel">,

clang/lib/AST/Interp/Pointer.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx) const {
232232

233233
// Primitive values.
234234
if (std::optional<PrimType> T = Ctx.classify(Ty)) {
235-
if (T == PT_Ptr || T == PT_FnPtr) {
236-
R = Ptr.toAPValue();
237-
} else {
238-
TYPE_SWITCH(*T, R = Ptr.deref<T>().toAPValue());
239-
}
235+
TYPE_SWITCH(*T, R = Ptr.deref<T>().toAPValue());
240236
return true;
241237
}
242238

clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -887,34 +887,10 @@ Value *Environment::createValueUnlessSelfReferential(
887887

888888
if (Type->isRecordType()) {
889889
CreatedValuesCount++;
890-
llvm::DenseMap<const ValueDecl *, StorageLocation *> FieldLocs;
891-
for (const FieldDecl *Field : DACtx->getModeledFields(Type)) {
892-
assert(Field != nullptr);
890+
auto &Loc = cast<RecordStorageLocation>(createStorageLocation(Type));
891+
initializeFieldsWithValues(Loc, Visited, Depth, CreatedValuesCount);
893892

894-
QualType FieldType = Field->getType();
895-
896-
FieldLocs.insert(
897-
{Field, &createLocAndMaybeValue(FieldType, Visited, Depth + 1,
898-
CreatedValuesCount)});
899-
}
900-
901-
RecordStorageLocation::SyntheticFieldMap SyntheticFieldLocs;
902-
for (const auto &Entry : DACtx->getSyntheticFields(Type)) {
903-
SyntheticFieldLocs.insert(
904-
{Entry.getKey(),
905-
&createLocAndMaybeValue(Entry.getValue(), Visited, Depth + 1,
906-
CreatedValuesCount)});
907-
}
908-
909-
RecordStorageLocation &Loc = DACtx->createRecordStorageLocation(
910-
Type, std::move(FieldLocs), std::move(SyntheticFieldLocs));
911-
RecordValue &RecordVal = create<RecordValue>(Loc);
912-
913-
// As we already have a storage location for the `RecordValue`, we can and
914-
// should associate them in the environment.
915-
setValue(Loc, RecordVal);
916-
917-
return &RecordVal;
893+
return &refreshRecordValue(Loc, *this);
918894
}
919895

920896
return nullptr;
@@ -943,6 +919,50 @@ Environment::createLocAndMaybeValue(QualType Ty,
943919
return Loc;
944920
}
945921

922+
void Environment::initializeFieldsWithValues(RecordStorageLocation &Loc,
923+
llvm::DenseSet<QualType> &Visited,
924+
int Depth,
925+
int &CreatedValuesCount) {
926+
auto initField = [&](QualType FieldType, StorageLocation &FieldLoc) {
927+
if (FieldType->isRecordType()) {
928+
auto &FieldRecordLoc = cast<RecordStorageLocation>(FieldLoc);
929+
setValue(FieldRecordLoc, create<RecordValue>(FieldRecordLoc));
930+
initializeFieldsWithValues(FieldRecordLoc, Visited, Depth + 1,
931+
CreatedValuesCount);
932+
} else {
933+
if (!Visited.insert(FieldType.getCanonicalType()).second)
934+
return;
935+
if (Value *Val = createValueUnlessSelfReferential(
936+
FieldType, Visited, Depth + 1, CreatedValuesCount))
937+
setValue(FieldLoc, *Val);
938+
Visited.erase(FieldType.getCanonicalType());
939+
}
940+
};
941+
942+
for (const auto &[Field, FieldLoc] : Loc.children()) {
943+
assert(Field != nullptr);
944+
QualType FieldType = Field->getType();
945+
946+
if (FieldType->isReferenceType()) {
947+
Loc.setChild(*Field,
948+
&createLocAndMaybeValue(FieldType, Visited, Depth + 1,
949+
CreatedValuesCount));
950+
} else {
951+
assert(FieldLoc != nullptr);
952+
initField(FieldType, *FieldLoc);
953+
}
954+
}
955+
for (const auto &[FieldName, FieldLoc] : Loc.synthetic_fields()) {
956+
assert(FieldLoc != nullptr);
957+
QualType FieldType = FieldLoc->getType();
958+
959+
// Synthetic fields cannot have reference type, so we don't need to deal
960+
// with this case.
961+
assert(!FieldType->isReferenceType());
962+
initField(FieldType, Loc.getSyntheticField(FieldName));
963+
}
964+
}
965+
946966
StorageLocation &Environment::createObjectInternal(const ValueDecl *D,
947967
QualType Ty,
948968
const Expr *InitExpr) {

clang/lib/Analysis/FlowSensitive/Transfer.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,19 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
535535
return;
536536

537537
copyRecord(*LocSrc, *LocDst, Env);
538-
Env.setStorageLocation(*S, *LocDst);
538+
539+
// If the expr is a glvalue, we can reasonably assume the operator is
540+
// returning T& and thus we can assign it `LocDst`.
541+
if (S->isGLValue()) {
542+
Env.setStorageLocation(*S, *LocDst);
543+
} else if (S->getType()->isRecordType()) {
544+
// Make sure that we have a `RecordValue` for this expression so that
545+
// `Environment::getResultObjectLocation()` is able to return a location
546+
// for it.
547+
if (Env.getValue(*S) == nullptr)
548+
refreshRecordValue(*S, Env);
549+
}
550+
539551
return;
540552
}
541553

0 commit comments

Comments
 (0)