Skip to content

Commit dd0419e

Browse files
committed
Merge "merge main into amd-staging" into amd-staging
2 parents 0013394 + b40ab04 commit dd0419e

File tree

93 files changed

+4767
-424
lines changed

Some content is hidden

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

93 files changed

+4767
-424
lines changed

clang-tools-extra/clangd/CodeComplete.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,9 @@ bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
14091409
Clang->getPreprocessorOpts().SingleFileParseMode = CompletingInPreamble;
14101410
Clang->setCodeCompletionConsumer(Consumer.release());
14111411

1412+
if (Input.Preamble.RequiredModules)
1413+
Input.Preamble.RequiredModules->adjustHeaderSearchOptions(Clang->getHeaderSearchOpts());
1414+
14121415
SyntaxOnlyAction Action;
14131416
if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
14141417
log("BeginSourceFile() failed when running codeComplete for {0}",
@@ -2122,7 +2125,7 @@ clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const {
21222125
// When an is used, Sema is responsible for completing the main file,
21232126
// the index can provide results from the preamble.
21242127
// Tell Sema not to deserialize the preamble to look for results.
2125-
Result.LoadExternal = !Index;
2128+
Result.LoadExternal = ForceLoadPreamble || !Index;
21262129
Result.IncludeFixIts = IncludeFixIts;
21272130

21282131
return Result;

clang-tools-extra/clangd/CodeComplete.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ struct CodeCompleteOptions {
5252
/// For example, private members are usually inaccessible.
5353
bool IncludeIneligibleResults = false;
5454

55+
/// Force sema to load decls from preamble even if an index is provided.
56+
/// This is helpful for cases the index can't provide symbols, e.g. with
57+
/// experimental c++20 modules
58+
bool ForceLoadPreamble = false;
59+
5560
/// Combine overloads into a single completion item where possible.
5661
/// If none, the implementation may choose an appropriate behavior.
5762
/// (In practice, ClangdLSPServer enables bundling if the client claims

clang-tools-extra/clangd/tool/ClangdMain.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,9 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
919919
Opts.CodeComplete.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
920920
Opts.CodeComplete.RunParser = CodeCompletionParse;
921921
Opts.CodeComplete.RankingModel = RankingModel;
922+
// FIXME: If we're using C++20 modules, force the lookup process to load
923+
// external decls, since currently the index doesn't support C++20 modules.
924+
Opts.CodeComplete.ForceLoadPreamble = ExperimentalModulesSupport;
922925

923926
RealThreadsafeFS TFS;
924927
std::vector<std::unique_ptr<config::Provider>> ProviderStack;

clang-tools-extra/clangd/unittests/PrerequisiteModulesTest.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,86 @@ import A;
402402
EXPECT_TRUE(D.isFromASTFile());
403403
}
404404

405+
// An end to end test for code complete in modules
406+
TEST_F(PrerequisiteModulesTests, CodeCompleteTest) {
407+
MockDirectoryCompilationDatabase CDB(TestDir, FS);
408+
409+
CDB.addFile("A.cppm", R"cpp(
410+
export module A;
411+
export void printA();
412+
)cpp");
413+
414+
llvm::StringLiteral UserContents = R"cpp(
415+
import A;
416+
void func() {
417+
print^
418+
}
419+
)cpp";
420+
421+
CDB.addFile("Use.cpp", UserContents);
422+
Annotations Test(UserContents);
423+
424+
ModulesBuilder Builder(CDB);
425+
426+
ParseInputs Use = getInputs("Use.cpp", CDB);
427+
Use.ModulesManager = &Builder;
428+
429+
std::unique_ptr<CompilerInvocation> CI =
430+
buildCompilerInvocation(Use, DiagConsumer);
431+
EXPECT_TRUE(CI);
432+
433+
auto Preamble =
434+
buildPreamble(getFullPath("Use.cpp"), *CI, Use, /*InMemory=*/true,
435+
/*Callback=*/nullptr);
436+
EXPECT_TRUE(Preamble);
437+
EXPECT_TRUE(Preamble->RequiredModules);
438+
439+
auto Result = codeComplete(getFullPath("Use.cpp"), Test.point(),
440+
Preamble.get(), Use, {});
441+
EXPECT_FALSE(Result.Completions.empty());
442+
EXPECT_EQ(Result.Completions[0].Name, "printA");
443+
}
444+
445+
TEST_F(PrerequisiteModulesTests, SignatureHelpTest) {
446+
MockDirectoryCompilationDatabase CDB(TestDir, FS);
447+
448+
CDB.addFile("A.cppm", R"cpp(
449+
export module A;
450+
export void printA(int a);
451+
)cpp");
452+
453+
llvm::StringLiteral UserContents = R"cpp(
454+
import A;
455+
void func() {
456+
printA(^);
457+
}
458+
)cpp";
459+
460+
CDB.addFile("Use.cpp", UserContents);
461+
Annotations Test(UserContents);
462+
463+
ModulesBuilder Builder(CDB);
464+
465+
ParseInputs Use = getInputs("Use.cpp", CDB);
466+
Use.ModulesManager = &Builder;
467+
468+
std::unique_ptr<CompilerInvocation> CI =
469+
buildCompilerInvocation(Use, DiagConsumer);
470+
EXPECT_TRUE(CI);
471+
472+
auto Preamble =
473+
buildPreamble(getFullPath("Use.cpp"), *CI, Use, /*InMemory=*/true,
474+
/*Callback=*/nullptr);
475+
EXPECT_TRUE(Preamble);
476+
EXPECT_TRUE(Preamble->RequiredModules);
477+
478+
auto Result = signatureHelp(getFullPath("Use.cpp"), Test.point(),
479+
*Preamble.get(), Use, MarkupKind::PlainText);
480+
EXPECT_FALSE(Result.signatures.empty());
481+
EXPECT_EQ(Result.signatures[0].label, "printA(int a) -> void");
482+
EXPECT_EQ(Result.signatures[0].parameters[0].labelString, "int a");
483+
}
484+
405485
} // namespace
406486
} // namespace clang::clangd
407487

clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/ADT/SmallVector.h"
2222
#include "llvm/ADT/StringRef.h"
2323
#include <string>
24+
#include <utility>
2425

2526
namespace clang {
2627
class SourceLocation;
@@ -62,7 +63,8 @@ void walkUsed(llvm::ArrayRef<Decl *> ASTRoots,
6263

6364
struct AnalysisResults {
6465
std::vector<const Include *> Unused;
65-
std::vector<std::string> Missing; // Spellings, like "<vector>"
66+
// Spellings, like "<vector>" paired with the Header that generated it.
67+
std::vector<std::pair<std::string, Header>> Missing;
6668
};
6769

6870
/// Determine which headers should be inserted or removed from the main file.

clang-tools-extra/include-cleaner/lib/Analysis.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
#include "llvm/ADT/STLExtras.h"
2727
#include "llvm/ADT/STLFunctionalExtras.h"
2828
#include "llvm/ADT/SmallVector.h"
29+
#include "llvm/ADT/StringMap.h"
2930
#include "llvm/ADT/StringRef.h"
30-
#include "llvm/ADT/StringSet.h"
3131
#include "llvm/Support/Error.h"
3232
#include "llvm/Support/ErrorHandling.h"
3333
#include <cassert>
@@ -84,7 +84,7 @@ analyze(llvm::ArrayRef<Decl *> ASTRoots,
8484
auto &SM = PP.getSourceManager();
8585
const auto MainFile = *SM.getFileEntryRefForID(SM.getMainFileID());
8686
llvm::DenseSet<const Include *> Used;
87-
llvm::StringSet<> Missing;
87+
llvm::StringMap<Header> Missing;
8888
if (!HeaderFilter)
8989
HeaderFilter = [](llvm::StringRef) { return false; };
9090
OptionalDirectoryEntryRef ResourceDir =
@@ -119,7 +119,7 @@ analyze(llvm::ArrayRef<Decl *> ASTRoots,
119119
Satisfied = true;
120120
}
121121
if (!Satisfied)
122-
Missing.insert(std::move(Spelling));
122+
Missing.try_emplace(std::move(Spelling), Providers.front());
123123
});
124124

125125
AnalysisResults Results;
@@ -144,8 +144,8 @@ analyze(llvm::ArrayRef<Decl *> ASTRoots,
144144
}
145145
Results.Unused.push_back(&I);
146146
}
147-
for (llvm::StringRef S : Missing.keys())
148-
Results.Missing.push_back(S.str());
147+
for (auto &E : Missing)
148+
Results.Missing.emplace_back(E.first().str(), E.second);
149149
llvm::sort(Results.Missing);
150150
return Results;
151151
}
@@ -158,9 +158,9 @@ std::string fixIncludes(const AnalysisResults &Results,
158158
// Encode insertions/deletions in the magic way clang-format understands.
159159
for (const Include *I : Results.Unused)
160160
cantFail(R.add(tooling::Replacement(FileName, UINT_MAX, 1, I->quote())));
161-
for (llvm::StringRef Spelled : Results.Missing)
162-
cantFail(R.add(tooling::Replacement(FileName, UINT_MAX, 0,
163-
("#include " + Spelled).str())));
161+
for (auto &[Spelled, _] : Results.Missing)
162+
cantFail(R.add(
163+
tooling::Replacement(FileName, UINT_MAX, 0, "#include " + Spelled)));
164164
// "cleanup" actually turns the UINT_MAX replacements into concrete edits.
165165
auto Positioned = cantFail(format::cleanupAroundReplacements(Code, R, Style));
166166
return cantFail(tooling::applyAllReplacements(Code, Positioned));

clang-tools-extra/include-cleaner/tool/IncludeCleaner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ class Action : public clang::ASTFrontendAction {
192192
case PrintStyle::Changes:
193193
for (const Include *I : Results.Unused)
194194
llvm::outs() << "- " << I->quote() << " @Line:" << I->Line << "\n";
195-
for (const auto &I : Results.Missing)
195+
for (const auto &[I, _] : Results.Missing)
196196
llvm::outs() << "+ " << I << "\n";
197197
break;
198198
case PrintStyle::Final:

clang-tools-extra/include-cleaner/unittests/AnalysisTest.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "llvm/ADT/IntrusiveRefCntPtr.h"
2626
#include "llvm/ADT/SmallVector.h"
2727
#include "llvm/ADT/StringRef.h"
28+
#include "llvm/Support/Error.h"
2829
#include "llvm/Support/MemoryBuffer.h"
2930
#include "llvm/Support/ScopedPrinter.h"
3031
#include "llvm/Support/VirtualFileSystem.h"
@@ -39,6 +40,7 @@
3940

4041
namespace clang::include_cleaner {
4142
namespace {
43+
using testing::_;
4244
using testing::AllOf;
4345
using testing::Contains;
4446
using testing::ElementsAre;
@@ -262,10 +264,12 @@ int x = a + c;
262264
auto Results =
263265
analyze(std::vector<Decl *>{Decls.begin(), Decls.end()},
264266
PP.MacroReferences, PP.Includes, &PI, AST.preprocessor());
267+
auto CHeader = llvm::cantFail(
268+
AST.context().getSourceManager().getFileManager().getFileRef("c.h"));
265269

266270
const Include *B = PP.Includes.atLine(3);
267271
ASSERT_EQ(B->Spelled, "b.h");
268-
EXPECT_THAT(Results.Missing, ElementsAre("\"c.h\""));
272+
EXPECT_THAT(Results.Missing, ElementsAre(Pair("\"c.h\"", Header(CHeader))));
269273
EXPECT_THAT(Results.Unused, ElementsAre(B));
270274
}
271275

@@ -370,7 +374,7 @@ TEST_F(AnalyzeTest, SpellingIncludesWithSymlinks) {
370374
auto Results = analyze(DeclsInTU, {}, PP.Includes, &PI, AST.preprocessor());
371375
// Check that we're spelling header using the symlink, and not underlying
372376
// path.
373-
EXPECT_THAT(Results.Missing, testing::ElementsAre("\"inner.h\""));
377+
EXPECT_THAT(Results.Missing, testing::ElementsAre(Pair("\"inner.h\"", _)));
374378
// header.h should be unused.
375379
EXPECT_THAT(Results.Unused, Not(testing::IsEmpty()));
376380

@@ -379,7 +383,7 @@ TEST_F(AnalyzeTest, SpellingIncludesWithSymlinks) {
379383
auto HeaderFilter = [](llvm::StringRef Path) { return Path == "inner.h"; };
380384
Results = analyze(DeclsInTU, {}, PP.Includes, &PI, AST.preprocessor(),
381385
HeaderFilter);
382-
EXPECT_THAT(Results.Missing, testing::ElementsAre("\"inner.h\""));
386+
EXPECT_THAT(Results.Missing, testing::ElementsAre(Pair("\"inner.h\"", _)));
383387
// header.h should be unused.
384388
EXPECT_THAT(Results.Unused, Not(testing::IsEmpty()));
385389
}
@@ -389,7 +393,7 @@ TEST_F(AnalyzeTest, SpellingIncludesWithSymlinks) {
389393
HeaderFilter);
390394
// header.h should be ignored now.
391395
EXPECT_THAT(Results.Unused, Not(testing::IsEmpty()));
392-
EXPECT_THAT(Results.Missing, testing::ElementsAre("\"inner.h\""));
396+
EXPECT_THAT(Results.Missing, testing::ElementsAre(Pair("\"inner.h\"", _)));
393397
}
394398
}
395399

@@ -414,9 +418,9 @@ TEST(FixIncludes, Basic) {
414418
Inc.add(I);
415419

416420
AnalysisResults Results;
417-
Results.Missing.push_back("\"aa.h\"");
418-
Results.Missing.push_back("\"ab.h\"");
419-
Results.Missing.push_back("<e.h>");
421+
Results.Missing.emplace_back("\"aa.h\"", Header(""));
422+
Results.Missing.emplace_back("\"ab.h\"", Header(""));
423+
Results.Missing.emplace_back("<e.h>", Header(""));
420424
Results.Unused.push_back(Inc.atLine(3));
421425
Results.Unused.push_back(Inc.atLine(4));
422426

@@ -429,7 +433,7 @@ R"cpp(#include "d.h"
429433
)cpp");
430434

431435
Results = {};
432-
Results.Missing.push_back("\"d.h\"");
436+
Results.Missing.emplace_back("\"d.h\"", Header(""));
433437
Code = R"cpp(#include "a.h")cpp";
434438
EXPECT_EQ(fixIncludes(Results, "d.cc", Code, format::getLLVMStyle()),
435439
R"cpp(#include "d.h"

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ Bug Fixes to C++ Support
472472
- Fixed an assertion failure in debug mode, and potential crashes in release mode, when
473473
diagnosing a failed cast caused indirectly by a failed implicit conversion to the type of the constructor parameter.
474474
- Fixed an assertion failure by adjusting integral to boolean vector conversions (#GH108326)
475+
- Mangle friend function templates with a constraint that depends on a template parameter from an enclosing template as members of the enclosing class. (#GH110247)
475476

476477
Bug Fixes to AST Handling
477478
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/docs/analyzer/checkers.rst

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,6 +1544,49 @@ Warn on ``mmap()`` calls with both writable and executable access.
15441544
// code
15451545
}
15461546
1547+
.. _security-PointerSub:
1548+
1549+
security.PointerSub (C)
1550+
"""""""""""""""""""""""
1551+
Check for pointer subtractions on two pointers pointing to different memory
1552+
chunks. According to the C standard §6.5.6 only subtraction of pointers that
1553+
point into (or one past the end) the same array object is valid (for this
1554+
purpose non-array variables are like arrays of size 1). This checker only
1555+
searches for different memory objects at subtraction, but does not check if the
1556+
array index is correct. Furthermore, only cases are reported where
1557+
stack-allocated objects are involved (no warnings on pointers to memory
1558+
allocated by `malloc`).
1559+
1560+
.. code-block:: c
1561+
1562+
void test() {
1563+
int a, b, c[10], d[10];
1564+
int x = &c[3] - &c[1];
1565+
x = &d[4] - &c[1]; // warn: 'c' and 'd' are different arrays
1566+
x = (&a + 1) - &a;
1567+
x = &b - &a; // warn: 'a' and 'b' are different variables
1568+
}
1569+
1570+
struct S {
1571+
int x[10];
1572+
int y[10];
1573+
};
1574+
1575+
void test1() {
1576+
struct S a[10];
1577+
struct S b;
1578+
int d = &a[4] - &a[6];
1579+
d = &a[0].x[3] - &a[0].x[1];
1580+
d = a[0].y - a[0].x; // warn: 'S.b' and 'S.a' are different objects
1581+
d = (char *)&b.y - (char *)&b.x; // warn: different members of the same object
1582+
d = (char *)&b.y - (char *)&b; // warn: object of type S is not the same array as a member of it
1583+
}
1584+
1585+
There may be existing applications that use code like above for calculating
1586+
offsets of members in a structure, using pointer subtractions. This is still
1587+
undefined behavior according to the standard and code like this can be replaced
1588+
with the `offsetof` macro.
1589+
15471590
.. _security-putenv-stack-array:
15481591
15491592
security.PutenvStackArray (C)
@@ -2761,49 +2804,6 @@ Check for pointer arithmetic on locations other than array elements.
27612804
p = &x + 1; // warn
27622805
}
27632806
2764-
.. _alpha-core-PointerSub:
2765-
2766-
alpha.core.PointerSub (C)
2767-
"""""""""""""""""""""""""
2768-
Check for pointer subtractions on two pointers pointing to different memory
2769-
chunks. According to the C standard §6.5.6 only subtraction of pointers that
2770-
point into (or one past the end) the same array object is valid (for this
2771-
purpose non-array variables are like arrays of size 1). This checker only
2772-
searches for different memory objects at subtraction, but does not check if the
2773-
array index is correct. Furthermore, only cases are reported where
2774-
stack-allocated objects are involved (no warnings on pointers to memory
2775-
allocated by `malloc`).
2776-
2777-
.. code-block:: c
2778-
2779-
void test() {
2780-
int a, b, c[10], d[10];
2781-
int x = &c[3] - &c[1];
2782-
x = &d[4] - &c[1]; // warn: 'c' and 'd' are different arrays
2783-
x = (&a + 1) - &a;
2784-
x = &b - &a; // warn: 'a' and 'b' are different variables
2785-
}
2786-
2787-
struct S {
2788-
int x[10];
2789-
int y[10];
2790-
};
2791-
2792-
void test1() {
2793-
struct S a[10];
2794-
struct S b;
2795-
int d = &a[4] - &a[6];
2796-
d = &a[0].x[3] - &a[0].x[1];
2797-
d = a[0].y - a[0].x; // warn: 'S.b' and 'S.a' are different objects
2798-
d = (char *)&b.y - (char *)&b.x; // warn: different members of the same object
2799-
d = (char *)&b.y - (char *)&b; // warn: object of type S is not the same array as a member of it
2800-
}
2801-
2802-
There may be existing applications that use code like above for calculating
2803-
offsets of members in a structure, using pointer subtractions. This is still
2804-
undefined behavior according to the standard and code like this can be replaced
2805-
with the `offsetof` macro.
2806-
28072807
.. _alpha-core-StackAddressAsyncEscape:
28082808
28092809
alpha.core.StackAddressAsyncEscape (ObjC)

0 commit comments

Comments
 (0)