Skip to content

Commit 1b939f5

Browse files
author
Jenkins
committed
merge main into amd-staging
Change-Id: I89b126e6306ab508eea44c80ca6f21681264fe81
2 parents 80150e5 + da69449 commit 1b939f5

File tree

163 files changed

+6008
-1356
lines changed

Some content is hidden

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

163 files changed

+6008
-1356
lines changed

clang/lib/AST/ByteCode/InterpFrame.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,31 +207,40 @@ Pointer InterpFrame::getParamPointer(unsigned Off) {
207207
return Pointer(B);
208208
}
209209

210+
static bool funcHasUsableBody(const Function *F) {
211+
assert(F);
212+
213+
if (F->isConstructor() || F->isDestructor())
214+
return true;
215+
216+
return !F->getDecl()->isImplicit();
217+
}
218+
210219
SourceInfo InterpFrame::getSource(CodePtr PC) const {
211220
// Implicitly created functions don't have any code we could point at,
212221
// so return the call site.
213-
if (Func && (!Func->hasBody() || Func->getDecl()->isImplicit()) && Caller)
222+
if (Func && !funcHasUsableBody(Func) && Caller)
214223
return Caller->getSource(RetPC);
215224

216225
return S.getSource(Func, PC);
217226
}
218227

219228
const Expr *InterpFrame::getExpr(CodePtr PC) const {
220-
if (Func && (!Func->hasBody() || Func->getDecl()->isImplicit()) && Caller)
221-
return Caller->getExpr(RetPC);
229+
if (Func && !funcHasUsableBody(Func) && Caller)
230+
return Caller->getExpr(PC);
222231

223232
return S.getExpr(Func, PC);
224233
}
225234

226235
SourceLocation InterpFrame::getLocation(CodePtr PC) const {
227-
if (Func && (!Func->hasBody() || Func->getDecl()->isImplicit()) && Caller)
236+
if (Func && !funcHasUsableBody(Func) && Caller)
228237
return Caller->getLocation(RetPC);
229238

230239
return S.getLocation(Func, PC);
231240
}
232241

233242
SourceRange InterpFrame::getRange(CodePtr PC) const {
234-
if (Func && (!Func->hasBody() || Func->getDecl()->isImplicit()) && Caller)
243+
if (Func && !funcHasUsableBody(Func) && Caller)
235244
return Caller->getRange(RetPC);
236245

237246
return S.getRange(Func, PC);

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5171,7 +5171,8 @@ static bool HasNonDeletedDefaultedEqualityComparison(Sema &S,
51715171

51725172
// const ClassT& obj;
51735173
OpaqueValueExpr Operand(
5174-
{}, Decl->getTypeForDecl()->getCanonicalTypeUnqualified().withConst(),
5174+
KeyLoc,
5175+
Decl->getTypeForDecl()->getCanonicalTypeUnqualified().withConst(),
51755176
ExprValueKind::VK_LValue);
51765177
UnresolvedSet<16> Functions;
51775178
// obj == obj;

clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,32 @@ class DerefFuncDeleteExprVisitor
6767
const Decl *D = CE->getCalleeDecl();
6868
if (D && D->hasBody())
6969
return VisitBody(D->getBody());
70+
else {
71+
auto name = safeGetName(D);
72+
if (name == "ensureOnMainThread" || name == "ensureOnMainRunLoop") {
73+
for (unsigned i = 0; i < CE->getNumArgs(); ++i) {
74+
auto *Arg = CE->getArg(i);
75+
if (VisitLabmdaArgument(Arg))
76+
return true;
77+
}
78+
}
79+
}
80+
return false;
81+
}
82+
83+
bool VisitLabmdaArgument(const Expr *E) {
84+
E = E->IgnoreParenCasts();
85+
if (auto *TempE = dyn_cast<CXXBindTemporaryExpr>(E))
86+
E = TempE->getSubExpr();
87+
if (auto *ConstructE = dyn_cast<CXXConstructExpr>(E)) {
88+
for (unsigned i = 0; i < ConstructE->getNumArgs(); ++i) {
89+
auto *Arg = ConstructE->getArg(i);
90+
if (auto *Lambda = dyn_cast<LambdaExpr>(Arg)) {
91+
if (VisitBody(Lambda->getBody()))
92+
return true;
93+
}
94+
}
95+
}
7096
return false;
7197
}
7298

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,3 +968,10 @@ namespace FunctionStart {
968968
static_assert(__builtin_function_start(a) == a, ""); // both-error {{not an integral constant expression}} \
969969
// both-note {{comparison of addresses of literals has unspecified value}}
970970
}
971+
972+
namespace BuiltinInImplicitCtor {
973+
constexpr struct {
974+
int a = __builtin_isnan(1.0);
975+
} Foo;
976+
static_assert(Foo.a == 0, "");
977+
}
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=webkit.RefCntblBaseVirtualDtor -verify %s
2+
3+
#include "mock-types.h"
4+
5+
namespace Detail {
6+
7+
template<typename Out, typename... In>
8+
class CallableWrapperBase {
9+
public:
10+
virtual ~CallableWrapperBase() { }
11+
virtual Out call(In...) = 0;
12+
};
13+
14+
template<typename, typename, typename...> class CallableWrapper;
15+
16+
template<typename CallableType, typename Out, typename... In>
17+
class CallableWrapper : public CallableWrapperBase<Out, In...> {
18+
public:
19+
explicit CallableWrapper(CallableType&& callable)
20+
: m_callable(WTFMove(callable)) { }
21+
CallableWrapper(const CallableWrapper&) = delete;
22+
CallableWrapper& operator=(const CallableWrapper&) = delete;
23+
Out call(In... in) final;
24+
private:
25+
CallableType m_callable;
26+
};
27+
28+
} // namespace Detail
29+
30+
template<typename> class Function;
31+
32+
template<typename Out, typename... In> Function<Out(In...)> adopt(Detail::CallableWrapperBase<Out, In...>*);
33+
34+
template <typename Out, typename... In>
35+
class Function<Out(In...)> {
36+
public:
37+
using Impl = Detail::CallableWrapperBase<Out, In...>;
38+
39+
Function() = default;
40+
41+
template<typename FunctionType>
42+
Function(FunctionType f);
43+
44+
Out operator()(In... in) const;
45+
explicit operator bool() const { return !!m_callableWrapper; }
46+
47+
private:
48+
enum AdoptTag { Adopt };
49+
Function(Impl* impl, AdoptTag)
50+
: m_callableWrapper(impl)
51+
{
52+
}
53+
54+
friend Function adopt<Out, In...>(Impl*);
55+
56+
Impl* m_callableWrapper;
57+
};
58+
59+
template<typename Out, typename... In> Function<Out(In...)> adopt(Detail::CallableWrapperBase<Out, In...>* impl)
60+
{
61+
return Function<Out(In...)>(impl, Function<Out(In...)>::Adopt);
62+
}
63+
64+
template<typename T, typename PtrTraits = RawPtrTraits<T>, typename RefDerefTraits = DefaultRefDerefTraits<T>> Ref<T, PtrTraits, RefDerefTraits> adoptRef(T&);
65+
66+
template<typename T, typename _PtrTraits, typename RefDerefTraits>
67+
inline Ref<T, _PtrTraits, RefDerefTraits> adoptRef(T& reference)
68+
{
69+
return Ref<T, _PtrTraits, RefDerefTraits>(reference);
70+
}
71+
72+
enum class DestructionThread : unsigned char { Any, Main, MainRunLoop };
73+
void ensureOnMainThread(Function<void()>&&); // Sync if called on main thread, async otherwise.
74+
void ensureOnMainRunLoop(Function<void()>&&); // Sync if called on main run loop, async otherwise.
75+
76+
class ThreadSafeRefCountedBase {
77+
public:
78+
ThreadSafeRefCountedBase() = default;
79+
80+
void ref() const
81+
{
82+
++m_refCount;
83+
}
84+
85+
bool hasOneRef() const
86+
{
87+
return refCount() == 1;
88+
}
89+
90+
unsigned refCount() const
91+
{
92+
return m_refCount;
93+
}
94+
95+
protected:
96+
bool derefBase() const
97+
{
98+
if (!--m_refCount) {
99+
m_refCount = 1;
100+
return true;
101+
}
102+
return false;
103+
}
104+
105+
private:
106+
mutable unsigned m_refCount { 1 };
107+
};
108+
109+
template<class T, DestructionThread destructionThread = DestructionThread::Any> class ThreadSafeRefCounted : public ThreadSafeRefCountedBase {
110+
public:
111+
void deref() const
112+
{
113+
if (!derefBase())
114+
return;
115+
116+
if constexpr (destructionThread == DestructionThread::Any) {
117+
delete static_cast<const T*>(this);
118+
} else if constexpr (destructionThread == DestructionThread::Main) {
119+
ensureOnMainThread([this] {
120+
delete static_cast<const T*>(this);
121+
});
122+
}
123+
}
124+
125+
protected:
126+
ThreadSafeRefCounted() = default;
127+
};
128+
129+
class FancyRefCountedClass final : public ThreadSafeRefCounted<FancyRefCountedClass, DestructionThread::Main> {
130+
public:
131+
static Ref<FancyRefCountedClass> create()
132+
{
133+
return adoptRef(*new FancyRefCountedClass());
134+
}
135+
136+
virtual ~FancyRefCountedClass();
137+
138+
private:
139+
FancyRefCountedClass();
140+
};
141+
142+
template<class T, DestructionThread destructionThread = DestructionThread::Any> class BadThreadSafeRefCounted : public ThreadSafeRefCountedBase {
143+
public:
144+
void deref() const
145+
{
146+
if (!derefBase())
147+
return;
148+
149+
[this] {
150+
delete static_cast<const T*>(this);
151+
};
152+
}
153+
154+
protected:
155+
BadThreadSafeRefCounted() = default;
156+
};
157+
158+
class FancyRefCountedClass2 final : public ThreadSafeRefCounted<FancyRefCountedClass, DestructionThread::Main> {
159+
// expected-warning@-1{{Class 'ThreadSafeRefCounted<FancyRefCountedClass, DestructionThread::Main>' is used as a base of class 'FancyRefCountedClass2' but doesn't have virtual destructor}}
160+
public:
161+
static Ref<FancyRefCountedClass2> create()
162+
{
163+
return adoptRef(*new FancyRefCountedClass2());
164+
}
165+
166+
virtual ~FancyRefCountedClass2();
167+
168+
private:
169+
FancyRefCountedClass2();
170+
};
171+
172+
template<class T, DestructionThread destructionThread = DestructionThread::Any> class NestedThreadSafeRefCounted : public ThreadSafeRefCountedBase {
173+
public:
174+
void deref() const
175+
{
176+
if (!derefBase())
177+
return;
178+
ensureOnMainRunLoop([&] {
179+
auto destroyThis = [&] {
180+
delete static_cast<const T*>(this);
181+
};
182+
destroyThis();
183+
});
184+
}
185+
186+
protected:
187+
NestedThreadSafeRefCounted() = default;
188+
};
189+
190+
class FancyRefCountedClass3 final : public NestedThreadSafeRefCounted<FancyRefCountedClass3, DestructionThread::Main> {
191+
public:
192+
static Ref<FancyRefCountedClass3> create()
193+
{
194+
return adoptRef(*new FancyRefCountedClass3());
195+
}
196+
197+
virtual ~FancyRefCountedClass3();
198+
199+
private:
200+
FancyRefCountedClass3();
201+
};
202+
203+
template<class T, DestructionThread destructionThread = DestructionThread::Any> class BadNestedThreadSafeRefCounted : public ThreadSafeRefCountedBase {
204+
public:
205+
void deref() const
206+
{
207+
if (!derefBase())
208+
return;
209+
ensureOnMainThread([&] {
210+
auto destroyThis = [&] {
211+
delete static_cast<const T*>(this);
212+
};
213+
});
214+
}
215+
216+
protected:
217+
BadNestedThreadSafeRefCounted() = default;
218+
};
219+
220+
class FancyRefCountedClass4 final : public BadNestedThreadSafeRefCounted<FancyRefCountedClass4, DestructionThread::Main> {
221+
// expected-warning@-1{{Class 'BadNestedThreadSafeRefCounted<FancyRefCountedClass4, DestructionThread::Main>' is used as a base of class 'FancyRefCountedClass4' but doesn't have virtual destructor}}
222+
public:
223+
static Ref<FancyRefCountedClass4> create()
224+
{
225+
return adoptRef(*new FancyRefCountedClass4());
226+
}
227+
228+
virtual ~FancyRefCountedClass4();
229+
230+
private:
231+
FancyRefCountedClass4();
232+
};

clang/test/Driver/mcmodel.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,4 @@
4343
// AARCH64-PIC-LARGE: error: invalid argument '-mcmodel=large' only allowed with '-fno-pic'
4444
// ERR-AARCH64_32: error: unsupported argument 'small' to option '-mcmodel=' for target 'aarch64_32-unknown-linux'
4545

46-
// ERR-LOONGARCH64-PLT-LARGE: error: invalid argument '-mcmodel=large' not allowed with '-fplt'
4746
// ERR-LOONGARCH64-PLT-EXTREME: error: invalid argument '-mcmodel=extreme' not allowed with '-fplt'

clang/test/Driver/riscv-mcmodel.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang --target=riscv32 -### -c -mcmodel=small %s 2>&1 | FileCheck --check-prefix=SMALL %s
2+
// RUN: %clang --target=riscv64 -### -c -mcmodel=small %s 2>&1 | FileCheck --check-prefix=SMALL %s
3+
4+
// RUN: %clang --target=riscv32 -### -c -mcmodel=medlow %s 2>&1 | FileCheck --check-prefix=SMALL %s
5+
// RUN: %clang --target=riscv64 -### -c -mcmodel=medlow %s 2>&1 | FileCheck --check-prefix=SMALL %s
6+
7+
// RUN: %clang --target=riscv32 -### -c -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=MEDIUM %s
8+
// RUN: %clang --target=riscv64 -### -c -mcmodel=medium %s 2>&1 | FileCheck --check-prefix=MEDIUM %s
9+
10+
// RUN: %clang --target=riscv32 -### -c -mcmodel=medany %s 2>&1 | FileCheck --check-prefix=MEDIUM %s
11+
// RUN: %clang --target=riscv64 -### -c -mcmodel=medany %s 2>&1 | FileCheck --check-prefix=MEDIUM %s
12+
13+
// SMALL: "-mcmodel=small"
14+
// MEDIUM: "-mcmodel=medium"

clang/test/SemaCXX/type-traits.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4147,6 +4147,24 @@ class Template {};
41474147
// Make sure we don't crash when instantiating a type
41484148
static_assert(!__is_trivially_equality_comparable(Template<Template<int>>));
41494149

4150+
4151+
struct S operator==(S, S);
4152+
4153+
template <class> struct basic_string_view {};
4154+
4155+
struct basic_string {
4156+
operator basic_string_view<int>() const;
4157+
};
4158+
4159+
template <class T>
4160+
const bool is_trivially_equality_comparable = __is_trivially_equality_comparable(T);
4161+
4162+
template <int = is_trivially_equality_comparable<basic_string> >
4163+
void find();
4164+
4165+
void func() { find(); }
4166+
4167+
41504168
namespace hidden_friend {
41514169

41524170
struct TriviallyEqualityComparable {

0 commit comments

Comments
 (0)