https://github.com/sarnex updated 
https://github.com/llvm/llvm-project/pull/138205

>From c66ec11d8170a0e4c0b2fc50bdae039fd9c208fb Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sar...@intel.com>
Date: Thu, 1 May 2025 14:47:45 -0700
Subject: [PATCH 1/3] [clang][Sema] Don't warn for implicit uses of builtins in
 system headers

Signed-off-by: Sarnie, Nick <nick.sar...@intel.com>
---
 clang/lib/Sema/SemaDecl.cpp                    | 7 ++++++-
 clang/test/Sema/Inputs/builtin-system-header.h | 1 +
 clang/test/Sema/builtin-system-header.c        | 8 ++++++++
 3 files changed, 15 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Sema/Inputs/builtin-system-header.h
 create mode 100644 clang/test/Sema/builtin-system-header.c

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a3285e8f6f5a2..37008f9eb3235 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2376,9 +2376,14 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, 
unsigned ID,
     return nullptr;
   }
 
+  // Warn for implicit uses of header dependent libraries,
+  // except in system headers.
   if (!ForRedeclaration &&
       (Context.BuiltinInfo.isPredefinedLibFunction(ID) ||
-       Context.BuiltinInfo.isHeaderDependentFunction(ID))) {
+       Context.BuiltinInfo.isHeaderDependentFunction(ID)) &&
+      (!getDiagnostics().getSuppressSystemWarnings() ||
+       !Context.getSourceManager().isInSystemHeader(
+           Context.getSourceManager().getSpellingLoc(Loc)))) {
     Diag(Loc, LangOpts.C99 ? diag::ext_implicit_lib_function_decl_c99
                            : diag::ext_implicit_lib_function_decl)
         << Context.BuiltinInfo.getName(ID) << R;
diff --git a/clang/test/Sema/Inputs/builtin-system-header.h 
b/clang/test/Sema/Inputs/builtin-system-header.h
new file mode 100644
index 0000000000000..ebd5655e6f8ef
--- /dev/null
+++ b/clang/test/Sema/Inputs/builtin-system-header.h
@@ -0,0 +1 @@
+#define MACRO(x,y) _InterlockedOr64(x,y);
diff --git a/clang/test/Sema/builtin-system-header.c 
b/clang/test/Sema/builtin-system-header.c
new file mode 100644
index 0000000000000..83c3c15e314a7
--- /dev/null
+++ b/clang/test/Sema/builtin-system-header.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -triple arm64-windows 
-isystem %S/Inputs %s
+
+// expected-no-diagnostics
+#include <builtin-system-header.h>
+
+void foo() {
+  MACRO(0,0);
+}

>From 36e8a8632e21604b42e3e87168edd648572cfc89 Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sar...@intel.com>
Date: Fri, 16 May 2025 12:58:34 -0700
Subject: [PATCH 2/3] rework change to rely on pragma intrinsic

Signed-off-by: Sarnie, Nick <nick.sar...@intel.com>
---
 clang/include/clang/Sema/Sema.h               | 10 +++++++
 clang/lib/Parse/ParsePragma.cpp               | 13 +++++++--
 clang/lib/Sema/SemaDecl.cpp                   | 28 +++++++++++++------
 .../test/Sema/Inputs/builtin-system-header.h  |  8 ++++++
 clang/test/Sema/builtin-pragma-intrinsic.c    | 25 +++++++++++++++++
 clang/test/Sema/builtin-system-header.c       |  8 ------
 6 files changed, 73 insertions(+), 19 deletions(-)
 create mode 100644 clang/test/Sema/builtin-pragma-intrinsic.c
 delete mode 100644 clang/test/Sema/builtin-system-header.c

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 14f9304b99030..7fc97d78390aa 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1825,6 +1825,11 @@ class Sema final : public SemaBase {
   /// Set of no-builtin functions listed by \#pragma function.
   llvm::SmallSetVector<StringRef, 4> MSFunctionNoBuiltins;
 
+  /// Map of BuiltinIDs to source locations that have #pragma intrinsic calls
+  /// that refer to them.
+  llvm::DenseMap<unsigned, llvm::SmallSetVector<SourceLocation, 4>>
+      PragmaIntrinsicBuiltinIDMap;
+
   /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
   /// a the record decl, to handle '\#pragma pack' and '\#pragma options 
align'.
   void AddAlignmentAttributesForRecord(RecordDecl *RD);
@@ -4345,6 +4350,11 @@ class Sema final : public SemaBase {
   /// contain non-field names.
   Scope *getNonFieldDeclScope(Scope *S);
 
+  // Determine if the given builtin usage at the given source location
+  // was previously specified in a #pragma intrinsic.
+  bool isBuiltinSpecifiedInPragmaIntrinsic(unsigned BuiltinID,
+                                           SourceLocation UsageLoc) const;
+
   FunctionDecl *CreateBuiltin(IdentifierInfo *II, QualType Type, unsigned ID,
                               SourceLocation Loc);
 
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index 9f9e4bb92af8c..c465dc1449ce8 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -301,9 +301,13 @@ struct PragmaMSRuntimeChecksHandler : public 
EmptyPragmaHandler {
 };
 
 struct PragmaMSIntrinsicHandler : public PragmaHandler {
-  PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {}
+  PragmaMSIntrinsicHandler(Sema &Actions)
+      : PragmaHandler("intrinsic"), Actions(Actions) {}
   void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
                     Token &FirstToken) override;
+
+private:
+  Sema &Actions;
 };
 
 // "\#pragma fenv_access (on)".
@@ -517,7 +521,7 @@ void Parser::initializePragmaHandlers() {
     PP.AddPragmaHandler(MSOptimize.get());
     MSRuntimeChecks = std::make_unique<PragmaMSRuntimeChecksHandler>();
     PP.AddPragmaHandler(MSRuntimeChecks.get());
-    MSIntrinsic = std::make_unique<PragmaMSIntrinsicHandler>();
+    MSIntrinsic = std::make_unique<PragmaMSIntrinsicHandler>(Actions);
     PP.AddPragmaHandler(MSIntrinsic.get());
     MSFenvAccess = std::make_unique<PragmaMSFenvAccessHandler>();
     PP.AddPragmaHandler(MSFenvAccess.get());
@@ -3803,7 +3807,10 @@ void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor 
&PP,
     if (!II->getBuiltinID())
       PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
           << II << SuggestIntrinH;
-
+    /// Store the location at which the builtin was used in a #pragma intrinsic
+    /// so we don't emit a missing header warning later.
+    Actions.PragmaIntrinsicBuiltinIDMap[II->getBuiltinID()].insert(
+        Tok.getLocation());
     PP.Lex(Tok);
     if (Tok.isNot(tok::comma))
       break;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 37008f9eb3235..48b89663069c5 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2299,6 +2299,21 @@ static StringRef getHeaderName(Builtin::Context 
&BuiltinInfo, unsigned ID,
   llvm_unreachable("unhandled error kind");
 }
 
+bool Sema::isBuiltinSpecifiedInPragmaIntrinsic(unsigned BuiltinID,
+                                               SourceLocation UsageLoc) const {
+  assert(Context.BuiltinInfo(BuiltinID) && "Invalid builtin id");
+  assert(UsageLoc.isValid() && "Invalid source location");
+  auto It = PragmaIntrinsicBuiltinIDMap.find(BuiltinID);
+  if (It == PragmaIntrinsicBuiltinIDMap.end())
+    return false;
+  for (const SourceLocation &PragmaIntrinLoc : It->second) {
+    if (Context.getSourceManager().isBeforeInTranslationUnit(PragmaIntrinLoc,
+                                                             UsageLoc))
+      return true;
+  }
+  return false;
+}
+
 FunctionDecl *Sema::CreateBuiltin(IdentifierInfo *II, QualType Type,
                                   unsigned ID, SourceLocation Loc) {
   DeclContext *Parent = Context.getTranslationUnitDecl();
@@ -2370,20 +2385,17 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo 
*II, unsigned ID,
 
     // Generally, we emit a warning that the declaration requires the
     // appropriate header.
-    Diag(Loc, diag::warn_implicit_decl_requires_sysheader)
-        << getHeaderName(Context.BuiltinInfo, ID, Error)
-        << Context.BuiltinInfo.getName(ID);
+    if (!isBuiltinSpecifiedInPragmaIntrinsic(ID, Loc))
+      Diag(Loc, diag::warn_implicit_decl_requires_sysheader)
+          << getHeaderName(Context.BuiltinInfo, ID, Error)
+          << Context.BuiltinInfo.getName(ID);
     return nullptr;
   }
 
-  // Warn for implicit uses of header dependent libraries,
-  // except in system headers.
   if (!ForRedeclaration &&
       (Context.BuiltinInfo.isPredefinedLibFunction(ID) ||
        Context.BuiltinInfo.isHeaderDependentFunction(ID)) &&
-      (!getDiagnostics().getSuppressSystemWarnings() ||
-       !Context.getSourceManager().isInSystemHeader(
-           Context.getSourceManager().getSpellingLoc(Loc)))) {
+      !isBuiltinSpecifiedInPragmaIntrinsic(ID, Loc)) {
     Diag(Loc, LangOpts.C99 ? diag::ext_implicit_lib_function_decl_c99
                            : diag::ext_implicit_lib_function_decl)
         << Context.BuiltinInfo.getName(ID) << R;
diff --git a/clang/test/Sema/Inputs/builtin-system-header.h 
b/clang/test/Sema/Inputs/builtin-system-header.h
index ebd5655e6f8ef..7eeb8d811fcfa 100644
--- a/clang/test/Sema/Inputs/builtin-system-header.h
+++ b/clang/test/Sema/Inputs/builtin-system-header.h
@@ -1 +1,9 @@
+#ifdef USE_PRAGMA_BEFORE
+#pragma intrinsic(_InterlockedOr64)
+#endif
+
 #define MACRO(x,y) _InterlockedOr64(x,y);
+
+#ifdef USE_PRAGMA_AFTER
+#pragma intrinsic(_InterlockedOr64)
+#endif
diff --git a/clang/test/Sema/builtin-pragma-intrinsic.c 
b/clang/test/Sema/builtin-pragma-intrinsic.c
new file mode 100644
index 0000000000000..1e8507bfd37df
--- /dev/null
+++ b/clang/test/Sema/builtin-pragma-intrinsic.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -triple arm64-windows 
-isystem %S/Inputs %s -DUSE_PRAGMA_BEFORE
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -triple arm64-windows 
-isystem %S/Inputs %s -DUSE_PRAGMA_AFTER
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -triple arm64-windows 
-isystem %S/Inputs %s -DUSE_PRAGMA_AFTER_USE
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -triple arm64-windows 
-isystem %S/Inputs %s -DUSE_PRAGMA_SAME_FILE
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -triple arm64-windows 
-isystem %S/Inputs %s
+
+#if defined(USE_PRAGMA_BEFORE) || defined(USE_PRAGMA_AFTER) || 
defined(USE_PRAGMA_SAME_FILE)
+// expected-no-diagnostics
+#else
+// expected-error@+10 {{call to undeclared library function 
'_InterlockedOr64'}}
+// expected-note@+9 {{include the header <intrin.h> or explicitly provide a 
declaration for '_InterlockedOr64'}}
+#endif
+#include <builtin-system-header.h>
+
+#ifdef USE_PRAGMA_SAME_FILE
+#pragma intrinsic(_InterlockedOr64)
+#endif
+
+void foo() {
+  MACRO(0,0);
+}
+
+#ifdef USE_PRAGMA_AFTER_USE
+#pragma intrinsic(_InterlockedOr64)
+#endif
diff --git a/clang/test/Sema/builtin-system-header.c 
b/clang/test/Sema/builtin-system-header.c
deleted file mode 100644
index 83c3c15e314a7..0000000000000
--- a/clang/test/Sema/builtin-system-header.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -triple arm64-windows 
-isystem %S/Inputs %s
-
-// expected-no-diagnostics
-#include <builtin-system-header.h>
-
-void foo() {
-  MACRO(0,0);
-}

>From 81e57222cce50d137d54d8f7743b5c43fa4a7beb Mon Sep 17 00:00:00 2001
From: "Sarnie, Nick" <nick.sar...@intel.com>
Date: Mon, 19 May 2025 11:15:48 -0700
Subject: [PATCH 3/3] declare the builtin if needed

Signed-off-by: Sarnie, Nick <nick.sar...@intel.com>
---
 clang/include/clang/Sema/Sema.h | 10 ----------
 clang/lib/Parse/ParsePragma.cpp | 13 +++++++++----
 clang/lib/Sema/SemaDecl.cpp     | 25 ++++---------------------
 3 files changed, 13 insertions(+), 35 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 7fc97d78390aa..14f9304b99030 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1825,11 +1825,6 @@ class Sema final : public SemaBase {
   /// Set of no-builtin functions listed by \#pragma function.
   llvm::SmallSetVector<StringRef, 4> MSFunctionNoBuiltins;
 
-  /// Map of BuiltinIDs to source locations that have #pragma intrinsic calls
-  /// that refer to them.
-  llvm::DenseMap<unsigned, llvm::SmallSetVector<SourceLocation, 4>>
-      PragmaIntrinsicBuiltinIDMap;
-
   /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
   /// a the record decl, to handle '\#pragma pack' and '\#pragma options 
align'.
   void AddAlignmentAttributesForRecord(RecordDecl *RD);
@@ -4350,11 +4345,6 @@ class Sema final : public SemaBase {
   /// contain non-field names.
   Scope *getNonFieldDeclScope(Scope *S);
 
-  // Determine if the given builtin usage at the given source location
-  // was previously specified in a #pragma intrinsic.
-  bool isBuiltinSpecifiedInPragmaIntrinsic(unsigned BuiltinID,
-                                           SourceLocation UsageLoc) const;
-
   FunctionDecl *CreateBuiltin(IdentifierInfo *II, QualType Type, unsigned ID,
                               SourceLocation Loc);
 
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index c465dc1449ce8..ec064e441a5f8 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -3807,10 +3807,15 @@ void 
PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
     if (!II->getBuiltinID())
       PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
           << II << SuggestIntrinH;
-    /// Store the location at which the builtin was used in a #pragma intrinsic
-    /// so we don't emit a missing header warning later.
-    Actions.PragmaIntrinsicBuiltinIDMap[II->getBuiltinID()].insert(
-        Tok.getLocation());
+    // If the builtin hasn't already been declared, declare it now.
+    DeclarationNameInfo NameInfo(II, Tok.getLocation());
+    LookupResult Previous(Actions, NameInfo, Sema::LookupOrdinaryName,
+                          Actions.forRedeclarationInCurContext());
+    Actions.LookupName(Previous, Actions.getCurScope(),
+                       /*CreateBuiltins*/ false);
+    if (Previous.empty())
+      Actions.LazilyCreateBuiltin(II, II->getBuiltinID(), 
Actions.getCurScope(),
+                                  /*ForRedeclaration*/ true, 
Tok.getLocation());
     PP.Lex(Tok);
     if (Tok.isNot(tok::comma))
       break;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 48b89663069c5..a3285e8f6f5a2 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2299,21 +2299,6 @@ static StringRef getHeaderName(Builtin::Context 
&BuiltinInfo, unsigned ID,
   llvm_unreachable("unhandled error kind");
 }
 
-bool Sema::isBuiltinSpecifiedInPragmaIntrinsic(unsigned BuiltinID,
-                                               SourceLocation UsageLoc) const {
-  assert(Context.BuiltinInfo(BuiltinID) && "Invalid builtin id");
-  assert(UsageLoc.isValid() && "Invalid source location");
-  auto It = PragmaIntrinsicBuiltinIDMap.find(BuiltinID);
-  if (It == PragmaIntrinsicBuiltinIDMap.end())
-    return false;
-  for (const SourceLocation &PragmaIntrinLoc : It->second) {
-    if (Context.getSourceManager().isBeforeInTranslationUnit(PragmaIntrinLoc,
-                                                             UsageLoc))
-      return true;
-  }
-  return false;
-}
-
 FunctionDecl *Sema::CreateBuiltin(IdentifierInfo *II, QualType Type,
                                   unsigned ID, SourceLocation Loc) {
   DeclContext *Parent = Context.getTranslationUnitDecl();
@@ -2385,17 +2370,15 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo 
*II, unsigned ID,
 
     // Generally, we emit a warning that the declaration requires the
     // appropriate header.
-    if (!isBuiltinSpecifiedInPragmaIntrinsic(ID, Loc))
-      Diag(Loc, diag::warn_implicit_decl_requires_sysheader)
-          << getHeaderName(Context.BuiltinInfo, ID, Error)
-          << Context.BuiltinInfo.getName(ID);
+    Diag(Loc, diag::warn_implicit_decl_requires_sysheader)
+        << getHeaderName(Context.BuiltinInfo, ID, Error)
+        << Context.BuiltinInfo.getName(ID);
     return nullptr;
   }
 
   if (!ForRedeclaration &&
       (Context.BuiltinInfo.isPredefinedLibFunction(ID) ||
-       Context.BuiltinInfo.isHeaderDependentFunction(ID)) &&
-      !isBuiltinSpecifiedInPragmaIntrinsic(ID, Loc)) {
+       Context.BuiltinInfo.isHeaderDependentFunction(ID))) {
     Diag(Loc, LangOpts.C99 ? diag::ext_implicit_lib_function_decl_c99
                            : diag::ext_implicit_lib_function_decl)
         << Context.BuiltinInfo.getName(ID) << R;

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to