[clang] Llvm diagnostic spirv#189964 (PR #190840)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 8 19:54:47 PDT 2026
https://github.com/PrabbyDD updated https://github.com/llvm/llvm-project/pull/190840
>From 18508d94e3cde9cf47fa11fcc28803cc7966c5e4 Mon Sep 17 00:00:00 2001
From: PrabbyDD <dhaliprabh at gmail.com>
Date: Mon, 6 Apr 2026 15:43:31 -0700
Subject: [PATCH 1/3] first PR attempt on SPIRV diagnositic
---
clang/include/clang/Basic/DiagnosticFrontendKinds.td | 3 +++
clang/lib/Frontend/CompilerInstance.cpp | 11 +++++++++++
2 files changed, 14 insertions(+)
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 62b74574102e4..7fa858c0d50be 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -43,6 +43,9 @@ def note_fe_backend_resource_limit: Note<"%0 (%1) exceeds limit (%2) in '%3'">,
def remark_fe_backend_plugin: Remark<"%0">, BackendInfo, InGroup<RemarkBackendPlugin>;
def note_fe_backend_plugin: Note<"%0">, BackendInfo;
+def err_spirv_requires_vulkan : Error
+ "SPIR-V target requires a Vulkan environment, e.g. '-target spirv64-unknown-vulkan1.3'">;
+
def warn_fe_override_module : Warning<
"overriding the module target triple with %0">,
InGroup<DiagGroup<"override-module">>;
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 0b00ad7128c00..89898d3adfbae 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -112,6 +112,17 @@ void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; }
void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; }
bool CompilerInstance::createTarget() {
+
+ // Validate Vulkan environment for SPIRV.
+ llvm::Triple Triple(getInvocation().getTargetOpts().Triple);
+ if (Triple.getArch() == llvm::Triple::spirv) {
+ if (Triple.getOS() != llvm::Triple::Vulkan ||
+ Triple.getVulkanVersion() == llvm::VersionTuple(0)) {
+ getDiagnostics().Report(diag::err_spirv_requires_vulkan) << Triple.str();
+ return false;
+ }
+ }
+
// Create the target instance.
setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(),
getInvocation().getTargetOpts()));
>From 2b0276129061915fc82c1639439c7b733215e196 Mon Sep 17 00:00:00 2001
From: PrabbyDD <dhaliprabh at gmail.com>
Date: Tue, 7 Apr 2026 13:04:38 -0700
Subject: [PATCH 2/3] [clang] generate diagnostic error instead of assert for
invalid SPIR-V target for release
When a user passes '-target spirv' without specififying a vulkan environment ttriple, SPIRVTargetInfo will fire an assert instead of throwing an error diagnostic. Added this diagnostic in CompilerInstance::createTarget() before target is initialized. Fixes #189964
---
clang/include/clang/Basic/DiagnosticFrontendKinds.td | 4 ++--
clang/test/Driver/spirv-target-validation.c | 4 ++++
2 files changed, 6 insertions(+), 2 deletions(-)
create mode 100644 clang/test/Driver/spirv-target-validation.c
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 7fa858c0d50be..0a3e4e82a79e5 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -43,8 +43,8 @@ def note_fe_backend_resource_limit: Note<"%0 (%1) exceeds limit (%2) in '%3'">,
def remark_fe_backend_plugin: Remark<"%0">, BackendInfo, InGroup<RemarkBackendPlugin>;
def note_fe_backend_plugin: Note<"%0">, BackendInfo;
-def err_spirv_requires_vulkan : Error
- "SPIR-V target requires a Vulkan environment, e.g. '-target spirv64-unknown-vulkan1.3'">;
+def err_spirv_requires_vulkan : Error<
+ "SPIR-V target requires a Vulkan environment (e.g. '-target spirv64-unknown-vulkan1.3')">;
def warn_fe_override_module : Warning<
"overriding the module target triple with %0">,
diff --git a/clang/test/Driver/spirv-target-validation.c b/clang/test/Driver/spirv-target-validation.c
new file mode 100644
index 0000000000000..cde5b46c54b94
--- /dev/null
+++ b/clang/test/Driver/spirv-target-validation.c
@@ -0,0 +1,4 @@
+// RUN: %clang -target spirv %s 2>&1 | FileCheck %s
+// CHECK: error: SPIR-V target requires a Vulkan environment
+
+int main() { return 0; }
\ No newline at end of file
>From 35dc19dcf5f281e3df5db7d96d4ac39cdb6eadb8 Mon Sep 17 00:00:00 2001
From: PrabbyDD <dhaliprabh at gmail.com>
Date: Tue, 7 Apr 2026 18:07:45 -0700
Subject: [PATCH 3/3] Fix formatting
---
clang/lib/Frontend/CompilerInstance.cpp | 96 ++++++++++-----------
clang/test/Driver/spirv-target-validation.c | 2 +-
2 files changed, 45 insertions(+), 53 deletions(-)
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 89898d3adfbae..efaf0b5cc7905 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -103,7 +103,8 @@ void CompilerInstance::setVerboseOutputStream(raw_ostream &Value) {
VerboseOutputStream = &Value;
}
-void CompilerInstance::setVerboseOutputStream(std::unique_ptr<raw_ostream> Value) {
+void CompilerInstance::setVerboseOutputStream(
+ std::unique_ptr<raw_ostream> Value) {
OwnedVerboseOutputStream.swap(Value);
VerboseOutputStream = OwnedVerboseOutputStream.get();
}
@@ -113,7 +114,7 @@ void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; }
bool CompilerInstance::createTarget() {
- // Validate Vulkan environment for SPIRV.
+ // Validate Vulkan environment for SPIRV.
llvm::Triple Triple(getInvocation().getTargetOpts().Triple);
if (Triple.getArch() == llvm::Triple::spirv) {
if (Triple.getOS() != llvm::Triple::Vulkan ||
@@ -197,9 +198,7 @@ void CompilerInstance::setASTContext(
getASTConsumer().Initialize(getASTContext());
}
-void CompilerInstance::setSema(Sema *S) {
- TheSema.reset(S);
-}
+void CompilerInstance::setSema(Sema *S) { TheSema.reset(S); }
void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) {
Consumer = std::move(Value);
@@ -327,7 +326,7 @@ static void SetUpDiagnosticLog(DiagnosticOptions &DiagOpts,
// Chain in the diagnostic client which will log the diagnostics.
auto Logger = std::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts,
- std::move(StreamOwner));
+ std::move(StreamOwner));
if (CodeGenOpts)
Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags);
if (Diags.ownsClient()) {
@@ -608,7 +607,8 @@ struct ReadModuleNames : ASTReaderListener {
Stack.push_back(M);
while (!Stack.empty()) {
Module *Current = Stack.pop_back_val();
- if (Current->IsUnimportable) continue;
+ if (Current->IsUnimportable)
+ continue;
Current->IsAvailable = true;
auto SubmodulesRange = Current->submodules();
llvm::append_range(Stack, SubmodulesRange);
@@ -702,16 +702,14 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
// Code Completion
-static bool EnableCodeCompletion(Preprocessor &PP,
- StringRef Filename,
- unsigned Line,
- unsigned Column) {
+static bool EnableCodeCompletion(Preprocessor &PP, StringRef Filename,
+ unsigned Line, unsigned Column) {
// Tell the source manager to chop off the given file at a specific
// line and column.
auto Entry = PP.getFileManager().getOptionalFileRef(Filename);
if (!Entry) {
PP.getDiagnostics().Report(diag::err_fe_invalid_code_complete_file)
- << Filename;
+ << Filename;
return true;
}
@@ -727,8 +725,8 @@ void CompilerInstance::createCodeCompletionConsumer() {
getPreprocessor(), Loc.FileName, Loc.Line, Loc.Column,
getFrontendOpts().CodeCompleteOpts, llvm::outs()));
return;
- } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName,
- Loc.Line, Loc.Column)) {
+ } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName, Loc.Line,
+ Loc.Column)) {
setCodeCompletionConsumer(nullptr);
return;
}
@@ -739,13 +737,9 @@ void CompilerInstance::createFrontendTimer() {
FrontendTimer.reset(new llvm::Timer("frontend", "Front end", *timerGroup));
}
-CodeCompleteConsumer *
-CompilerInstance::createCodeCompletionConsumer(Preprocessor &PP,
- StringRef Filename,
- unsigned Line,
- unsigned Column,
- const CodeCompleteOptions &Opts,
- raw_ostream &OS) {
+CodeCompleteConsumer *CompilerInstance::createCodeCompletionConsumer(
+ Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column,
+ const CodeCompleteOptions &Opts, raw_ostream &OS) {
if (EnableCodeCompletion(PP, Filename, Line, Column))
return nullptr;
@@ -907,7 +901,7 @@ CompilerInstance::createOutputFileImpl(StringRef OutputPath, bool Binary,
// Initialization Utilities
-bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input){
+bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input) {
return InitializeSourceManager(Input, getDiagnostics(), getFileManager(),
getSourceManager());
}
@@ -921,7 +915,8 @@ bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input,
Input.getKind().getFormat() == InputKind::ModuleMap
? Input.isSystem() ? SrcMgr::C_System_ModuleMap
: SrcMgr::C_User_ModuleMap
- : Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
+ : Input.isSystem() ? SrcMgr::C_System
+ : SrcMgr::C_User;
if (Input.isBuffer()) {
SourceMgr.setMainFileID(SourceMgr.createFileID(Input.getBuffer(), Kind));
@@ -1452,7 +1447,7 @@ static bool readASTAfterCompileModule(CompilerInstance &ImportingInstance,
// The ASTReader didn't diagnose the error, so conservatively report it.
if (ReadResult == ASTReader::Missing || !Diags.hasErrorOccurred())
Diags.Report(ModuleNameLoc, diag::err_module_not_built)
- << Module->Name << SourceRange(ImportLoc, ModuleNameLoc);
+ << Module->Name << SourceRange(ImportLoc, ModuleNameLoc);
return false;
}
@@ -1671,29 +1666,29 @@ static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro,
// This macro was defined on the command line, then #undef'd later.
// Complain.
PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
- << true << ConfigMacro << Mod->getFullModuleName();
+ << true << ConfigMacro << Mod->getFullModuleName();
auto LatestDef = LatestLocalMD->getDefinition();
assert(LatestDef.isUndefined() &&
"predefined macro went away with no #undef?");
PP.Diag(LatestDef.getUndefLocation(), diag::note_module_def_undef_here)
- << true;
+ << true;
return;
} else if (!CmdLineDefinition) {
// There was no definition for this macro in the command line,
// but there was a local definition. Complain.
PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
- << false << ConfigMacro << Mod->getFullModuleName();
+ << false << ConfigMacro << Mod->getFullModuleName();
PP.Diag(CurrentDefinition->getDefinitionLoc(),
diag::note_module_def_undef_here)
- << false;
+ << false;
} else if (!CurrentDefinition->isIdenticalTo(*CmdLineDefinition, PP,
/*Syntactically=*/true)) {
// The macro definitions differ.
PP.Diag(ImportLoc, diag::warn_module_config_macro_undef)
- << false << ConfigMacro << Mod->getFullModuleName();
+ << false << ConfigMacro << Mod->getFullModuleName();
PP.Diag(CurrentDefinition->getDefinitionLoc(),
diag::note_module_def_undef_here)
- << false;
+ << false;
}
}
@@ -1748,7 +1743,7 @@ void CompilerInstance::createASTReader() {
TheASTReader->setDeserializationListener(
getASTConsumer().GetASTDeserializationListener());
getASTContext().setASTMutationListener(
- getASTConsumer().GetASTMutationListener());
+ getASTConsumer().GetASTMutationListener());
}
getASTContext().setExternalSource(TheASTReader);
if (hasSema())
@@ -1910,16 +1905,15 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST(
unsigned ARRFlags = Source == MS_ModuleCache
? ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing |
ASTReader::ARR_TreatModuleWithErrorsAsOutOfDate
- : Source == MS_PrebuiltModulePath
- ? 0
- : ASTReader::ARR_ConfigurationMismatch;
- switch (getASTReader()->ReadAST(ModuleFilename,
- Source == MS_PrebuiltModulePath
- ? serialization::MK_PrebuiltModule
- : Source == MS_ModuleBuildPragma
- ? serialization::MK_ExplicitModule
- : serialization::MK_ImplicitModule,
- ImportLoc, ARRFlags)) {
+ : Source == MS_PrebuiltModulePath
+ ? 0
+ : ASTReader::ARR_ConfigurationMismatch;
+ switch (getASTReader()->ReadAST(
+ ModuleFilename,
+ Source == MS_PrebuiltModulePath ? serialization::MK_PrebuiltModule
+ : Source == MS_ModuleBuildPragma ? serialization::MK_ExplicitModule
+ : serialization::MK_ImplicitModule,
+ ImportLoc, ARRFlags)) {
case ASTReader::Success: {
if (M)
return M;
@@ -2019,8 +2013,7 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST(
}
ModuleLoadResult
-CompilerInstance::loadModule(SourceLocation ImportLoc,
- ModuleIdPath Path,
+CompilerInstance::loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
Module::NameVisibilityKind Visibility,
bool IsInclusionDirective) {
// Determine what file we're searching from.
@@ -2255,7 +2248,7 @@ void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc,
FrontendInputFile Input(
ModuleMapFileName,
InputKind(getLanguageFromOptions(Invocation->getLangOpts()),
- InputKind::ModuleMap, /*Preprocessed*/true));
+ InputKind::ModuleMap, /*Preprocessed*/ true));
std::string NullTerminatedSource(Source.str());
@@ -2296,8 +2289,8 @@ void CompilerInstance::makeModuleVisible(Module *Mod,
TheASTReader->makeModuleVisible(Mod, Visibility, ImportLoc);
}
-GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
- SourceLocation TriggerLoc) {
+GlobalModuleIndex *
+CompilerInstance::loadGlobalModuleIndex(SourceLocation TriggerLoc) {
if (getPreprocessor()
.getHeaderSearchInfo()
.getSpecificModuleCachePath()
@@ -2343,7 +2336,8 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
bool RecreateIndex = false;
for (ModuleMap::module_iterator I = MMap.module_begin(),
- E = MMap.module_end(); I != E; ++I) {
+ E = MMap.module_end();
+ I != E; ++I) {
Module *TheModule = I->second;
if (!TheModule->getASTFileKey()) {
SmallVector<IdentifierLoc, 2> Path;
@@ -2375,15 +2369,13 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
}
// Check global module index for missing imports.
-bool
-CompilerInstance::lookupMissingImports(StringRef Name,
- SourceLocation TriggerLoc) {
+bool CompilerInstance::lookupMissingImports(StringRef Name,
+ SourceLocation TriggerLoc) {
// Look for the symbol in non-imported modules, but only if an error
// actually occurred.
if (!buildingModule()) {
// Load global module index, or retrieve a previously loaded one.
- GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex(
- TriggerLoc);
+ GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex(TriggerLoc);
// Only if we have a global index.
if (GlobalIndex) {
diff --git a/clang/test/Driver/spirv-target-validation.c b/clang/test/Driver/spirv-target-validation.c
index cde5b46c54b94..c87e528c75350 100644
--- a/clang/test/Driver/spirv-target-validation.c
+++ b/clang/test/Driver/spirv-target-validation.c
@@ -1,4 +1,4 @@
-// RUN: %clang -target spirv %s 2>&1 | FileCheck %s
+// RUN: not %clang -target spirv %s 2>&1 | FileCheck %s
// CHECK: error: SPIR-V target requires a Vulkan environment
int main() { return 0; }
\ No newline at end of file
More information about the cfe-commits
mailing list