Skip to content

Commit 36e8a86

Browse files
committed
rework change to rely on pragma intrinsic
Signed-off-by: Sarnie, Nick <[email protected]>
1 parent c66ec11 commit 36e8a86

File tree

6 files changed

+73
-19
lines changed

6 files changed

+73
-19
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,6 +1825,11 @@ class Sema final : public SemaBase {
18251825
/// Set of no-builtin functions listed by \#pragma function.
18261826
llvm::SmallSetVector<StringRef, 4> MSFunctionNoBuiltins;
18271827

1828+
/// Map of BuiltinIDs to source locations that have #pragma intrinsic calls
1829+
/// that refer to them.
1830+
llvm::DenseMap<unsigned, llvm::SmallSetVector<SourceLocation, 4>>
1831+
PragmaIntrinsicBuiltinIDMap;
1832+
18281833
/// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
18291834
/// a the record decl, to handle '\#pragma pack' and '\#pragma options align'.
18301835
void AddAlignmentAttributesForRecord(RecordDecl *RD);
@@ -4345,6 +4350,11 @@ class Sema final : public SemaBase {
43454350
/// contain non-field names.
43464351
Scope *getNonFieldDeclScope(Scope *S);
43474352

4353+
// Determine if the given builtin usage at the given source location
4354+
// was previously specified in a #pragma intrinsic.
4355+
bool isBuiltinSpecifiedInPragmaIntrinsic(unsigned BuiltinID,
4356+
SourceLocation UsageLoc) const;
4357+
43484358
FunctionDecl *CreateBuiltin(IdentifierInfo *II, QualType Type, unsigned ID,
43494359
SourceLocation Loc);
43504360

clang/lib/Parse/ParsePragma.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,13 @@ struct PragmaMSRuntimeChecksHandler : public EmptyPragmaHandler {
301301
};
302302

303303
struct PragmaMSIntrinsicHandler : public PragmaHandler {
304-
PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {}
304+
PragmaMSIntrinsicHandler(Sema &Actions)
305+
: PragmaHandler("intrinsic"), Actions(Actions) {}
305306
void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
306307
Token &FirstToken) override;
308+
309+
private:
310+
Sema &Actions;
307311
};
308312

309313
// "\#pragma fenv_access (on)".
@@ -517,7 +521,7 @@ void Parser::initializePragmaHandlers() {
517521
PP.AddPragmaHandler(MSOptimize.get());
518522
MSRuntimeChecks = std::make_unique<PragmaMSRuntimeChecksHandler>();
519523
PP.AddPragmaHandler(MSRuntimeChecks.get());
520-
MSIntrinsic = std::make_unique<PragmaMSIntrinsicHandler>();
524+
MSIntrinsic = std::make_unique<PragmaMSIntrinsicHandler>(Actions);
521525
PP.AddPragmaHandler(MSIntrinsic.get());
522526
MSFenvAccess = std::make_unique<PragmaMSFenvAccessHandler>();
523527
PP.AddPragmaHandler(MSFenvAccess.get());
@@ -3803,7 +3807,10 @@ void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
38033807
if (!II->getBuiltinID())
38043808
PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
38053809
<< II << SuggestIntrinH;
3806-
3810+
/// Store the location at which the builtin was used in a #pragma intrinsic
3811+
/// so we don't emit a missing header warning later.
3812+
Actions.PragmaIntrinsicBuiltinIDMap[II->getBuiltinID()].insert(
3813+
Tok.getLocation());
38073814
PP.Lex(Tok);
38083815
if (Tok.isNot(tok::comma))
38093816
break;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,6 +2299,21 @@ static StringRef getHeaderName(Builtin::Context &BuiltinInfo, unsigned ID,
22992299
llvm_unreachable("unhandled error kind");
23002300
}
23012301

2302+
bool Sema::isBuiltinSpecifiedInPragmaIntrinsic(unsigned BuiltinID,
2303+
SourceLocation UsageLoc) const {
2304+
assert(Context.BuiltinInfo(BuiltinID) && "Invalid builtin id");
2305+
assert(UsageLoc.isValid() && "Invalid source location");
2306+
auto It = PragmaIntrinsicBuiltinIDMap.find(BuiltinID);
2307+
if (It == PragmaIntrinsicBuiltinIDMap.end())
2308+
return false;
2309+
for (const SourceLocation &PragmaIntrinLoc : It->second) {
2310+
if (Context.getSourceManager().isBeforeInTranslationUnit(PragmaIntrinLoc,
2311+
UsageLoc))
2312+
return true;
2313+
}
2314+
return false;
2315+
}
2316+
23022317
FunctionDecl *Sema::CreateBuiltin(IdentifierInfo *II, QualType Type,
23032318
unsigned ID, SourceLocation Loc) {
23042319
DeclContext *Parent = Context.getTranslationUnitDecl();
@@ -2370,20 +2385,17 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
23702385

23712386
// Generally, we emit a warning that the declaration requires the
23722387
// appropriate header.
2373-
Diag(Loc, diag::warn_implicit_decl_requires_sysheader)
2374-
<< getHeaderName(Context.BuiltinInfo, ID, Error)
2375-
<< Context.BuiltinInfo.getName(ID);
2388+
if (!isBuiltinSpecifiedInPragmaIntrinsic(ID, Loc))
2389+
Diag(Loc, diag::warn_implicit_decl_requires_sysheader)
2390+
<< getHeaderName(Context.BuiltinInfo, ID, Error)
2391+
<< Context.BuiltinInfo.getName(ID);
23762392
return nullptr;
23772393
}
23782394

2379-
// Warn for implicit uses of header dependent libraries,
2380-
// except in system headers.
23812395
if (!ForRedeclaration &&
23822396
(Context.BuiltinInfo.isPredefinedLibFunction(ID) ||
23832397
Context.BuiltinInfo.isHeaderDependentFunction(ID)) &&
2384-
(!getDiagnostics().getSuppressSystemWarnings() ||
2385-
!Context.getSourceManager().isInSystemHeader(
2386-
Context.getSourceManager().getSpellingLoc(Loc)))) {
2398+
!isBuiltinSpecifiedInPragmaIntrinsic(ID, Loc)) {
23872399
Diag(Loc, LangOpts.C99 ? diag::ext_implicit_lib_function_decl_c99
23882400
: diag::ext_implicit_lib_function_decl)
23892401
<< Context.BuiltinInfo.getName(ID) << R;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
1+
#ifdef USE_PRAGMA_BEFORE
2+
#pragma intrinsic(_InterlockedOr64)
3+
#endif
4+
15
#define MACRO(x,y) _InterlockedOr64(x,y);
6+
7+
#ifdef USE_PRAGMA_AFTER
8+
#pragma intrinsic(_InterlockedOr64)
9+
#endif
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -triple arm64-windows -isystem %S/Inputs %s -DUSE_PRAGMA_BEFORE
2+
// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -triple arm64-windows -isystem %S/Inputs %s -DUSE_PRAGMA_AFTER
3+
// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -triple arm64-windows -isystem %S/Inputs %s -DUSE_PRAGMA_AFTER_USE
4+
// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -triple arm64-windows -isystem %S/Inputs %s -DUSE_PRAGMA_SAME_FILE
5+
// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -triple arm64-windows -isystem %S/Inputs %s
6+
7+
#if defined(USE_PRAGMA_BEFORE) || defined(USE_PRAGMA_AFTER) || defined(USE_PRAGMA_SAME_FILE)
8+
// expected-no-diagnostics
9+
#else
10+
// expected-error@+10 {{call to undeclared library function '_InterlockedOr64'}}
11+
// expected-note@+9 {{include the header <intrin.h> or explicitly provide a declaration for '_InterlockedOr64'}}
12+
#endif
13+
#include <builtin-system-header.h>
14+
15+
#ifdef USE_PRAGMA_SAME_FILE
16+
#pragma intrinsic(_InterlockedOr64)
17+
#endif
18+
19+
void foo() {
20+
MACRO(0,0);
21+
}
22+
23+
#ifdef USE_PRAGMA_AFTER_USE
24+
#pragma intrinsic(_InterlockedOr64)
25+
#endif

clang/test/Sema/builtin-system-header.c

Lines changed: 0 additions & 8 deletions
This file was deleted.

0 commit comments

Comments
 (0)