Skip to content

Commit 26273d5

Browse files
committed
merge main into amd-staging
2 parents 3035dd8 + dff2ca4 commit 26273d5

File tree

118 files changed

+5697
-2614
lines changed

Some content is hidden

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

118 files changed

+5697
-2614
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1674,6 +1674,7 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
16741674
const Expr *LHS = E->getLHS();
16751675
const Expr *RHS = E->getRHS();
16761676
const Expr *Index = E->getIdx();
1677+
const Expr *Base = E->getBase();
16771678

16781679
if (DiscardResult)
16791680
return this->discard(LHS) && this->discard(RHS);
@@ -1682,8 +1683,17 @@ bool Compiler<Emitter>::VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
16821683
// side is the base.
16831684
bool Success = true;
16841685
for (const Expr *SubExpr : {LHS, RHS}) {
1685-
if (!this->visit(SubExpr))
1686+
if (!this->visit(SubExpr)) {
16861687
Success = false;
1688+
continue;
1689+
}
1690+
1691+
// Expand the base if this is a subscript on a
1692+
// pointer expression.
1693+
if (SubExpr == Base && Base->getType()->isPointerType()) {
1694+
if (!this->emitExpandPtr(E))
1695+
Success = false;
1696+
}
16871697
}
16881698

16891699
if (!Success)

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -139,17 +139,19 @@ static bool CheckActive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
139139

140140
Pointer U = Ptr.getBase();
141141
Pointer C = Ptr;
142-
while (!U.isRoot() && U.inUnion() && !U.isActive()) {
143-
if (U.getField())
144-
C = U;
142+
while (!U.isRoot() && !U.isActive()) {
143+
// A little arbitrary, but this is what the current interpreter does.
144+
// See the AnonymousUnion test in test/AST/ByteCode/unions.cpp.
145+
// GCC's output is more similar to what we would get without
146+
// this condition.
147+
if (U.getRecord() && U.getRecord()->isAnonymousUnion())
148+
break;
149+
150+
C = U;
145151
U = U.getBase();
146152
}
147153
assert(C.isField());
148154

149-
// Get the inactive field descriptor.
150-
const FieldDecl *InactiveField = C.getField();
151-
assert(InactiveField);
152-
153155
// Consider:
154156
// union U {
155157
// struct {
@@ -165,6 +167,11 @@ static bool CheckActive(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
165167
if (!U.getFieldDesc()->isUnion())
166168
return true;
167169

170+
// Get the inactive field descriptor.
171+
assert(!C.isActive());
172+
const FieldDecl *InactiveField = C.getField();
173+
assert(InactiveField);
174+
168175
// Find the active field of the union.
169176
const Record *R = U.getRecord();
170177
assert(R && R->isUnion() && "Not a union");

clang/lib/AST/ByteCode/Interp.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2589,7 +2589,10 @@ inline bool NarrowPtr(InterpState &S, CodePtr OpPC) {
25892589

25902590
inline bool ExpandPtr(InterpState &S, CodePtr OpPC) {
25912591
const Pointer &Ptr = S.Stk.pop<Pointer>();
2592-
S.Stk.push<Pointer>(Ptr.expand());
2592+
if (Ptr.isBlockPointer())
2593+
S.Stk.push<Pointer>(Ptr.expand());
2594+
else
2595+
S.Stk.push<Pointer>(Ptr);
25932596
return true;
25942597
}
25952598

clang/lib/AST/ByteCode/Pointer.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -437,28 +437,35 @@ void Pointer::activate() const {
437437
if (!getInlineDesc()->InUnion)
438438
return;
439439

440-
getInlineDesc()->IsActive = true;
440+
auto activate = [](Pointer &P) -> void {
441+
P.getInlineDesc()->IsActive = true;
442+
};
443+
auto deactivate = [](Pointer &P) -> void {
444+
P.getInlineDesc()->IsActive = false;
445+
};
441446

442-
// Get the union, iterate over its fields and DEactivate all others.
447+
// Unions might be nested etc., so find the topmost Pointer that's
448+
// not in a union anymore.
443449
Pointer UnionPtr = getBase();
444-
while (!UnionPtr.getFieldDesc()->isUnion())
450+
while (!UnionPtr.isRoot() && UnionPtr.inUnion())
445451
UnionPtr = UnionPtr.getBase();
446452

453+
assert(UnionPtr.getFieldDesc()->isUnion());
454+
447455
const Record *UnionRecord = UnionPtr.getRecord();
448456
for (const Record::Field &F : UnionRecord->fields()) {
449457
Pointer FieldPtr = UnionPtr.atField(F.Offset);
450458
if (FieldPtr == *this) {
451459
} else {
452-
FieldPtr.getInlineDesc()->IsActive = false;
460+
deactivate(FieldPtr);
453461
// FIXME: Recurse.
454462
}
455463
}
456464

457-
Pointer B = getBase();
458-
while (!B.isRoot() && B.inUnion()) {
465+
Pointer B = *this;
466+
while (B != UnionPtr) {
467+
activate(B);
459468
// FIXME: Need to de-activate other fields of parent records.
460-
B.getInlineDesc()->IsActive = true;
461-
assert(B.isActive());
462469
B = B.getBase();
463470
}
464471
}

clang/lib/AST/ByteCode/Pointer.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,6 @@ class Pointer {
494494
/// Returns the field information.
495495
const FieldDecl *getField() const { return getFieldDesc()->asFieldDecl(); }
496496

497-
/// Checks if the object is a union.
498-
bool isUnion() const;
499-
500497
/// Checks if the storage is extern.
501498
bool isExtern() const {
502499
if (isBlockPointer())

clang/lib/Headers/cpuid.h

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -267,18 +267,18 @@
267267
: "0"(__leaf), "2"(__count))
268268
#else
269269
/* x86-64 uses %rbx as the base register, so preserve it. */
270-
#define __cpuid(__leaf, __eax, __ebx, __ecx, __edx) \
271-
__asm(" xchgq %%rbx,%q1\n" \
272-
" cpuid\n" \
273-
" xchgq %%rbx,%q1" \
274-
: "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \
270+
#define __cpuid(__leaf, __eax, __ebx, __ecx, __edx) \
271+
__asm(" xchg{q|} {%%|}rbx,%q1\n" \
272+
" cpuid\n" \
273+
" xchg{q|} {%%|}rbx,%q1" \
274+
: "=a"(__eax), "=r"(__ebx), "=c"(__ecx), "=d"(__edx) \
275275
: "0"(__leaf))
276276

277-
#define __cpuid_count(__leaf, __count, __eax, __ebx, __ecx, __edx) \
278-
__asm(" xchgq %%rbx,%q1\n" \
279-
" cpuid\n" \
280-
" xchgq %%rbx,%q1" \
281-
: "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \
277+
#define __cpuid_count(__leaf, __count, __eax, __ebx, __ecx, __edx) \
278+
__asm(" xchg{q|} {%%|}rbx,%q1\n" \
279+
" cpuid\n" \
280+
" xchg{q|} {%%|}rbx,%q1" \
281+
: "=a"(__eax), "=r"(__ebx), "=c"(__ecx), "=d"(__edx) \
282282
: "0"(__leaf), "2"(__count))
283283
#endif
284284

@@ -289,20 +289,22 @@ static __inline unsigned int __get_cpuid_max (unsigned int __leaf,
289289
#ifdef __i386__
290290
int __cpuid_supported;
291291

292-
__asm(" pushfl\n"
293-
" popl %%eax\n"
294-
" movl %%eax,%%ecx\n"
295-
" xorl $0x00200000,%%eax\n"
296-
" pushl %%eax\n"
297-
" popfl\n"
298-
" pushfl\n"
299-
" popl %%eax\n"
300-
" movl $0,%0\n"
301-
" cmpl %%eax,%%ecx\n"
292+
__asm(" pushf{l|d}\n"
293+
" pop{l|} {%%|}eax\n"
294+
" mov{l|} {%%eax,%%ecx|ecx,eax}\n"
295+
" xor{l|} {$0x00200000,%%eax|eax,0x00200000}\n"
296+
" push{l|} {%%|}eax\n"
297+
" popf{l|d}\n"
298+
" pushf{l|d}\n"
299+
" pop{l|} {%%|}eax\n"
300+
" mov{l|} {$0,%0|%0,0}\n"
301+
" cmp{l|} {%%eax,%%ecx|ecx,eax}\n"
302302
" je 1f\n"
303-
" movl $1,%0\n"
303+
" mov{l|} {$1,%0|%0,1}\n"
304304
"1:"
305-
: "=r" (__cpuid_supported) : : "eax", "ecx");
305+
: "=r"(__cpuid_supported)
306+
:
307+
: "eax", "ecx");
306308
if (!__cpuid_supported)
307309
return 0;
308310
#endif

clang/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,6 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
314314
RegionArgIsBad = true;
315315
}
316316

317-
assert(ArgSM);
318317
// Is the argument to the call being tracked?
319318
const AllocationState *AS = State->get<AllocatedData>(ArgSM);
320319
if (!AS)

clang/test/AST/ByteCode/arrays.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,3 +662,16 @@ namespace InvalidIndex {
662662
}
663663
static_assert(foo(0) == 1, "");
664664
}
665+
666+
namespace PointerSubscript {
667+
template<typename T>
668+
constexpr T foo() {
669+
T ss[] = {{}, {}, {}};
670+
T *s = &ss[0];
671+
672+
return s[2];
673+
}
674+
static_assert(foo<int>() == 0);
675+
struct S{};
676+
static_assert((foo<S>(), true));
677+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %clang_cc1 -std=c++2c -fexperimental-new-constant-interpreter -verify=expected,both %s
2+
// RUN: %clang_cc1 -std=c++2c -verify=ref,both %s
3+
4+
// both-no-diagnostics
5+
6+
namespace std {
7+
inline namespace __1 {
8+
template <class _Tp> class unique_ptr;
9+
template <class _Tp> class unique_ptr<_Tp[]> {
10+
public:
11+
_Tp* __ptr_;
12+
13+
public:
14+
constexpr _Tp&
15+
operator[](unsigned i) const {
16+
return __ptr_[i];
17+
};
18+
};
19+
} // namespace __1
20+
} // namespace std
21+
struct WithTrivialDtor {
22+
int x = 6;
23+
constexpr friend void operator==(WithTrivialDtor const &x,
24+
WithTrivialDtor const &y) {
25+
(void)(x.x == y.x);
26+
}
27+
};
28+
constexpr bool test() {
29+
30+
WithTrivialDtor array[50];
31+
std::unique_ptr<WithTrivialDtor[]> p(&array[0]);
32+
(void)(p[1] == WithTrivialDtor());
33+
34+
return true;
35+
}
36+
static_assert(test());

clang/test/AST/ByteCode/unions.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,4 +485,23 @@ namespace IFD {
485485
}
486486
static_assert(test());
487487
}
488+
489+
namespace AnonymousUnion {
490+
struct A {
491+
int x;
492+
union { int p, q; };
493+
};
494+
union B {
495+
A a;
496+
int bb;
497+
};
498+
499+
constexpr B return_init_all() {
500+
B b = {.bb = 1};
501+
b.a.x = 2;
502+
return b;
503+
}
504+
static_assert(return_init_all().a.p == 7); // both-error {{}} \
505+
// both-note {{read of member 'p' of union with no active member}}
506+
}
488507
#endif

0 commit comments

Comments
 (0)