Skip to content

Commit 508b0f2

Browse files
committed
Merge from 'main' to 'sycl-web' (#21)
CONFLICT (content): Merge conflict in clang/lib/Sema/SemaDecl.cpp
2 parents cd7f8da + 35c9baa commit 508b0f2

File tree

153 files changed

+4074
-1841
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

+4074
-1841
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ class Checker {
123123
std::vector<std::string> CC1Args;
124124
Inputs.CompileCommand = Cmd;
125125
Inputs.TFS = &TFS;
126+
Inputs.ClangTidyProvider = Opts.ClangTidyProvider;
126127
if (Contents.hasValue()) {
127128
Inputs.Contents = *Contents;
128129
log("Imaginary source file contents:\n{0}", Inputs.Contents);

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

Lines changed: 17 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -169,48 +169,6 @@ TEST_F(OverlayCDBTest, Adjustments) {
169169
"-DFallback", "-DAdjust_baz.cc"));
170170
}
171171

172-
// Allows placement of files for tests and cleans them up after.
173-
// FIXME: GlobalCompilationDatabase is mostly VFS-clean now, switch to MockFS?
174-
class ScratchFS {
175-
llvm::SmallString<128> Root;
176-
177-
public:
178-
ScratchFS() {
179-
EXPECT_FALSE(llvm::sys::fs::createUniqueDirectory("clangd-cdb-test", Root))
180-
<< "Failed to create unique directory";
181-
}
182-
183-
~ScratchFS() {
184-
EXPECT_FALSE(llvm::sys::fs::remove_directories(Root))
185-
<< "Failed to cleanup " << Root;
186-
}
187-
188-
llvm::StringRef root() const { return Root; }
189-
190-
void write(PathRef RelativePath, llvm::StringRef Contents) {
191-
std::string AbsPath = path(RelativePath);
192-
EXPECT_FALSE(llvm::sys::fs::create_directories(
193-
llvm::sys::path::parent_path(AbsPath)))
194-
<< "Failed to create directories for: " << AbsPath;
195-
196-
std::error_code EC;
197-
llvm::raw_fd_ostream OS(AbsPath, EC);
198-
EXPECT_FALSE(EC) << "Failed to open " << AbsPath << " for writing";
199-
OS << llvm::formatv(Contents.data(),
200-
llvm::sys::path::convert_to_slash(Root));
201-
OS.close();
202-
203-
EXPECT_FALSE(OS.has_error());
204-
}
205-
206-
std::string path(PathRef RelativePath) const {
207-
llvm::SmallString<128> AbsPath(Root);
208-
llvm::sys::path::append(AbsPath, RelativePath);
209-
llvm::sys::path::native(AbsPath);
210-
return AbsPath.str().str();
211-
}
212-
};
213-
214172
TEST(GlobalCompilationDatabaseTest, DiscoveryWithNestedCDBs) {
215173
const char *const CDBOuter =
216174
R"cdb(
@@ -242,59 +200,59 @@ TEST(GlobalCompilationDatabaseTest, DiscoveryWithNestedCDBs) {
242200
}
243201
]
244202
)cdb";
245-
ScratchFS FS;
246-
RealThreadsafeFS TFS;
247-
FS.write("compile_commands.json", CDBOuter);
248-
FS.write("build/compile_commands.json", CDBInner);
203+
MockFS FS;
204+
FS.Files[testPath("compile_commands.json")] =
205+
llvm::formatv(CDBOuter, llvm::sys::path::convert_to_slash(testRoot()));
206+
FS.Files[testPath("build/compile_commands.json")] =
207+
llvm::formatv(CDBInner, llvm::sys::path::convert_to_slash(testRoot()));
249208

250209
// Note that gen2.cc goes missing with our following model, not sure this
251210
// happens in practice though.
252211
{
253-
DirectoryBasedGlobalCompilationDatabase DB(TFS);
212+
DirectoryBasedGlobalCompilationDatabase DB(FS);
254213
std::vector<std::string> DiscoveredFiles;
255214
auto Sub =
256215
DB.watch([&DiscoveredFiles](const std::vector<std::string> Changes) {
257216
DiscoveredFiles = Changes;
258217
});
259218

260-
DB.getCompileCommand(FS.path("build/../a.cc"));
219+
DB.getCompileCommand(testPath("build/../a.cc"));
261220
EXPECT_THAT(DiscoveredFiles, UnorderedElementsAre(AllOf(
262221
EndsWith("a.cc"), Not(HasSubstr("..")))));
263222
DiscoveredFiles.clear();
264223

265-
DB.getCompileCommand(FS.path("build/gen.cc"));
224+
DB.getCompileCommand(testPath("build/gen.cc"));
266225
EXPECT_THAT(DiscoveredFiles, UnorderedElementsAre(EndsWith("gen.cc")));
267226
}
268227

269228
// With a custom compile commands dir.
270229
{
271-
DirectoryBasedGlobalCompilationDatabase::Options Opts(TFS);
272-
Opts.CompileCommandsDir = FS.root().str();
230+
DirectoryBasedGlobalCompilationDatabase::Options Opts(FS);
231+
Opts.CompileCommandsDir = testRoot();
273232
DirectoryBasedGlobalCompilationDatabase DB(Opts);
274233
std::vector<std::string> DiscoveredFiles;
275234
auto Sub =
276235
DB.watch([&DiscoveredFiles](const std::vector<std::string> Changes) {
277236
DiscoveredFiles = Changes;
278237
});
279238

280-
DB.getCompileCommand(FS.path("a.cc"));
239+
DB.getCompileCommand(testPath("a.cc"));
281240
EXPECT_THAT(DiscoveredFiles,
282241
UnorderedElementsAre(EndsWith("a.cc"), EndsWith("gen.cc"),
283242
EndsWith("gen2.cc")));
284243
DiscoveredFiles.clear();
285244

286-
DB.getCompileCommand(FS.path("build/gen.cc"));
245+
DB.getCompileCommand(testPath("build/gen.cc"));
287246
EXPECT_THAT(DiscoveredFiles, IsEmpty());
288247
}
289248
}
290249

291250
TEST(GlobalCompilationDatabaseTest, BuildDir) {
292-
ScratchFS FS;
293-
RealThreadsafeFS TFS;
251+
MockFS FS;
294252
auto Command = [&](llvm::StringRef Relative) {
295-
DirectoryBasedGlobalCompilationDatabase::Options Opts(TFS);
253+
DirectoryBasedGlobalCompilationDatabase::Options Opts(FS);
296254
return DirectoryBasedGlobalCompilationDatabase(Opts)
297-
.getCompileCommand(FS.path(Relative))
255+
.getCompileCommand(testPath(Relative))
298256
.getValueOr(tooling::CompileCommand())
299257
.CommandLine;
300258
};
@@ -314,7 +272,8 @@ TEST(GlobalCompilationDatabaseTest, BuildDir) {
314272
}
315273
]
316274
)cdb";
317-
FS.write("x/build/compile_commands.json", CDB);
275+
FS.Files[testPath("x/build/compile_commands.json")] =
276+
llvm::formatv(CDB, llvm::sys::path::convert_to_slash(testRoot()));
318277
EXPECT_THAT(Command("x/foo.cc"), Contains("-DXYZZY"));
319278
EXPECT_THAT(Command("bar.cc"), IsEmpty())
320279
<< "x/build/compile_flags.json only applicable to x/";

clang/docs/ClangOffloadBundler.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ The layout of a bundled code object is defined by the following table:
4444
Field Type Size in Bytes Description
4545
=================================== ======= ================ ===============================
4646
Magic String string 24 ``__CLANG_OFFLOAD_BUNDLE__``
47-
Number Of Code Objects integer 8 Number od bundled code objects.
47+
Number Of Bundle Entries integer 8 Number of bundle entries.
4848
1st Bundle Entry Code Object Offset integer 8 Byte offset from beginning of
4949
bundled code object to 1st code
5050
object.
@@ -208,4 +208,4 @@ Target specific information is available for the following:
208208
features <https://llvm.org/docs/AMDGPUUsage.html#amdgpu-target-features>`_
209209
supported.
210210

211-
Most other targets do not support target IDs.
211+
Most other targets do not support target IDs.

clang/include/clang/Basic/Attr.td

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4263,3 +4263,19 @@ def Builtin : InheritableAttr {
42634263
let SemaHandler = 0;
42644264
let Documentation = [Undocumented];
42654265
}
4266+
4267+
def EnforceTCB : InheritableAttr {
4268+
let Spellings = [Clang<"enforce_tcb">];
4269+
let Subjects = SubjectList<[Function]>;
4270+
let Args = [StringArgument<"TCBName">];
4271+
let Documentation = [EnforceTCBDocs];
4272+
bit InheritEvenIfAlreadyPresent = 1;
4273+
}
4274+
4275+
def EnforceTCBLeaf : InheritableAttr {
4276+
let Spellings = [Clang<"enforce_tcb_leaf">];
4277+
let Subjects = SubjectList<[Function]>;
4278+
let Args = [StringArgument<"TCBName">];
4279+
let Documentation = [EnforceTCBLeafDocs];
4280+
bit InheritEvenIfAlreadyPresent = 1;
4281+
}

clang/include/clang/Basic/AttrDocs.td

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6411,3 +6411,28 @@ Attribute docs`_, and `the GCC Inline docs`_.
64116411
}];
64126412
let Heading = "always_inline, __force_inline";
64136413
}
6414+
6415+
def EnforceTCBDocs : Documentation {
6416+
let Category = DocCatFunction;
6417+
let Content = [{
6418+
The ``enforce_tcb`` attribute can be placed on functions to enforce that a
6419+
trusted compute base (TCB) does not call out of the TCB. This generates a
6420+
warning every time a function not marked with an ``enforce_tcb`` attribute is
6421+
called from a function with the ``enforce_tcb`` attribute. A function may be a
6422+
part of multiple TCBs. Invocations through function pointers are currently
6423+
not checked. Builtins are considered to a part of every TCB.
6424+
6425+
- ``enforce_tcb(Name)`` indicates that this function is a part of the TCB named ``Name``
6426+
}];
6427+
}
6428+
6429+
def EnforceTCBLeafDocs : Documentation {
6430+
let Category = DocCatFunction;
6431+
let Content = [{
6432+
The ``enforce_tcb_leaf`` attribute satisfies the requirement enforced by
6433+
``enforce_tcb`` for the marked function to be in the named TCB but does not
6434+
continue to check the functions called from within the leaf function.
6435+
6436+
- ``enforce_tcb_leaf(Name)`` indicates that this function is a part of the TCB named ``Name``
6437+
}];
6438+
}

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11256,4 +11256,11 @@ def err_probability_not_constant_float : Error<
1125611256
def err_probability_out_of_range : Error<
1125711257
"probability argument to __builtin_expect_with_probability is outside the "
1125811258
"range [0.0, 1.0]">;
11259+
11260+
// TCB warnings
11261+
def err_tcb_conflicting_attributes : Error<
11262+
"attributes '%0(\"%2\")' and '%1(\"%2\")' are mutually exclusive">;
11263+
def warn_tcb_enforcement_violation : Warning<
11264+
"calling %0 is a violation of trusted computing base '%1'">,
11265+
InGroup<DiagGroup<"tcb-enforcement">>;
1125911266
} // end of sema component.

clang/include/clang/Sema/Sema.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3365,6 +3365,9 @@ class Sema final {
33653365
Decl *D, const WebAssemblyImportNameAttr &AL);
33663366
WebAssemblyImportModuleAttr *mergeImportModuleAttr(
33673367
Decl *D, const WebAssemblyImportModuleAttr &AL);
3368+
EnforceTCBAttr *mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL);
3369+
EnforceTCBLeafAttr *mergeEnforceTCBLeafAttr(Decl *D,
3370+
const EnforceTCBLeafAttr &AL);
33683371

33693372
SYCLIntelLoopFuseAttr *
33703373
mergeSYCLIntelLoopFuseAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E);
@@ -12625,6 +12628,8 @@ class Sema final {
1262512628
/// attempts to add itself into the container
1262612629
void CheckObjCCircularContainer(ObjCMessageExpr *Message);
1262712630

12631+
void CheckTCBEnforcement(const CallExpr *TheCall, const FunctionDecl *Callee);
12632+
1262812633
void AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE);
1262912634
void AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc,
1263012635
bool DeleteWasArrayForm);

clang/lib/Sema/SemaChecking.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#include "llvm/ADT/SmallString.h"
7676
#include "llvm/ADT/SmallVector.h"
7777
#include "llvm/ADT/StringRef.h"
78+
#include "llvm/ADT/StringSet.h"
7879
#include "llvm/ADT/StringSwitch.h"
7980
#include "llvm/ADT/Triple.h"
8081
#include "llvm/Support/AtomicOrdering.h"
@@ -4708,6 +4709,8 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
47084709
if (!FnInfo)
47094710
return false;
47104711

4712+
CheckTCBEnforcement(TheCall, FDecl);
4713+
47114714
CheckAbsoluteValueFunction(TheCall, FDecl);
47124715
CheckMaxUnsignedZero(TheCall, FDecl);
47134716

@@ -16198,3 +16201,38 @@ ExprResult Sema::SemaBuiltinMatrixColumnMajorStore(CallExpr *TheCall,
1619816201

1619916202
return CallResult;
1620016203
}
16204+
16205+
/// \brief Enforce the bounds of a TCB
16206+
/// CheckTCBEnforcement - Enforces that every function in a named TCB only
16207+
/// directly calls other functions in the same TCB as marked by the enforce_tcb
16208+
/// and enforce_tcb_leaf attributes.
16209+
void Sema::CheckTCBEnforcement(const CallExpr *TheCall,
16210+
const FunctionDecl *Callee) {
16211+
const FunctionDecl *Caller = getCurFunctionDecl();
16212+
16213+
// Calls to builtins are not enforced.
16214+
if (!Caller || !Caller->hasAttr<EnforceTCBAttr>() ||
16215+
Callee->getBuiltinID() != 0)
16216+
return;
16217+
16218+
// Search through the enforce_tcb and enforce_tcb_leaf attributes to find
16219+
// all TCBs the callee is a part of.
16220+
llvm::StringSet<> CalleeTCBs;
16221+
for_each(Callee->specific_attrs<EnforceTCBAttr>(),
16222+
[&](const auto *A) { CalleeTCBs.insert(A->getTCBName()); });
16223+
for_each(Callee->specific_attrs<EnforceTCBLeafAttr>(),
16224+
[&](const auto *A) { CalleeTCBs.insert(A->getTCBName()); });
16225+
16226+
// Go through the TCBs the caller is a part of and emit warnings if Caller
16227+
// is in a TCB that the Callee is not.
16228+
for_each(
16229+
Caller->specific_attrs<EnforceTCBAttr>(),
16230+
[&](const auto *A) {
16231+
StringRef CallerTCB = A->getTCBName();
16232+
if (CalleeTCBs.count(CallerTCB) == 0) {
16233+
this->Diag(TheCall->getExprLoc(),
16234+
diag::warn_tcb_enforcement_violation) << Callee
16235+
<< CallerTCB;
16236+
}
16237+
});
16238+
}

clang/lib/Sema/SemaDecl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2614,6 +2614,10 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
26142614
NewAttr = S.mergeImportNameAttr(D, *INA);
26152615
else if (const auto *LFA = dyn_cast<SYCLIntelLoopFuseAttr>(Attr))
26162616
NewAttr = S.mergeSYCLIntelLoopFuseAttr(D, *LFA, LFA->getValue());
2617+
else if (const auto *TCBA = dyn_cast<EnforceTCBAttr>(Attr))
2618+
NewAttr = S.mergeEnforceTCBAttr(D, *TCBA);
2619+
else if (const auto *TCBLA = dyn_cast<EnforceTCBLeafAttr>(Attr))
2620+
NewAttr = S.mergeEnforceTCBLeafAttr(D, *TCBLA);
26172621
else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))
26182622
NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));
26192623

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8295,6 +8295,75 @@ static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
82958295
D->addAttr(::new (S.Context) CFGuardAttr(S.Context, AL, Arg));
82968296
}
82978297

8298+
8299+
template <typename AttrTy>
8300+
static const AttrTy *findEnforceTCBAttrByName(Decl *D, StringRef Name) {
8301+
auto Attrs = D->specific_attrs<AttrTy>();
8302+
auto I = llvm::find_if(Attrs,
8303+
[Name](const AttrTy *A) {
8304+
return A->getTCBName() == Name;
8305+
});
8306+
return I == Attrs.end() ? nullptr : *I;
8307+
}
8308+
8309+
template <typename AttrTy, typename ConflictingAttrTy>
8310+
static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
8311+
StringRef Argument;
8312+
if (!S.checkStringLiteralArgumentAttr(AL, 0, Argument))
8313+
return;
8314+
8315+
// A function cannot be have both regular and leaf membership in the same TCB.
8316+
if (const ConflictingAttrTy *ConflictingAttr =
8317+
findEnforceTCBAttrByName<ConflictingAttrTy>(D, Argument)) {
8318+
// We could attach a note to the other attribute but in this case
8319+
// there's no need given how the two are very close to each other.
8320+
S.Diag(AL.getLoc(), diag::err_tcb_conflicting_attributes)
8321+
<< AL.getAttrName()->getName() << ConflictingAttr->getAttrName()->getName()
8322+
<< Argument;
8323+
8324+
// Error recovery: drop the non-leaf attribute so that to suppress
8325+
// all future warnings caused by erroneous attributes. The leaf attribute
8326+
// needs to be kept because it can only suppresses warnings, not cause them.
8327+
D->dropAttr<EnforceTCBAttr>();
8328+
return;
8329+
}
8330+
8331+
D->addAttr(AttrTy::Create(S.Context, Argument, AL));
8332+
}
8333+
8334+
template <typename AttrTy, typename ConflictingAttrTy>
8335+
static AttrTy *mergeEnforceTCBAttrImpl(Sema &S, Decl *D, const AttrTy &AL) {
8336+
// Check if the new redeclaration has different leaf-ness in the same TCB.
8337+
StringRef TCBName = AL.getTCBName();
8338+
if (const ConflictingAttrTy *ConflictingAttr =
8339+
findEnforceTCBAttrByName<ConflictingAttrTy>(D, TCBName)) {
8340+
S.Diag(ConflictingAttr->getLoc(), diag::err_tcb_conflicting_attributes)
8341+
<< ConflictingAttr->getAttrName()->getName()
8342+
<< AL.getAttrName()->getName() << TCBName;
8343+
8344+
// Add a note so that the user could easily find the conflicting attribute.
8345+
S.Diag(AL.getLoc(), diag::note_conflicting_attribute);
8346+
8347+
// More error recovery.
8348+
D->dropAttr<EnforceTCBAttr>();
8349+
return nullptr;
8350+
}
8351+
8352+
ASTContext &Context = S.getASTContext();
8353+
return ::new(Context) AttrTy(Context, AL, AL.getTCBName());
8354+
}
8355+
8356+
EnforceTCBAttr *Sema::mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL) {
8357+
return mergeEnforceTCBAttrImpl<EnforceTCBAttr, EnforceTCBLeafAttr>(
8358+
*this, D, AL);
8359+
}
8360+
8361+
EnforceTCBLeafAttr *Sema::mergeEnforceTCBLeafAttr(
8362+
Decl *D, const EnforceTCBLeafAttr &AL) {
8363+
return mergeEnforceTCBAttrImpl<EnforceTCBLeafAttr, EnforceTCBAttr>(
8364+
*this, D, AL);
8365+
}
8366+
82988367
//===----------------------------------------------------------------------===//
82998368
// Top Level Sema Entry Points
83008369
//===----------------------------------------------------------------------===//
@@ -9085,6 +9154,14 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
90859154
case ParsedAttr::AT_UseHandle:
90869155
handleHandleAttr<UseHandleAttr>(S, D, AL);
90879156
break;
9157+
9158+
case ParsedAttr::AT_EnforceTCB:
9159+
handleEnforceTCBAttr<EnforceTCBAttr, EnforceTCBLeafAttr>(S, D, AL);
9160+
break;
9161+
9162+
case ParsedAttr::AT_EnforceTCBLeaf:
9163+
handleEnforceTCBAttr<EnforceTCBLeafAttr, EnforceTCBAttr>(S, D, AL);
9164+
break;
90889165
}
90899166
}
90909167

0 commit comments

Comments
 (0)