Skip to content

Commit fcf1e48

Browse files
committed
merge main into amd-staging
2 parents f63674c + 494253f commit fcf1e48

File tree

38 files changed

+1669
-50
lines changed

38 files changed

+1669
-50
lines changed

clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,11 @@ void UnconventionalAssignOperatorCheck::registerMatchers(
6666
hasArgument(0, cxxThisExpr())),
6767
cxxOperatorCallExpr(
6868
hasOverloadedOperatorName("="),
69-
hasArgument(
70-
0, unaryOperator(hasOperatorName("*"),
69+
hasArgument(0, unaryOperator(hasOperatorName("*"),
70+
hasUnaryOperand(cxxThisExpr())))),
71+
binaryOperator(
72+
hasOperatorName("="),
73+
hasLHS(unaryOperator(hasOperatorName("*"),
7174
hasUnaryOperand(cxxThisExpr())))))))));
7275
const auto IsGoodAssign = cxxMethodDecl(IsAssign, HasGoodReturnType);
7376

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,11 @@ Changes in existing checks
266266
<clang-tidy/checks/misc/redundant-expression>` check by providing additional
267267
examples and fixing some macro related false positives.
268268

269+
- Improved :doc:`misc-unconventional-assign-operator
270+
<clang-tidy/checks/misc/unconventional-assign-operator>` check by fixing
271+
false positives when copy assignment operator function in a template class
272+
returns the result of another assignment to ``*this`` (``return *this=...``).
273+
269274
- Improved :doc:`misc-unused-using-decls
270275
<clang-tidy/checks/misc/unused-using-decls>` check by fixing false positives
271276
on ``operator""`` with template parameters.

clang-tools-extra/test/clang-tidy/checkers/misc/unconventional-assign-operator.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,16 @@ struct TemplateTypeAlias {
163163
Alias3<TypeAlias::Alias> &operator=(double) { return *this; }
164164
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'TemplateTypeAlias&' [misc-unconventional-assign-operator]
165165
};
166+
167+
namespace gh143237 {
168+
template<typename T>
169+
struct TemplateAssignment {
170+
explicit TemplateAssignment(int) {
171+
}
172+
173+
TemplateAssignment& operator=(int n) {
174+
// No warning
175+
return *this = TemplateAssignment(n);
176+
}
177+
};
178+
}

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5545,7 +5545,6 @@ bool Compiler<Emitter>::visitCXXForRangeStmt(const CXXForRangeStmt *S) {
55455545
const Stmt *BeginStmt = S->getBeginStmt();
55465546
const Stmt *RangeStmt = S->getRangeStmt();
55475547
const Stmt *EndStmt = S->getEndStmt();
5548-
const VarDecl *LoopVar = S->getLoopVariable();
55495548

55505549
LabelTy EndLabel = this->getLabel();
55515550
LabelTy CondLabel = this->getLabel();
@@ -5570,7 +5569,7 @@ bool Compiler<Emitter>::visitCXXForRangeStmt(const CXXForRangeStmt *S) {
55705569
if (!this->jumpFalse(EndLabel))
55715570
return false;
55725571

5573-
if (!this->visitVarDecl(LoopVar))
5572+
if (!this->visitDeclStmt(S->getLoopVarStmt(), /*EvaluateConditionDecl=*/true))
55745573
return false;
55755574

55765575
// Body.

clang/lib/AST/ByteCode/Interp.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,8 +1930,10 @@ bool StoreBitField(InterpState &S, CodePtr OpPC) {
19301930
const Pointer &Ptr = S.Stk.peek<Pointer>();
19311931
if (!CheckStore(S, OpPC, Ptr))
19321932
return false;
1933-
if (Ptr.canBeInitialized())
1933+
if (Ptr.canBeInitialized()) {
19341934
Ptr.initialize();
1935+
Ptr.activate();
1936+
}
19351937
if (const auto *FD = Ptr.getField())
19361938
Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue());
19371939
else
@@ -1945,8 +1947,10 @@ bool StoreBitFieldPop(InterpState &S, CodePtr OpPC) {
19451947
const Pointer &Ptr = S.Stk.pop<Pointer>();
19461948
if (!CheckStore(S, OpPC, Ptr))
19471949
return false;
1948-
if (Ptr.canBeInitialized())
1950+
if (Ptr.canBeInitialized()) {
19491951
Ptr.initialize();
1952+
Ptr.activate();
1953+
}
19501954
if (const auto *FD = Ptr.getField())
19511955
Ptr.deref<T>() = Value.truncate(FD->getBitWidthValue());
19521956
else

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,9 @@ static bool interp__builtin_overflowop(InterpState &S, CodePtr OpPC,
861861

862862
// Write Result to ResultPtr and put Overflow on the stack.
863863
assignInteger(S, ResultPtr, ResultT, Result);
864-
ResultPtr.initialize();
864+
if (ResultPtr.canBeInitialized())
865+
ResultPtr.initialize();
866+
865867
assert(Call->getDirectCallee()->getReturnType()->isBooleanType());
866868
S.Stk.push<Boolean>(Overflow);
867869
return true;

clang/lib/AST/ByteCode/Pointer.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -505,8 +505,19 @@ void Pointer::activate() const {
505505
auto activate = [](Pointer &P) -> void {
506506
P.getInlineDesc()->IsActive = true;
507507
};
508-
auto deactivate = [](Pointer &P) -> void {
508+
509+
std::function<void(Pointer &)> deactivate;
510+
deactivate = [&deactivate](Pointer &P) -> void {
509511
P.getInlineDesc()->IsActive = false;
512+
513+
if (const Record *R = P.getRecord()) {
514+
for (const Record::Field &F : R->fields()) {
515+
Pointer FieldPtr = P.atField(F.Offset);
516+
if (FieldPtr.getInlineDesc()->IsActive)
517+
deactivate(FieldPtr);
518+
}
519+
// FIXME: Bases?
520+
}
510521
};
511522

512523
// Unions might be nested etc., so find the topmost Pointer that's
@@ -516,21 +527,31 @@ void Pointer::activate() const {
516527
UnionPtr = UnionPtr.getBase();
517528

518529
assert(UnionPtr.getFieldDesc()->isUnion());
519-
520530
const Record *UnionRecord = UnionPtr.getRecord();
531+
532+
// The direct child pointer of the union that's on the path from
533+
// this pointer to the union.
534+
Pointer ChildPtr = *this;
535+
assert(ChildPtr != UnionPtr);
536+
while (true) {
537+
if (ChildPtr.getBase() == UnionPtr)
538+
break;
539+
ChildPtr = ChildPtr.getBase();
540+
}
541+
assert(ChildPtr.getBase() == UnionPtr);
542+
521543
for (const Record::Field &F : UnionRecord->fields()) {
522544
Pointer FieldPtr = UnionPtr.atField(F.Offset);
523-
if (FieldPtr == *this) {
545+
if (FieldPtr == ChildPtr) {
546+
// No need to deactivate, will be activated in the next loop.
524547
} else {
525548
deactivate(FieldPtr);
526-
// FIXME: Recurse.
527549
}
528550
}
529551

530552
Pointer B = *this;
531553
while (B != UnionPtr) {
532554
activate(B);
533-
// FIXME: Need to de-activate other fields of parent records.
534555
B = B.getBase();
535556
}
536557
}

clang/test/AST/ByteCode/builtin-functions.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,4 +1753,12 @@ namespace I128Mul {
17531753
}
17541754
#endif
17551755

1756+
namespace InitParam {
1757+
constexpr int foo(int a) {
1758+
__builtin_mul_overflow(20, 10, &a);
1759+
return a;
1760+
}
1761+
static_assert(foo(10) == 200);
1762+
}
1763+
17561764
#endif

0 commit comments

Comments
 (0)