llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: Sarah Spall (spall) <details> <summary>Changes</summary> Add the `precise` keyword If `precise` appears anywhere in a translation unit, the whole translation unit is compiled as if `-Gis` (`-ffp-model=strict`) and `-fno-fast-math` were given, matching DXC. To support this, all HLSL codegen is deferred to the end of the translation unit. The FP options are then switched to strict before any code is emitted. Delay emitting warn_fp_nan_inf_when_disabled warning till codegen and if precise does not appear. `precise` in an uninstantiated template or an unused typedef still affects the whole translation unit. Closes #<!-- -->232058 Assisted by Copilot --- Patch is 30.60 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/234462.diff 18 Files Affected: - (modified) clang/include/clang/Basic/Attr.td (+7) - (modified) clang/include/clang/Basic/AttrDocs.td (+17) - (modified) clang/include/clang/Basic/TokenKinds.def (+1) - (modified) clang/include/clang/Sema/SemaHLSL.h (+5) - (modified) clang/lib/CodeGen/CGCall.cpp (+8-2) - (modified) clang/lib/CodeGen/CodeGenAction.cpp (+46) - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+4-2) - (modified) clang/lib/CodeGen/ModuleBuilder.cpp (+69) - (modified) clang/lib/Parse/ParseDecl.cpp (+4) - (modified) clang/lib/Parse/ParseTentative.cpp (+2-1) - (modified) clang/lib/Sema/SemaChecking.cpp (+31-13) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+3) - (modified) clang/lib/Sema/SemaHLSL.cpp (+20) - (added) clang/test/AST/HLSL/precise.hlsl (+80) - (added) clang/test/CodeGenHLSL/precise-unused.hlsl (+26) - (added) clang/test/CodeGenHLSL/precise.hlsl (+58) - (added) clang/test/ParserHLSL/precise-keyword.hlsl (+6) - (added) clang/test/SemaHLSL/precise-fp-diagnostics.hlsl (+35) ``````````diff diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index f8bd097733529a..a8c6efef0c5c9b 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -5477,6 +5477,13 @@ def HLSLColumnMajor : TypeAttr { let Documentation = [HLSLMatrixLayoutDocs]; } +def HLSLPrecise : HLSLAnnotationAttr { + let Spellings = [CustomKeyword<"precise">]; + let Subjects = SubjectList<[Field, Function, Var, TypedefName], ErrorDiag>; + let LangOpts = [HLSL]; + let Documentation = [HLSLPreciseDocs]; +} + def RandomizeLayout : InheritableAttr { let Spellings = [GCC<"randomize_layout">]; let Subjects = SubjectList<[Record]>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index e8ce3c3dea7f3b..821ee53958453d 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -9759,6 +9759,23 @@ row_major float2x2 myMatrix; }]; } +def HLSLPreciseDocs : Documentation { + let Category = DocCatVariable; + let Heading = "precise"; + let Content = [{ +The HLSL ``precise`` keyword can be applied to variables, parameters, fields, +typedefs, and function return values to request that floating-point computations +contributing to their values are performed with IEEE-strict semantics. + +Clang currently implements a simplified version of ``precise``: if the keyword +is used anywhere in a translation unit, the whole translation unit is compiled +in IEEE-strict floating-point mode, as if ``-Gis`` (``-ffp-model=strict``) and +``-fno-fast-math`` had been specified. + +The full documentation is available here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-variable-syntax + }]; +} + def WebAssemblyFuncrefDocs : Documentation { let Category = DocCatType; let Content = [{ diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 528825ad68b8dc..f8ef70728be001 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -555,6 +555,7 @@ KEYWORD(inout , KEYHLSL) KEYWORD(out , KEYHLSL) KEYWORD(row_major , KEYHLSL) KEYWORD(column_major , KEYHLSL) +KEYWORD(precise , KEYHLSL) // HLSL Intangible Types #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) KEYWORD(Name, KEYHLSL) #include "clang/Basic/HLSLIntangibleTypes.def" diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index 3d62f47dfde691..cc3dc6b9f123b5 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -18,6 +18,7 @@ #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/DiagnosticSema.h" +#include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/SemaBase.h" #include "llvm/ADT/ArrayRef.h" @@ -191,6 +192,8 @@ class SemaHLSL : public SemaBase { void handleShaderAttr(Decl *D, const ParsedAttr &AL); void handleResourceBindingAttr(Decl *D, const ParsedAttr &AL); void handleParamModifierAttr(Decl *D, const ParsedAttr &AL); + void handlePreciseAttr(Decl *D, const ParsedAttr &AL); + void deferFPNaNInfDiagnostic(const CallExpr *Call, bool IsNaN); void handleInterpolationModifierAttr(Decl *D, const ParsedAttr &AL); Attr *buildMatrixLayoutTypeAttr(QualType T, const ParsedAttr &AL); bool diagnoseMatrixLayoutInstantiation(attr::Kind K, QualType T, @@ -244,6 +247,8 @@ class SemaHLSL : public SemaBase { bool initGlobalResourceArrayDecl(VarDecl *VD); private: + llvm::SmallVector<PartialDiagnosticAt> DeferredFPNaNInfDiagnostics; + // HLSL resource type attributes need to be processed all at once. // This is a list to collect them. llvm::SmallVector<const Attr *> HLSLResourcesTypeAttrs; diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index bc942d8a6246f7..23d36a46888225 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -6292,7 +6292,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, } if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) { - if (FD->hasAttr<StrictFPAttr>()) + // HLSL `precise` makes the function strictfp after Sema decided whether to + // add StrictFPAttr, so also check the emitted function. + if (FD->hasAttr<StrictFPAttr>() || + (getContext().getTranslationUnitDecl()->hasAttr<HLSLPreciseAttr>() && + CurFn->hasFnAttribute(llvm::Attribute::StrictFP))) // All calls within a strictfp function are marked strictfp Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::StrictFP); @@ -6381,7 +6385,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, EmitPointerAuthOperandBundle(ConcreteCallee.getPointerAuthInfo(), BundleList); if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) - if (FD->hasAttr<StrictFPAttr>()) + if (FD->hasAttr<StrictFPAttr>() || + (getContext().getTranslationUnitDecl()->hasAttr<HLSLPreciseAttr>() && + CurFn->hasFnAttribute(llvm::Attribute::StrictFP))) // All calls within a strictfp function are marked strictfp Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::StrictFP); diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 61ca1904d52685..bc49559e53fccd 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -177,6 +177,52 @@ bool BackendConsumer::LinkInModules(llvm::Module *M) { } void BackendConsumer::HandleTranslationUnit(ASTContext &C) { + // If HLSL `precise` appears anywhere in the TU, compile the whole TU as if + // -ffp-model=strict (-Gis) had been specified. This is only sound because + // CodeGeneratorImpl defers all HLSL emission until HandleTranslationUnit; + // see DeferEmission in ModuleBuilder.cpp. + if (C.getTranslationUnitDecl()->hasAttr<HLSLPreciseAttr>() && + !Diags.hasErrorOccurred()) { + auto &Opts = CI.getLangOpts(); + bool SupportsStrictFP = CI.getTarget().hasStrictFP() || Opts.ExpStrictFP; + auto ExceptionMode = + SupportsStrictFP ? LangOptions::FPE_Strict : LangOptions::FPE_Ignore; + bool AlreadyStrict = + Opts.getDefaultFPContractMode() == LangOptions::FPM_Off && + Opts.getComplexRange() == LangOptions::CX_Full && + Opts.RoundingMath == SupportsStrictFP && + Opts.getFPExceptionMode() == ExceptionMode; + + // Match -Gis, including the target's existing strict-FP fallback. + // Sema has already consulted MathErrno (e.g. to mark libm builtins const). + // This is consistent because the HLSL driver already passes -fmath-errno by + // default; it has no effect on HLSL intrinsics. + Opts.MathErrno = true; + Opts.setDefaultFPContractMode(LangOptions::FPM_Off); + Opts.setComplexRange(LangOptions::CX_Full); + // HLSL enables -ffast-math by default; precise must not allow lossy FP + // optimizations, so clear it and every option it implies. + Opts.FastMath = false; + Opts.UnsafeFPMath = false; + Opts.AllowFPReassoc = false; + Opts.NoHonorNaNs = false; + Opts.NoHonorInfs = false; + Opts.NoSignedZero = false; + Opts.AllowRecip = false; + Opts.ApproxFunc = false; + if (!AlreadyStrict) { + Opts.RoundingMath = true; + Opts.setFPExceptionMode(LangOptions::FPE_Strict); + // Mirrors the fallback in CompilerInstance::createTarget. + if (!SupportsStrictFP) { + Diags.Report(diag::warn_fe_backend_unsupported_fp_rounding); + Opts.RoundingMath = false; + Diags.Report(diag::warn_fe_backend_unsupported_fp_exceptions); + Opts.setFPExceptionMode(LangOptions::FPE_Ignore); + } + } + } + { llvm::TimeTraceScope TimeScope("Frontend"); PrettyStackTraceString CrashInfo("Per-file LLVM IR generation"); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index e5bca359e6a855..92ef97fb1f1786 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1105,9 +1105,11 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, ToConstrainedExceptMD(getLangOpts().getDefaultExceptionMode()); Builder.setDefaultConstrainedRounding(RM); Builder.setDefaultConstrainedExcept(FPExceptionBehavior); + bool HLSLPrecise = + CGM.getContext().getTranslationUnitDecl()->hasAttr<HLSLPreciseAttr>(); if ((FD && (FD->UsesFPIntrin() || FD->hasAttr<StrictFPAttr>())) || - (!FD && (FPExceptionBehavior != llvm::fp::ebIgnore || - RM != llvm::RoundingMode::NearestTiesToEven))) { + ((!FD || HLSLPrecise) && (FPExceptionBehavior != llvm::fp::ebIgnore || + RM != llvm::RoundingMode::NearestTiesToEven))) { Builder.setIsFPConstrained(true); Fn->addFnAttr(llvm::Attribute::StrictFP); } diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index 0b00362487d2af..e015ff152dc76b 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -27,6 +27,7 @@ #include "llvm/IR/Module.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/VirtualFileSystem.h" +#include <functional> #include <memory> using namespace clang; @@ -66,6 +67,15 @@ namespace { std::unique_ptr<CodeGen::CodeGenModule> Builder; SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs; + // HLSL emission is deferred until HandleTranslationUnit so that it observes + // the final translation-unit-wide Sema state. In particular, if the + // `precise` keyword appears anywhere in the TU, the whole TU is compiled in + // strict FP mode (see BackendConsumer::HandleTranslationUnit). Because the + // keyword may appear after functions that would otherwise already have + // been emitted, every HLSL compile has to defer. + bool DeferEmission = false; + SmallVector<std::function<void()>, 8> DeferredCallbacks; + static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName, const CodeGenOptions &CGO) { if (ModuleName == "-" && !CGO.MainFileName.empty()) @@ -157,6 +167,7 @@ namespace { void Initialize(ASTContext &Context) override { Ctx = &Context; + DeferEmission = Context.getLangOpts().HLSL; M->setTargetTriple(Ctx->getTargetInfo().getTriple()); M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString()); @@ -182,6 +193,12 @@ namespace { if (Diags.hasErrorOccurred()) return; + if (DeferEmission) { + DeferredCallbacks.push_back( + [this, VD] { HandleCXXStaticMemberVarInstantiation(VD); }); + return; + } + Builder->HandleCXXStaticMemberVarInstantiation(VD); } @@ -194,6 +211,11 @@ namespace { if (Diags.hasUnrecoverableErrorOccurred()) return true; + if (DeferEmission) { + DeferredCallbacks.push_back([this, DG] { HandleTopLevelDecl(DG); }); + return true; + } + HandlingTopLevelDeclRAII HandlingDecl(*this); // Make sure to emit all elements of a Decl. @@ -220,6 +242,12 @@ namespace { if (Diags.hasUnrecoverableErrorOccurred()) return; + if (DeferEmission) { + DeferredCallbacks.push_back( + [this, D] { HandleInlineFunctionDefinition(D); }); + return; + } + assert(D->doesThisDeclarationHaveABody()); // We may want to emit this definition. However, that decision might be @@ -248,6 +276,11 @@ namespace { if (Diags.hasUnrecoverableErrorOccurred()) return; + if (DeferEmission) { + DeferredCallbacks.push_back([this, D] { HandleTagDeclDefinition(D); }); + return; + } + // Don't allow re-entrant calls to CodeGen triggered by PCH // deserialization to emit deferred decls. HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false); @@ -300,6 +333,12 @@ namespace { if (Diags.hasUnrecoverableErrorOccurred()) return; + if (DeferEmission) { + DeferredCallbacks.push_back( + [this, D] { HandleTagDeclRequiredDefinition(D); }); + return; + } + // Don't allow re-entrant calls to CodeGen triggered by PCH // deserialization to emit deferred decls. HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false); @@ -310,6 +349,14 @@ namespace { } void HandleTranslationUnit(ASTContext &Ctx) override { + // Replay in order before finalization. Callbacks triggered by replay, + // including AST deserialization, can now emit immediately. + DeferEmission = false; + if (!Diags.hasUnrecoverableErrorOccurred()) + for (auto &Callback : DeferredCallbacks) + Callback(); + DeferredCallbacks.clear(); + // Release the Builder when there is no error. if (!Diags.hasUnrecoverableErrorOccurred() && Builder) Builder->Release(); @@ -329,6 +376,11 @@ namespace { if (Diags.hasUnrecoverableErrorOccurred()) return; + if (DeferEmission) { + DeferredCallbacks.push_back([this, RD] { AssignInheritanceModel(RD); }); + return; + } + Builder->RefreshTypeCacheForClass(RD); } @@ -336,10 +388,22 @@ namespace { if (Diags.hasUnrecoverableErrorOccurred()) return; + if (DeferEmission) { + DeferredCallbacks.push_back( + [this, D] { CompleteTentativeDefinition(D); }); + return; + } + Builder->EmitTentativeDefinition(D); } void CompleteExternalDeclaration(DeclaratorDecl *D) override { + if (DeferEmission) { + DeferredCallbacks.push_back( + [this, D] { CompleteExternalDeclaration(D); }); + return; + } + Builder->EmitExternalDeclaration(D); } @@ -347,6 +411,11 @@ namespace { if (Diags.hasUnrecoverableErrorOccurred()) return; + if (DeferEmission) { + DeferredCallbacks.push_back([this, RD] { HandleVTable(RD); }); + return; + } + Builder->EmitVTable(RD); } }; diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 40249287184446..7482865e4b53ab 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4706,6 +4706,7 @@ void Parser::ParseDeclarationSpecifiers( case tok::kw_in: case tok::kw_inout: case tok::kw_out: + case tok::kw_precise: // NOTE: ParseHLSLQualifiers will consume the qualifier token. ParseHLSLQualifiers(DS.getAttributes()); continue; @@ -5879,6 +5880,7 @@ bool Parser::isTypeSpecifierQualifier(const Token &Tok) { case tok::kw_out: case tok::kw_row_major: case tok::kw_column_major: + case tok::kw_precise: return getLangOpts().HLSL; } } @@ -6161,6 +6163,7 @@ bool Parser::isDeclarationSpecifier( case tok::kw_groupshared: return true; + case tok::kw_precise: case tok::kw_nointerpolation: case tok::kw_linear: case tok::kw_centroid: @@ -6419,6 +6422,7 @@ void Parser::ParseTypeQualifierListOpt( case tok::kw_noperspective: case tok::kw_sample: case tok::kw_center: + case tok::kw_precise: // NOTE: ParseHLSLQualifiers will consume the qualifier token. ParseHLSLQualifiers(DS.getAttributes()); continue; diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index a4581538fbcec1..27a0ec79753e74 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -1286,7 +1286,7 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename, // OpenCL pipe case tok::kw_pipe: - // HLSL interpolation and address space qualifiers + // HLSL interpolation, address space qualifiers, and precise case tok::kw_nointerpolation: case tok::kw_linear: case tok::kw_centroid: @@ -1297,6 +1297,7 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename, case tok::kw_in: case tok::kw_inout: case tok::kw_out: + case tok::kw_precise: // HLSL matrix layout qualifiers case tok::kw_row_major: case tok::kw_column_major: diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 51506c62d4e35f..f1e6fa361aaa72 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -6495,9 +6495,13 @@ bool Sema::BuiltinUnorderedCompare(CallExpr *TheCall, unsigned BuiltinID) { return true; if (BuiltinID == Builtin::BI__builtin_isunordered && - TheCall->getFPFeaturesInEffect(getLangOpts()).getNoHonorNaNs()) - Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) - << 1 << 0 << TheCall->getSourceRange(); + TheCall->getFPFeaturesInEffect(getLangOpts()).getNoHonorNaNs()) { + if (getLangOpts().HLSL) + HLSL().deferFPNaNInfDiagnostic(TheCall, /*IsNaN=*/true); + else + Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) + << 1 << 0 << TheCall->getSourceRange(); + } ExprResult OrigArg0 = TheCall->getArg(0); ExprResult OrigArg1 = TheCall->getArg(1); @@ -6538,14 +6542,22 @@ bool Sema::BuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs, FPOptions FPO = TheCall->getFPFeaturesInEffect(getLangOpts()); if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite || BuiltinID == Builtin::BI__builtin_isinf || - BuiltinID == Builtin::BI__builtin_isinf_sign)) - Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) - << 0 << 0 << TheCall->getSourceRange(); + BuiltinID == Builtin::BI__builtin_isinf_sign)) { + if (getLangOpts().HLSL) + HLSL().deferFPNaNInfDiagnostic(TheCall, /*IsNaN=*/false); + else + Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) + << 0 << 0 << TheCall->getSourceRange(); + } if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan || - BuiltinID == Builtin::BI__builtin_isunordered)) - Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) - << 1 << 0 << TheCall->getSourceRange(); + BuiltinID == Builtin::BI__builtin_isunordered)) { + if (getLangOpts().HLSL) + HLSL().deferFPNaNInfDiagnostic(TheCall, /*IsNaN=*/true); + else + Diag(TheCall->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) + << 1 << 0 << TheCall->getSourceRange(); + } bool IsFPClass = NumArgs == 2; @@ -10779,8 +10791,11 @@ void Sema::CheckInfNaNFunction(const CallExpr *Call, if (FPO.getNoHonorNaNs() && (IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered") || IsInfOrNanFunction(FDecl->getName(), MathCheck::NaN))) { - Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) - << 1 << 0 << Call->getSourceRange(); + if (getLangOpts().HLSL) + HLSL().deferFPNaNInfDiagnostic(Call, /*IsNaN=*/true); + else + Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) + << 1 << 0 << Call->getSourceRange(); return; } @@ -10788,8 +10803,11 @@ void Sema::CheckInfNaNFunction(const CallExpr *Call, (IsStdFunction(FDecl, "isinf") || IsStdFunction(FDecl, "isfinite") || IsInfinityFunction(FDecl) || IsInfOrNanFunction(FDecl->getName(), MathCheck::Inf))) { - Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) - << 0 << 0 << Call->getSourceRange(); + if (getLangOpts().HLSL) + HLSL().deferFPNaNInfDiagnostic(Call, /*IsNaN=*/false); + else + Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) + << 0 << 0 << Call->getSourceRange(); } } diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 6205c705101592..f0240a7e7eb2cd 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -8337,6 +8337,9 @@ ProcessDeclAttribute(Sema &S, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_HLSLVkLocation: S.HLSL().handleVkLocationAttr(D, AL); break; + case P... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/234462 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
