Skip to content

Commit 95bd9ee

Browse files
authored
[clang][Sema] Declare builtins used in #pragma intrinsic (#138205)
When trying to remove the usage of `__has_builtin` on MSVC CUDA ARM for some builtins, the recommended direction was to universally declare the MSVC builtins on all platforms and require the header providing declarations to be included. This was done [here](#128222). However, some MSVC headers already use the MSVC builtins without including the header, so we introduce a warning for anyone compiling with MSVC for this target, so the above change had to be reverted. The MSVC headers use `#pragma intrinsic` before the intrinsic uses and that seems to be enough for MSVC, so declare builtins when used in `#pragma intrinsic` in Clang to prevent the warning. --------- Signed-off-by: Sarnie, Nick <[email protected]>
1 parent cb57578 commit 95bd9ee

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

clang/lib/Parse/ParsePragma.cpp

Lines changed: 15 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());
@@ -3793,7 +3797,15 @@ void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
37933797
if (!II->getBuiltinID())
37943798
PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
37953799
<< II << SuggestIntrinH;
3796-
3800+
// If the builtin hasn't already been declared, declare it now.
3801+
DeclarationNameInfo NameInfo(II, Tok.getLocation());
3802+
LookupResult Previous(Actions, NameInfo, Sema::LookupOrdinaryName,
3803+
Actions.forRedeclarationInCurContext());
3804+
Actions.LookupName(Previous, Actions.getCurScope(),
3805+
/*CreateBuiltins*/ false);
3806+
if (Previous.empty())
3807+
Actions.LazilyCreateBuiltin(II, II->getBuiltinID(), Actions.getCurScope(),
3808+
/*ForRedeclaration*/ true, Tok.getLocation());
37973809
PP.Lex(Tok);
37983810
if (Tok.isNot(tok::comma))
37993811
break;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifdef USE_PRAGMA_BEFORE
2+
#pragma intrinsic(_InterlockedOr64)
3+
#endif
4+
5+
#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

0 commit comments

Comments
 (0)