Skip to content

Commit c6cc629

Browse files
committed
Merge from 'main' to 'sycl-web' (61 commits)
CONFLICT (content): Merge conflict in llvm/unittests/Passes/CMakeLists.txt
2 parents 98acd59 + e281d10 commit c6cc629

File tree

153 files changed

+5261
-2721
lines changed

Some content is hidden

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

153 files changed

+5261
-2721
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ C++ Language Changes
7373
- Improved ``-O0`` code generation for calls to ``std::forward_like``. Similarly to
7474
``std::move, std::forward`` et al. it is now treated as a compiler builtin and implemented
7575
directly rather than instantiating the definition from the standard library.
76+
- Implemented `CWG2518 <https://wg21.link/CWG2518>`_ which allows ``static_assert(false)``
77+
to not be ill-formed when its condition is evaluated in the context of a template definition.
7678

7779
C++20 Feature Support
7880
^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ASTContext.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6695,8 +6695,28 @@ bool ASTContext::isSameEntity(const NamedDecl *X, const NamedDecl *Y) const {
66956695
return false;
66966696
}
66976697

6698-
if (!isSameConstraintExpr(FuncX->getTrailingRequiresClause(),
6699-
FuncY->getTrailingRequiresClause()))
6698+
// The trailing require clause of instantiated function may change during
6699+
// the semantic analysis. Trying to get the primary template function (if
6700+
// exists) to compare the primary trailing require clause.
6701+
auto TryToGetPrimaryTemplatedFunction =
6702+
[](const FunctionDecl *FD) -> const FunctionDecl * {
6703+
switch (FD->getTemplatedKind()) {
6704+
case FunctionDecl::TK_DependentNonTemplate:
6705+
return FD->getInstantiatedFromDecl();
6706+
case FunctionDecl::TK_FunctionTemplate:
6707+
return FD->getDescribedFunctionTemplate()->getTemplatedDecl();
6708+
case FunctionDecl::TK_MemberSpecialization:
6709+
return FD->getInstantiatedFromMemberFunction();
6710+
case FunctionDecl::TK_FunctionTemplateSpecialization:
6711+
return FD->getPrimaryTemplate()->getTemplatedDecl();
6712+
default:
6713+
return FD;
6714+
}
6715+
};
6716+
const FunctionDecl *PrimaryX = TryToGetPrimaryTemplatedFunction(FuncX);
6717+
const FunctionDecl *PrimaryY = TryToGetPrimaryTemplatedFunction(FuncY);
6718+
if (!isSameConstraintExpr(PrimaryX->getTrailingRequiresClause(),
6719+
PrimaryY->getTrailingRequiresClause()))
67006720
return false;
67016721

67026722
auto GetTypeAsWritten = [](const FunctionDecl *FD) {

clang/lib/AST/Interp/Disasm.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,7 @@ template <typename T> inline T ReadArg(Program &P, CodePtr &OpPC) {
3434
LLVM_DUMP_METHOD void Function::dump() const { dump(llvm::errs()); }
3535

3636
LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const {
37-
if (F) {
38-
if (const auto *MD = dyn_cast<CXXMethodDecl>(F))
39-
OS << MD->getParent()->getDeclName() << "::";
40-
OS << F->getDeclName() << " " << (const void *)this << ":\n";
41-
} else {
42-
OS << "<<expr>>\n";
43-
}
44-
37+
OS << getName() << " " << (const void *)this << "\n";
4538
OS << "frame size: " << getFrameSize() << "\n";
4639
OS << "arg size: " << getArgSize() << "\n";
4740
OS << "rvo: " << hasRVO() << "\n";

clang/lib/AST/Interp/Function.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,12 @@ class Function final {
9090

9191
/// Returns the name of the function decl this code
9292
/// was generated for.
93-
const std::string getName() const { return F->getNameInfo().getAsString(); }
93+
const std::string getName() const {
94+
if (!F)
95+
return "<<expr>>";
96+
97+
return F->getQualifiedNameAsString();
98+
}
9499

95100
/// Returns the location.
96101
SourceLocation getLoc() const { return Loc; }

clang/lib/AST/Interp/InterpState.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,14 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "InterpState.h"
10-
#include <limits>
11-
#include "Function.h"
1210
#include "InterpFrame.h"
1311
#include "InterpStack.h"
14-
#include "Opcode.h"
15-
#include "PrimType.h"
1612
#include "Program.h"
1713
#include "State.h"
1814

1915
using namespace clang;
2016
using namespace clang::interp;
2117

22-
using APSInt = llvm::APSInt;
23-
2418
InterpState::InterpState(State &Parent, Program &P, InterpStack &Stk,
2519
Context &Ctx, SourceMapper *M)
2620
: Parent(Parent), M(M), P(P), Stk(Stk), Ctx(Ctx), Current(nullptr),
@@ -41,11 +35,9 @@ InterpState::~InterpState() {
4135
}
4236

4337
Frame *InterpState::getCurrentFrame() {
44-
if (Current && Current->Caller) {
38+
if (Current && Current->Caller)
4539
return Current;
46-
} else {
47-
return Parent.getCurrentFrame();
48-
}
40+
return Parent.getCurrentFrame();
4941
}
5042

5143
bool InterpState::reportOverflow(const Expr *E, const llvm::APSInt &Value) {

clang/lib/Analysis/FlowSensitive/Transfer.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,15 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
732732
Env.setValue(Loc, *Val);
733733

734734
if (Type->isStructureOrClassType()) {
735-
for (auto It : llvm::zip(Type->getAsRecordDecl()->fields(), S->inits())) {
735+
// Unnamed bitfields are only used for padding and are not appearing in
736+
// `InitListExpr`'s inits. However, those fields do appear in RecordDecl's
737+
// field list, and we thus need to remove them before mapping inits to
738+
// fields to avoid mapping inits to the wrongs fields.
739+
std::vector<FieldDecl *> Fields;
740+
llvm::copy_if(
741+
Type->getAsRecordDecl()->fields(), std::back_inserter(Fields),
742+
[](const FieldDecl *Field) { return !Field->isUnnamedBitfield(); });
743+
for (auto It : llvm::zip(Fields, S->inits())) {
736744
const FieldDecl *Field = std::get<0>(It);
737745
assert(Field != nullptr);
738746

clang/lib/Sema/AnalysisBasedWarnings.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2509,7 +2509,7 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
25092509
// Check for throw out of non-throwing function.
25102510
if (!Diags.isIgnored(diag::warn_throw_in_noexcept_func, D->getBeginLoc()))
25112511
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
2512-
if (S.getLangOpts().CPlusPlus && isNoexcept(FD))
2512+
if (S.getLangOpts().CPlusPlus && !fscope->isCoroutine() && isNoexcept(FD))
25132513
checkThrowInNonThrowingFunc(S, FD, AC);
25142514

25152515
// Emit unsafe buffer usage warnings and fixits.

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16830,7 +16830,14 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
1683016830
FoldKind).isInvalid())
1683116831
Failed = true;
1683216832

16833-
if (!Failed && !Cond) {
16833+
// CWG2518
16834+
// [dcl.pre]/p10 If [...] the expression is evaluated in the context of a
16835+
// template definition, the declaration has no effect.
16836+
bool InTemplateDefinition =
16837+
getLangOpts().CPlusPlus && CurContext->isDependentContext();
16838+
16839+
if (!Failed && !Cond && !InTemplateDefinition) {
16840+
1683416841
SmallString<256> MsgBuffer;
1683516842
llvm::raw_svector_ostream Msg(MsgBuffer);
1683616843
if (AssertMessage) {
@@ -16861,7 +16868,8 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
1686116868
DiagnoseStaticAssertDetails(InnerCond);
1686216869
} else {
1686316870
Diag(StaticAssertLoc, diag::err_static_assert_failed)
16864-
<< !AssertMessage << Msg.str() << AssertExpr->getSourceRange();
16871+
<< !AssertMessage << Msg.str() << AssertExpr->getSourceRange();
16872+
PrintContextStack();
1686516873
}
1686616874
Failed = true;
1686716875
}

clang/test/CXX/drs/dr25xx.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify
22

3+
namespace dr2518 { // dr2518: 17 review
4+
5+
template <class T>
6+
void f(T t) {
7+
if constexpr (sizeof(T) != sizeof(int)) {
8+
static_assert(false, "must be int-sized"); // expected-error {{must be int-size}}
9+
}
10+
}
11+
12+
void g(char c) {
13+
f(0);
14+
f(c); // expected-note {{requested here}}
15+
}
16+
17+
template <typename Ty>
18+
struct S {
19+
static_assert(false); // expected-error {{static assertion failed}}
20+
};
21+
22+
template <>
23+
struct S<int> {};
24+
25+
template <>
26+
struct S<float> {};
27+
28+
int test_specialization() {
29+
S<int> s1;
30+
S<float> s2;
31+
S<double> s3; // expected-note {{in instantiation of template class 'dr2518::S<double>' requested here}}
32+
}
33+
34+
}
35+
36+
337
namespace dr2565 { // dr2565: 16 open
438
template<typename T>
539
concept C = requires (typename T::type x) {

clang/test/CodeGen/sanitizer-module-constructor.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ void h(void) { f(e); }
1818

1919
// CHECK: Running pass: {{.*}}SanitizerPass
2020
// CHECK-NOT: Running pass: LoopSimplifyPass on {{.*}}san.module_ctor
21-
// CHECK: Running analysis: DominatorTreeAnalysis on {{.*}}san.module_ctor
21+
// CHECK: Running analysis: TargetLibraryAnalysis on {{.*}}san.module_ctor

clang/test/Modules/pr60890.cppm

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// https://github.com/llvm/llvm-project/issues/60890
2+
//
3+
// RUN: rm -rf %t
4+
// RUN: mkdir -p %t
5+
// RUN: split-file %s %t
6+
//
7+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/a.cppm -o %t/a.pcm
8+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/b.cppm -fprebuilt-module-path=%t -o %t/b.pcm
9+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/c.cppm -fprebuilt-module-path=%t -o %t/c.pcm
10+
// RUN: %clang_cc1 -std=c++20 %t/d.cpp -fprebuilt-module-path=%t -S -emit-llvm -o -
11+
12+
//--- a.cppm
13+
export module a;
14+
15+
export template<typename T>
16+
struct a {
17+
friend void aa(a x) requires(true) {}
18+
void aaa() requires(true) {}
19+
};
20+
21+
export template struct a<double>;
22+
23+
export template<typename T>
24+
void foo(T) requires(true) {}
25+
26+
export template void foo<double>(double);
27+
28+
export template <typename T>
29+
class A {
30+
friend void foo<>(A);
31+
};
32+
33+
//--- b.cppm
34+
export module b;
35+
36+
import a;
37+
38+
void b() {
39+
a<int> _;
40+
a<double> __;
41+
}
42+
43+
//--- c.cppm
44+
export module c;
45+
46+
import a;
47+
48+
struct c {
49+
void f() const {
50+
a<int> _;
51+
aa(_);
52+
_.aaa();
53+
54+
a<double> __;
55+
aa(__);
56+
__.aaa();
57+
58+
foo<int>(5);
59+
foo<double>(3.0);
60+
foo(A<int>());
61+
}
62+
};
63+
64+
//--- d.cpp
65+
// expected-no-diagnostics
66+
import a;
67+
import b;
68+
import c;
69+
70+
void d() {
71+
a<int> _;
72+
aa(_);
73+
_.aaa();
74+
75+
a<double> __;
76+
aa(__);
77+
__.aaa();
78+
79+
foo<int>(5);
80+
foo<double>(3.0);
81+
foo(A<int>());
82+
}

clang/test/Modules/template-pack.cppm

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
// RUN: split-file %s %t
4+
//
5+
// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/a.cppm -o %t/a.pcm
6+
// RUN: %clang_cc1 -std=c++20 %t/b.cppm -fprebuilt-module-path=%t -fsyntax-only -verify
7+
8+
//--- foo.h
9+
10+
namespace std
11+
{
12+
template<class _Dom1>
13+
void operator &&(_Dom1 __v, _Dom1 __w)
14+
{
15+
return;
16+
}
17+
}
18+
19+
//--- bar.h
20+
namespace std
21+
{
22+
template<typename... _Types>
23+
struct _Traits
24+
{
25+
static constexpr bool _S_copy_ctor =
26+
(__is_trivial(_Types) && ...);
27+
};
28+
29+
template<typename... _Types>
30+
struct variant
31+
{
32+
void
33+
swap(variant& __rhs)
34+
noexcept((__is_trivial(_Types) && ...))
35+
{
36+
}
37+
};
38+
}
39+
40+
//--- a.cppm
41+
module;
42+
#include "foo.h"
43+
#include "bar.h"
44+
export module a;
45+
46+
//--- b.cppm
47+
// expected-no-diagnostics
48+
module;
49+
#include "bar.h"
50+
export module b;
51+
import a;

clang/test/SemaCXX/access-base-class.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,14 @@ struct flag {
9696
};
9797

9898
template <class T>
99-
struct trait : flag<sizeof(T)> {};
99+
struct trait : flag<sizeof(T)> {}; // expected-note 2{{here}}
100100

101-
template <class T, bool Inferred = trait<T>::value>
101+
template <class T, bool Inferred = trait<T>::value> // expected-note {{here}}
102102
struct a {};
103103

104104
template <class T>
105105
class b {
106-
a<T> x;
106+
a<T> x; // expected-note {{here}}
107107
using U = a<T>;
108108
};
109109

@@ -113,5 +113,5 @@ struct Impossible {
113113
};
114114

115115
// verify "no member named 'value'" bogus diagnostic is not emitted.
116-
trait<b<Impossible<0>>>::value;
116+
trait<b<Impossible<0>>>::value; // expected-note {{here}}
117117
} // namespace T8

clang/test/SemaCXX/coroutines.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1309,7 +1309,7 @@ struct DepTestType {
13091309
}
13101310
};
13111311

1312-
template struct DepTestType<int>; // expected-note {{requested here}}
1312+
template struct DepTestType<int>; // expected-note 2{{requested here}}
13131313
template CoroMemberTag DepTestType<int>::test_member_template(long, const char *) const &&;
13141314

13151315
template CoroMemberTag DepTestType<int>::test_static_template<void>(const char *volatile &, unsigned);

0 commit comments

Comments
 (0)