From 7a4f21794e096d491cede831759a5db25763ffc9 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Thu, 20 Mar 2025 13:17:56 +0100 Subject: [PATCH 01/29] [SER] Generalize long vector diagnostics to HitObject - Generalize long vector diagnostics code to HitObjects. - Diagnose unsupported use of HitObject in globals, entry params/returns and various other shader-kind-specific contexts. - Create HitObject variants from the invalid-longvec-decls*.hlsl tests to make sure all cases are covered. Specification: https://github.com/microsoft/hlsl-specs/blob/main/proposals/0027-shader-execution-reordering.md Bug: #7234 [SER] Diagnose and validate illegal use of HitObject in unsupported contexts --- tools/clang/include/clang/AST/DeclCXX.h | 9 + .../clang/Basic/DiagnosticSemaKinds.td | 6 +- tools/clang/include/clang/Sema/SemaHLSL.h | 8 + tools/clang/lib/AST/DeclCXX.cpp | 9 +- tools/clang/lib/AST/HlslTypes.cpp | 3 + tools/clang/lib/Sema/SemaDXR.cpp | 6 +- tools/clang/lib/Sema/SemaDecl.cpp | 13 +- tools/clang/lib/Sema/SemaHLSL.cpp | 104 +++++--- tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp | 23 +- .../types/invalid-hitobject-decls-hs.hlsl | 24 ++ .../types/invalid-hitobject-decls-struct.hlsl | 238 ++++++++++++++++++ .../invalid-hitobject-decls-substruct.hlsl | 238 ++++++++++++++++++ .../invalid-hitobject-decls-template.hlsl | 238 ++++++++++++++++++ 13 files changed, 872 insertions(+), 47 deletions(-) create mode 100644 tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-hs.hlsl create mode 100644 tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl create mode 100644 tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl create mode 100644 tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-template.hlsl diff --git a/tools/clang/include/clang/AST/DeclCXX.h b/tools/clang/include/clang/AST/DeclCXX.h index 36e0f99c82..97e88ef10b 100644 --- a/tools/clang/include/clang/AST/DeclCXX.h +++ b/tools/clang/include/clang/AST/DeclCXX.h @@ -469,6 +469,10 @@ class CXXRecordDecl : public RecordDecl { /// class containing an HLSL vector longer than 4 elements. bool HasHLSLLongVector : 1; + /// \brief Whether this class contains at least one member or base + /// class containing an HLSL HitObject. + bool HasHLSLHitObject : 1; + /// \brief The number of base class specifiers in Bases. unsigned NumBases; @@ -1029,6 +1033,11 @@ class CXXRecordDecl : public RecordDecl { /// \brief Set that this class contains an HLSL long vector of over 4 elements bool setHasHLSLLongVector() { return data().HasHLSLLongVector = true; } + // \brief Determine whether this class contains an HLSL HitObject. + bool hasHLSLHitObject() { return data().HasHLSLHitObject; } + /// \brief Set that this class contains an HLSL HitObject. + bool setHasHLSLHitObject() { return data().HasHLSLHitObject = true; } + /// \brief Determine whether this class describes a lambda function object. bool isLambda() const { // An update record can't turn a non-lambda into a lambda. diff --git a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index ae7e777180..2112d8a9b0 100644 --- a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7878,14 +7878,14 @@ def err_hlsl_load_from_mesh_out_arrays: Error< "output arrays of a mesh shader can not be read from">; def err_hlsl_out_indices_array_incorrect_access: Error< "a vector in out indices array must be accessed as a whole">; -def err_hlsl_unsupported_long_vector - : Error<"vectors of over 4 elements in " +def err_hlsl_unsupported_type + : Error<"%select{vectors of over 4 elements|HitObjects}0 in " "%select{ConstantBuffers or TextureBuffers|" "tessellation patches|geometry streams|node records|" "cbuffers or tbuffers|user-defined struct parameter|" "entry function parameters|entry function return type|" "patch constant function parameters|patch constant function return type|" - "payload parameters|attributes}0 are not supported">; + "payload parameters|attributes}1 are not supported">; def err_hlsl_logical_binop_scalar : Error< "operands for short-circuiting logical binary operator must be scalar, for non-scalar types use '%select{and|or}0'">; def err_hlsl_ternary_scalar : Error< diff --git a/tools/clang/include/clang/Sema/SemaHLSL.h b/tools/clang/include/clang/Sema/SemaHLSL.h index 59d99ab4c5..8f21ceec65 100644 --- a/tools/clang/include/clang/Sema/SemaHLSL.h +++ b/tools/clang/include/clang/Sema/SemaHLSL.h @@ -129,6 +129,14 @@ unsigned CaculateInitListArraySizeForHLSL(clang::Sema *sema, const clang::QualType EltTy); bool ContainsLongVector(clang::QualType); +bool ContainsHitObject(clang::QualType); + +/// \brief Determine if the given type contains a long vector or a hit object. +/// \param QT The type to check. +/// \param DiagTypeIdx The index of the type in the diagnostic message. +/// \returns True if the type contains a long vector or a hit object, false +/// otherwise. +bool ContainsLongVecOrHitObject(clang::QualType QT, unsigned &DiagTypeIdx); bool IsConversionToLessOrEqualElements(clang::Sema *self, const clang::ExprResult &sourceExpr, diff --git a/tools/clang/lib/AST/DeclCXX.cpp b/tools/clang/lib/AST/DeclCXX.cpp index baed44667f..14cf7c208d 100644 --- a/tools/clang/lib/AST/DeclCXX.cpp +++ b/tools/clang/lib/AST/DeclCXX.cpp @@ -72,8 +72,9 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) ImplicitCopyAssignmentHasConstParam(true), HasDeclaredCopyConstructorWithConstParam(false), HasDeclaredCopyAssignmentWithConstParam(false), IsLambda(false), - IsParsingBaseSpecifiers(false), HasHLSLLongVector(false), NumBases(0), - NumVBases(0), Bases(), VBases(), Definition(D), FirstFriend() {} + IsParsingBaseSpecifiers(false), HasHLSLLongVector(false), + HasHLSLHitObject(false), NumBases(0), NumVBases(0), Bases(), VBases(), + Definition(D), FirstFriend() {} // HLSL Change End - Add HasLongVector and clang-format CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const { @@ -206,6 +207,8 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, // HLSL Change Begin - Propagate presence of long vector to child classes. if (BaseClassDecl->hasHLSLLongVector()) data().HasHLSLLongVector = true; + if (BaseClassDecl->hasHLSLHitObject()) + data().HasHLSLHitObject = true; // HLSL Change End // Record if this base is the first non-literal field or base. @@ -393,6 +396,8 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) { // HLSL Change Begin - Propagate presence of long vector to child classes. if (Subobj->hasHLSLLongVector()) data().HasHLSLLongVector = true; + if (Subobj->hasHLSLHitObject()) + data().HasHLSLHitObject = true; // HLSL Change End } diff --git a/tools/clang/lib/AST/HlslTypes.cpp b/tools/clang/lib/AST/HlslTypes.cpp index 5b19e064a3..0a7cf87ecd 100644 --- a/tools/clang/lib/AST/HlslTypes.cpp +++ b/tools/clang/lib/AST/HlslTypes.cpp @@ -25,6 +25,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Type.h" #include "clang/Sema/AttributeList.h" // conceptually ParsedAttributes +#include "clang/Sema/SemaHLSL.h" #include "llvm/ADT/StringSwitch.h" using namespace clang; @@ -124,6 +125,8 @@ bool IsHLSLNumericUserDefinedType(clang::QualType type) { // which can't be annotated. But includes UDTs of trivially copyable data and // the builtin trivially copyable raytracing structs. bool IsHLSLCopyableAnnotatableRecord(clang::QualType QT) { + if (ContainsHitObject(QT)) + return false; return IsHLSLNumericUserDefinedType(QT) || IsHLSLBuiltinRayAttributeStruct(QT); } diff --git a/tools/clang/lib/Sema/SemaDXR.cpp b/tools/clang/lib/Sema/SemaDXR.cpp index f0102f9e3f..fa87a3db5c 100644 --- a/tools/clang/lib/Sema/SemaDXR.cpp +++ b/tools/clang/lib/Sema/SemaDXR.cpp @@ -835,9 +835,11 @@ void DiagnoseBuiltinCallWithPayload(Sema &S, const VarDecl *Payload, } if (ContainsLongVector(Payload->getType())) { + // No need to check for HitObject, checked with payload diagnosis. + const unsigned LongVectorIdx = 0; const unsigned PayloadParametersIdx = 10; - S.Diag(Payload->getLocation(), diag::err_hlsl_unsupported_long_vector) - << PayloadParametersIdx; + S.Diag(Payload->getLocation(), diag::err_hlsl_unsupported_type) + << LongVectorIdx << PayloadParametersIdx; return; } diff --git a/tools/clang/lib/Sema/SemaDecl.cpp b/tools/clang/lib/Sema/SemaDecl.cpp index e09bf4623c..a3a597db42 100644 --- a/tools/clang/lib/Sema/SemaDecl.cpp +++ b/tools/clang/lib/Sema/SemaDecl.cpp @@ -13247,10 +13247,16 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, SmallVector RecFields; bool ARCErrReported = false; + bool HasHitObject = false; for (ArrayRef::iterator i = Fields.begin(), end = Fields.end(); i != end; ++i) { FieldDecl *FD = cast(*i); + // HLSL Change Begin - set HitObject bit for fields + if (!HasHitObject && hlsl::ContainsHitObject(FD->getType())) + HasHitObject = true; + // HLSL Change End + // Get the type for the field. const Type *FDTy = FD->getType().getTypePtr(); @@ -13439,7 +13445,12 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, I = CXXRecord->conversion_begin(), E = CXXRecord->conversion_end(); I != E; ++I) I.setAccess((*I)->getAccess()); - + + // HLSL Change Begin - set HitObject bit for fields + if (HasHitObject) + CXXRecord->setHasHLSLHitObject(); + // HLSL Change End + if (!CXXRecord->isDependentType()) { if (CXXRecord->hasUserDeclaredDestructor()) { // Adjust user-defined destructor exception spec. diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 6eadfeaac9..1be343a115 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -5533,10 +5533,11 @@ class HLSLExternalSource : public ExternalSemaSource { m_sema->RequireCompleteType(argSrcLoc, argType, diag::err_typecheck_decl_incomplete_type); - if (ContainsLongVector(argType)) { + unsigned DiagTypeIdx = 0; + if (hlsl::ContainsLongVecOrHitObject(argType, DiagTypeIdx)) { const unsigned ConstantBuffersOrTextureBuffersIdx = 0; - m_sema->Diag(argSrcLoc, diag::err_hlsl_unsupported_long_vector) - << ConstantBuffersOrTextureBuffersIdx; + m_sema->Diag(argSrcLoc, diag::err_hlsl_unsupported_type) + << DiagTypeIdx << ConstantBuffersOrTextureBuffersIdx; return true; } } @@ -5641,11 +5642,11 @@ class HLSLExternalSource : public ExternalSemaSource { CXXRecordDecl *Decl = arg.getAsType()->getAsCXXRecordDecl(); if (Decl && !Decl->isCompleteDefinition()) return true; - if (ContainsLongVector(arg.getAsType())) { + unsigned DiagTypeIdx = 0; + if (ContainsLongVecOrHitObject(arg.getAsType(), DiagTypeIdx)) { const unsigned TessellationPatchesIDx = 1; - m_sema->Diag(argLoc.getLocation(), - diag::err_hlsl_unsupported_long_vector) - << TessellationPatchesIDx; + m_sema->Diag(argLoc.getLocation(), diag::err_hlsl_unsupported_type) + << DiagTypeIdx << TessellationPatchesIDx; return true; } } else if (Template->getTemplatedDecl()->hasAttr()) { @@ -5660,11 +5661,11 @@ class HLSLExternalSource : public ExternalSemaSource { CXXRecordDecl *Decl = arg.getAsType()->getAsCXXRecordDecl(); if (Decl && !Decl->isCompleteDefinition()) return true; - if (ContainsLongVector(arg.getAsType())) { + unsigned DiagTypeIdx = 0; + if (ContainsLongVecOrHitObject(arg.getAsType(), DiagTypeIdx)) { const unsigned GeometryStreamsIdx = 2; - m_sema->Diag(argLoc.getLocation(), - diag::err_hlsl_unsupported_long_vector) - << GeometryStreamsIdx; + m_sema->Diag(argLoc.getLocation(), diag::err_hlsl_unsupported_type) + << DiagTypeIdx << GeometryStreamsIdx; return true; } } @@ -10779,8 +10780,11 @@ bool DiagnoseIntersectionAttributes(Sema &S, SourceLocation Loc, QualType Ty) { } if (ContainsLongVector(Ty)) { + // No need to check for HitObject, checked with attributes diagnosis. + const unsigned LongVectorIdx = 0; const unsigned AttributesIdx = 11; - S.Diag(Loc, diag::err_hlsl_unsupported_long_vector) << AttributesIdx; + S.Diag(Loc, diag::err_hlsl_unsupported_type) + << LongVectorIdx << AttributesIdx; return false; } return true; @@ -12119,9 +12123,10 @@ bool hlsl::DiagnoseNodeStructArgument(Sema *self, TemplateArgumentLoc ArgLoc, switch (shapeKind) { case AR_TOBJ_VECTOR: if (GetHLSLVecSize(ArgTy) > DXIL::kDefaultMaxVectorLength) { + const unsigned LongVectorIdx = 0; const unsigned NodeRecordsIdx = 3; - self->Diag(ArgLoc.getLocation(), diag::err_hlsl_unsupported_long_vector) - << NodeRecordsIdx; + self->Diag(ArgLoc.getLocation(), diag::err_hlsl_unsupported_type) + << LongVectorIdx << NodeRecordsIdx; Empty = false; return false; } @@ -12591,6 +12596,24 @@ bool hlsl::ShouldSkipNRVO(clang::Sema &sema, clang::QualType returnType, return false; } +bool hlsl::ContainsHitObject(QualType QT) { + if (QT.isNull() || QT->isDependentType()) + return false; + + while (const ArrayType *Arr = QT->getAsArrayTypeUnsafe()) + QT = Arr->getElementType(); + + if (IsHLSLHitObjectType(QT)) + return true; + + if (CXXRecordDecl *Decl = QT->getAsCXXRecordDecl()) { + if (!Decl->isCompleteDefinition()) + return false; + return Decl->hasHLSLHitObject(); + } + return false; +} + bool hlsl::ContainsLongVector(QualType QT) { if (QT.isNull() || QT->isDependentType()) return false; @@ -12606,6 +12629,19 @@ bool hlsl::ContainsLongVector(QualType QT) { return false; } +bool hlsl::ContainsLongVecOrHitObject(clang::QualType QT, + unsigned &DiagTypeIdx) { + if (ContainsHitObject(QT)) { + DiagTypeIdx = 1; + return true; + } + if (ContainsLongVector(QT)) { + DiagTypeIdx = 0; + return true; + } + return false; +} + bool hlsl::IsConversionToLessOrEqualElements( clang::Sema *self, const clang::ExprResult &sourceExpr, const clang::QualType &targetType, bool explicitConversion) { @@ -15277,7 +15313,8 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth, } // Disallow long vecs from $Global cbuffers. - if (isGlobal && !isStatic && !isGroupShared && !IS_BASIC_OBJECT(basicKind)) { + const unsigned CbuffersOrTbuffersIdx = 4; + if (isGlobal && !isStatic) { // Suppress actual emitting of errors for incompletable types here // They are redundant to those produced in ActOnUninitializedDecl. struct SilentDiagnoser : public TypeDiagnoser { @@ -15285,10 +15322,18 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth, virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {} } SD; RequireCompleteType(D.getLocStart(), qt, SD); - if (ContainsLongVector(qt)) { - unsigned CbuffersOrTbuffersIdx = 4; - Diag(D.getLocStart(), diag::err_hlsl_unsupported_long_vector) - << CbuffersOrTbuffersIdx; + unsigned DiagTypeIdx = 0; + bool HasError = false; + if (!isGroupShared && !IS_BASIC_OBJECT(basicKind) && ContainsLongVector(qt)) + HasError = true; + else if (ContainsHitObject(qt)) { + const unsigned HitObjectTypeIdx = 1; + DiagTypeIdx = HitObjectTypeIdx; + HasError = true; + } + if (HasError) { + Diag(D.getLocStart(), diag::err_hlsl_unsupported_type) + << DiagTypeIdx << CbuffersOrTbuffersIdx; result = false; } } @@ -16195,10 +16240,11 @@ static bool isRelatedDeclMarkedNointerpolation(Expr *E) { // Verify that user-defined intrinsic struct args contain no long vectors static bool CheckUDTIntrinsicArg(Sema *S, Expr *Arg) { - if (ContainsLongVector(Arg->getType())) { + unsigned DiagTypeIdx = 0; + if (ContainsLongVecOrHitObject(Arg->getType(), DiagTypeIdx)) { const unsigned UserDefinedStructParameterIdx = 5; - S->Diag(Arg->getExprLoc(), diag::err_hlsl_unsupported_long_vector) - << UserDefinedStructParameterIdx; + S->Diag(Arg->getExprLoc(), diag::err_hlsl_unsupported_type) + << DiagTypeIdx << UserDefinedStructParameterIdx; return true; } return false; @@ -16938,17 +16984,19 @@ void DiagnoseEntry(Sema &S, FunctionDecl *FD) { // Would be nice to check for resources here as they crash the compiler now. // See issue #7186. for (const auto *param : FD->params()) { - if (ContainsLongVector(param->getType())) { + unsigned DiagTypeIdx = 0; + if (ContainsLongVecOrHitObject(param->getType(), DiagTypeIdx)) { const unsigned EntryFunctionParametersIdx = 6; - S.Diag(param->getLocation(), diag::err_hlsl_unsupported_long_vector) - << EntryFunctionParametersIdx; + S.Diag(param->getLocation(), diag::err_hlsl_unsupported_type) + << DiagTypeIdx << EntryFunctionParametersIdx; } } - if (ContainsLongVector(FD->getReturnType())) { + unsigned DiagTypeIdx = 0; + if (ContainsLongVecOrHitObject(FD->getReturnType(), DiagTypeIdx)) { const unsigned EntryFunctionReturnIdx = 7; - S.Diag(FD->getLocation(), diag::err_hlsl_unsupported_long_vector) - << EntryFunctionReturnIdx; + S.Diag(FD->getLocation(), diag::err_hlsl_unsupported_type) + << DiagTypeIdx << EntryFunctionReturnIdx; } DXIL::ShaderKind Stage = diff --git a/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp b/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp index abca7cbf86..c8ad298081 100644 --- a/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp +++ b/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp @@ -709,19 +709,20 @@ void hlsl::DiagnoseTranslationUnit(clang::Sema *self) { << hullPatchCount.value(); } } - for (const auto *param : pPatchFnDecl->params()) - if (ContainsLongVector(param->getType())) { - const unsigned PatchConstantFunctionParametersIdx = 8; - self->Diag(param->getLocation(), - diag::err_hlsl_unsupported_long_vector) - << PatchConstantFunctionParametersIdx; - } + for (const auto *param : pPatchFnDecl->params()) { + unsigned TypeDiagIdx = 0; + const unsigned PatchConstantFunctionParametersIdx = 8; + if (ContainsLongVecOrHitObject(param->getType(), TypeDiagIdx)) + self->Diag(param->getLocation(), diag::err_hlsl_unsupported_type) + << TypeDiagIdx << PatchConstantFunctionParametersIdx; + } - if (ContainsLongVector(pPatchFnDecl->getReturnType())) { + unsigned TypeDiagIdx = 0; + if (ContainsLongVecOrHitObject(pPatchFnDecl->getReturnType(), + TypeDiagIdx)) { const unsigned PatchConstantFunctionReturnIdx = 9; - self->Diag(pPatchFnDecl->getLocation(), - diag::err_hlsl_unsupported_long_vector) - << PatchConstantFunctionReturnIdx; + self->Diag(pPatchFnDecl->getLocation(), diag::err_hlsl_unsupported_type) + << TypeDiagIdx << PatchConstantFunctionReturnIdx; } } DXIL::ShaderKind EntrySK = shaderModel->GetKind(); diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-hs.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-hs.hlsl new file mode 100644 index 0000000000..6020594a69 --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-hs.hlsl @@ -0,0 +1,24 @@ +// RUN: %dxc -DTYPE=float -T hs_6_9 -verify %s + +struct HsConstantData { + float Edges[3] : SV_TessFactor; + dx::HitObject hit; +}; + +struct LongVec { + float4 f; + dx::HitObject hit; +}; + +HsConstantData PatchConstantFunction( // expected-error{{HitObjects in patch constant function return type are not supported}} + dx::HitObject hit : V, // expected-error{{HitObjects in patch constant function parameters are not supported}} + LongVec lv : L) { // expected-error{{HitObjects in patch constant function parameters are not supported}} + return (HsConstantData)0; +} + +[domain("tri")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(32)] +[patchconstantfunc("PatchConstantFunction")] +void main() { +} diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl new file mode 100644 index 0000000000..ed4b03280a --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl @@ -0,0 +1,238 @@ +// RUN: %dxc -T lib_6_9 -DTYPE=HitStruct -verify %s + +#define PASTE_(x,y) x##y +#define PASTE(x,y) PASTE_(x,y) + +#ifndef TYPE +#define TYPE HitTpl +#endif + +// Add tests for base types and instantiated template classes with HitObjects + +struct HitStruct { + float4 f; + dx::HitObject hit; +}; + +struct HitStructSub : HitStruct { + int3 is; +}; + +template +struct HitTpl { + float4 f; + T val; +}; + +dx::HitObject global_hit; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} +dx::HitObject global_hit_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + +cbuffer BadBuffy { + dx::HitObject cb_hit; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + dx::HitObject cb_hit_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} +}; + +tbuffer BadTuffy { + dx::HitObject tb_vec; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + dx::HitObject tb_vec_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + TYPE tb_vec_rec; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + TYPE tb_vec_rec_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} +}; + +ConstantBuffer const_buf; // expected-error{{HitObjects in ConstantBuffers or TextureBuffers are not supported}} +TextureBuffer tex_buf; // expected-error{{HitObjects in ConstantBuffers or TextureBuffers are not supported}} + +[shader("pixel")] +TYPE main( // expected-error{{HitObjects in entry function return type are not supported}} + TYPE vec : V) : SV_Target { // expected-error{{HitObjects in entry function parameters are not supported}} + return vec; +} + +[shader("vertex")] +TYPE vs_main( // expected-error{{HitObjects in entry function return type are not supported}} + TYPE parm : P) : SV_Target { // expected-error{{HitObjects in entry function parameters are not supported}} + parm.f = 0; + return parm; +} + + +[shader("geometry")] +[maxvertexcount(3)] +void gs_point( + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + line TYPE e, + // expected-error@+1{{HitObjects in geometry streams are not supported}} + inout PointStream OutputStream0) {} + +[shader("geometry")] +[maxvertexcount(12)] +void gs_line( + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + line TYPE a, + // expected-error@+1{{HitObjects in geometry streams are not supported}} + inout LineStream OutputStream0) {} + + +[shader("geometry")] +[maxvertexcount(12)] +void gs_line( + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + line TYPE a, + // expected-error@+1{{HitObjects in geometry streams are not supported}} + inout TriangleStream OutputStream0) {} + +[shader("domain")] +[domain("tri")] +void ds_main( + // expected-error@+1{{HitObjects in tessellation patches are not supported}} + OutputPatch TrianglePatch) {} + +void patch_const( + // expected-error@+1{{HitObjects in tessellation patches are not supported}} + InputPatch inpatch, + // expected-error@+1{{HitObjects in tessellation patches are not supported}} + OutputPatch outpatch) {} + +[shader("hull")] +[domain("tri")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(32)] +[patchconstantfunc("patch_const")] +// expected-error@+1{{HitObjects in tessellation patches are not supported}} +void hs_main(InputPatch TrianglePatch) {} + +RaytracingAccelerationStructure RTAS; + +struct [raypayload] DXRHitStruct { + float4 f : write(closesthit) : read(caller); + TYPE hit : write(closesthit) : read(caller); +}; + +struct [raypayload] DXRHitStructSub : DXRHitStruct { + int3 is : write(closesthit) : read(caller); +}; + +template +struct [raypayload] DXRHitTpl { + float4 f : write(closesthit) : read(caller); + T hit : write(closesthit) : read(caller); +}; + +#define RTTYPE PASTE(DXR,TYPE) + +[shader("raygeneration")] +void raygen() { + RTTYPE p = (RTTYPE)0; + RayDesc ray = (RayDesc)0; + TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + CallShader(0, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +[shader("closesthit")] +void closesthit( + // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-note@14{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + inout RTTYPE payload, + // expected-error@+3{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} + // expected-note@14{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + in RTTYPE attribs) { + RayDesc ray; + TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + CallShader(0, payload); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +[shader("anyhit")] +void AnyHit( + // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-note@14{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + inout RTTYPE payload, + // expected-error@+3{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} + // expected-note@14{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + in RTTYPE attribs) +{ +} + +[shader("miss")] +void Miss( + // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-note@14{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + inout RTTYPE payload){ + RayDesc ray; + TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + CallShader(0, payload); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +[shader("intersection")] +void Intersection() { + float hitT = RayTCurrent(); + RTTYPE attr = (RTTYPE)0; + bool bReported = ReportHit(hitT, 0, attr); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +[shader("callable")] +void callable1( + // expected-error@+3{{callable parameter 'p' must be a user-defined type composed of only numeric types}} + // expected-note@14{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + inout RTTYPE p) { + CallShader(0, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +groupshared TYPE as_pld; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + +[shader("amplification")] +[numthreads(1,1,1)] +void Amp() { + TYPE as_pld; + DispatchMesh(1,1,1,as_pld); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +struct NodeHitStruct { + uint3 grid : SV_DispatchGrid; + TYPE hit; +}; + +struct NodeHitStructSub : NodeHitStruct { + int3 is; +}; + +template +struct NodeHitTpl { + uint3 grid : SV_DispatchGrid; + T hit; +}; + +#define NTYPE PASTE(Node,TYPE) + +[Shader("node")] +[NodeLaunch("broadcasting")] +[NumThreads(8,1,1)] +[NodeMaxDispatchGrid(8, 1, 1)] +// Below error raised because the constructed node input record is invalid. Could be improved. +// expected-error@+1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} +void broadcast( + // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} + DispatchNodeInputRecord input, + // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} + NodeOutput output) +{ + ThreadNodeOutputRecords touts; // expected-error{{object 'dx::HitObject' may not appear in a node record}} + GroupNodeOutputRecords gouts; // expected-error{{object 'dx::HitObject' may not appear in a node record}} +} + +[Shader("node")] +[NodeLaunch("coalescing")] +[NumThreads(8,1,1)] +void coalesce( + // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} + GroupNodeInputRecords input) {} + +[Shader("node")] +[NodeLaunch("thread")] +// expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} +void threader(ThreadNodeInputRecord input) {} diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl new file mode 100644 index 0000000000..04e9f69939 --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl @@ -0,0 +1,238 @@ +// RUN: %dxc -T lib_6_9 -DTYPE=HitStructSub -verify %s + +#define PASTE_(x,y) x##y +#define PASTE(x,y) PASTE_(x,y) + +#ifndef TYPE +#define TYPE HitTpl +#endif + +// Add tests for base types and instantiated template classes with HitObjects + +struct HitStruct { + float4 f; + dx::HitObject hit; +}; + +struct HitStructSub : HitStruct { + int3 is; +}; + +template +struct HitTpl { + float4 f; + T val; +}; + +dx::HitObject global_hit; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} +dx::HitObject global_hit_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + +cbuffer BadBuffy { + dx::HitObject cb_hit; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + dx::HitObject cb_hit_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} +}; + +tbuffer BadTuffy { + dx::HitObject tb_vec; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + dx::HitObject tb_vec_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + TYPE tb_vec_rec; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + TYPE tb_vec_rec_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} +}; + +ConstantBuffer const_buf; // expected-error{{HitObjects in ConstantBuffers or TextureBuffers are not supported}} +TextureBuffer tex_buf; // expected-error{{HitObjects in ConstantBuffers or TextureBuffers are not supported}} + +[shader("pixel")] +TYPE main( // expected-error{{HitObjects in entry function return type are not supported}} + TYPE vec : V) : SV_Target { // expected-error{{HitObjects in entry function parameters are not supported}} + return vec; +} + +[shader("vertex")] +TYPE vs_main( // expected-error{{HitObjects in entry function return type are not supported}} + TYPE parm : P) : SV_Target { // expected-error{{HitObjects in entry function parameters are not supported}} + parm.f = 0; + return parm; +} + + +[shader("geometry")] +[maxvertexcount(3)] +void gs_point( + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + line TYPE e, + // expected-error@+1{{HitObjects in geometry streams are not supported}} + inout PointStream OutputStream0) {} + +[shader("geometry")] +[maxvertexcount(12)] +void gs_line( + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + line TYPE a, + // expected-error@+1{{HitObjects in geometry streams are not supported}} + inout LineStream OutputStream0) {} + + +[shader("geometry")] +[maxvertexcount(12)] +void gs_line( + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + line TYPE a, + // expected-error@+1{{HitObjects in geometry streams are not supported}} + inout TriangleStream OutputStream0) {} + +[shader("domain")] +[domain("tri")] +void ds_main( + // expected-error@+1{{HitObjects in tessellation patches are not supported}} + OutputPatch TrianglePatch) {} + +void patch_const( + // expected-error@+1{{HitObjects in tessellation patches are not supported}} + InputPatch inpatch, + // expected-error@+1{{HitObjects in tessellation patches are not supported}} + OutputPatch outpatch) {} + +[shader("hull")] +[domain("tri")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(32)] +[patchconstantfunc("patch_const")] +// expected-error@+1{{HitObjects in tessellation patches are not supported}} +void hs_main(InputPatch TrianglePatch) {} + +RaytracingAccelerationStructure RTAS; + +struct [raypayload] DXRHitStruct { + float4 f : write(closesthit) : read(caller); + TYPE hit : write(closesthit) : read(caller); +}; + +struct [raypayload] DXRHitStructSub : DXRHitStruct { + int3 is : write(closesthit) : read(caller); +}; + +template +struct [raypayload] DXRHitTpl { + float4 f : write(closesthit) : read(caller); + T hit : write(closesthit) : read(caller); +}; + +#define RTTYPE PASTE(DXR,TYPE) + +[shader("raygeneration")] +void raygen() { + RTTYPE p = (RTTYPE)0; + RayDesc ray = (RayDesc)0; + TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + CallShader(0, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +[shader("closesthit")] +void closesthit( + // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-note@14{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + inout RTTYPE payload, + // expected-error@+3{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} + // expected-note@14{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + in RTTYPE attribs) { + RayDesc ray; + TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + CallShader(0, payload); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +[shader("anyhit")] +void AnyHit( + // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-note@14{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + inout RTTYPE payload, + // expected-error@+3{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} + // expected-note@14{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + in RTTYPE attribs) +{ +} + +[shader("miss")] +void Miss( + // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-note@14{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + inout RTTYPE payload){ + RayDesc ray; + TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + CallShader(0, payload); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +[shader("intersection")] +void Intersection() { + float hitT = RayTCurrent(); + RTTYPE attr = (RTTYPE)0; + bool bReported = ReportHit(hitT, 0, attr); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +[shader("callable")] +void callable1( + // expected-error@+3{{callable parameter 'p' must be a user-defined type composed of only numeric types}} + // expected-note@14{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + inout RTTYPE p) { + CallShader(0, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +groupshared TYPE as_pld; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + +[shader("amplification")] +[numthreads(1,1,1)] +void Amp() { + TYPE as_pld; + DispatchMesh(1,1,1,as_pld); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +struct NodeHitStruct { + uint3 grid : SV_DispatchGrid; + TYPE hit; +}; + +struct NodeHitStructSub : NodeHitStruct { + int3 is; +}; + +template +struct NodeHitTpl { + uint3 grid : SV_DispatchGrid; + T hit; +}; + +#define NTYPE PASTE(Node,TYPE) + +[Shader("node")] +[NodeLaunch("broadcasting")] +[NumThreads(8,1,1)] +[NodeMaxDispatchGrid(8, 1, 1)] +// Below error raised because the constructed node input record is invalid. Could be improved. +// expected-error@+1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} +void broadcast( + // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} + DispatchNodeInputRecord input, + // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} + NodeOutput output) +{ + ThreadNodeOutputRecords touts; // expected-error{{object 'dx::HitObject' may not appear in a node record}} + GroupNodeOutputRecords gouts; // expected-error{{object 'dx::HitObject' may not appear in a node record}} +} + +[Shader("node")] +[NodeLaunch("coalescing")] +[NumThreads(8,1,1)] +void coalesce( + // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} + GroupNodeInputRecords input) {} + +[Shader("node")] +[NodeLaunch("thread")] +// expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} +void threader(ThreadNodeInputRecord input) {} diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-template.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-template.hlsl new file mode 100644 index 0000000000..95d25d4c82 --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-template.hlsl @@ -0,0 +1,238 @@ +// RUN: %dxc -T lib_6_9 -verify %s + +#define PASTE_(x,y) x##y +#define PASTE(x,y) PASTE_(x,y) + +#ifndef TYPE +#define TYPE HitTpl +#endif + +// Add tests for base types and instantiated template classes with HitObjects + +struct HitStruct { + float4 f; + dx::HitObject hit; +}; + +struct HitStructSub : HitStruct { + int3 is; +}; + +template +struct HitTpl { + float4 f; + T val; +}; + +dx::HitObject global_hit; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} +dx::HitObject global_hit_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + +cbuffer BadBuffy { + dx::HitObject cb_hit; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + dx::HitObject cb_hit_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} +}; + +tbuffer BadTuffy { + dx::HitObject tb_vec; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + dx::HitObject tb_vec_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + TYPE tb_vec_rec; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + TYPE tb_vec_rec_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} +}; + +ConstantBuffer const_buf; // expected-error{{HitObjects in ConstantBuffers or TextureBuffers are not supported}} +TextureBuffer tex_buf; // expected-error{{HitObjects in ConstantBuffers or TextureBuffers are not supported}} + +[shader("pixel")] +TYPE main( // expected-error{{HitObjects in entry function return type are not supported}} + TYPE vec : V) : SV_Target { // expected-error{{HitObjects in entry function parameters are not supported}} + return vec; +} + +[shader("vertex")] +TYPE vs_main( // expected-error{{HitObjects in entry function return type are not supported}} + TYPE parm : P) : SV_Target { // expected-error{{HitObjects in entry function parameters are not supported}} + parm.f = 0; + return parm; +} + + +[shader("geometry")] +[maxvertexcount(3)] +void gs_point( + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + line TYPE e, + // expected-error@+1{{HitObjects in geometry streams are not supported}} + inout PointStream OutputStream0) {} + +[shader("geometry")] +[maxvertexcount(12)] +void gs_line( + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + line TYPE a, + // expected-error@+1{{HitObjects in geometry streams are not supported}} + inout LineStream OutputStream0) {} + + +[shader("geometry")] +[maxvertexcount(12)] +void gs_line( + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + line TYPE a, + // expected-error@+1{{HitObjects in geometry streams are not supported}} + inout TriangleStream OutputStream0) {} + +[shader("domain")] +[domain("tri")] +void ds_main( + // expected-error@+1{{HitObjects in tessellation patches are not supported}} + OutputPatch TrianglePatch) {} + +void patch_const( + // expected-error@+1{{HitObjects in tessellation patches are not supported}} + InputPatch inpatch, + // expected-error@+1{{HitObjects in tessellation patches are not supported}} + OutputPatch outpatch) {} + +[shader("hull")] +[domain("tri")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(32)] +[patchconstantfunc("patch_const")] +// expected-error@+1{{HitObjects in tessellation patches are not supported}} +void hs_main(InputPatch TrianglePatch) {} + +RaytracingAccelerationStructure RTAS; + +struct [raypayload] DXRHitStruct { + float4 f : write(closesthit) : read(caller); + TYPE hit : write(closesthit) : read(caller); +}; + +struct [raypayload] DXRHitStructSub : DXRHitStruct { + int3 is : write(closesthit) : read(caller); +}; + +template +struct [raypayload] DXRHitTpl { + float4 f : write(closesthit) : read(caller); + T hit : write(closesthit) : read(caller); +}; + +#define RTTYPE PASTE(DXR,TYPE) + +[shader("raygeneration")] +void raygen() { + RTTYPE p = (RTTYPE)0; + RayDesc ray = (RayDesc)0; + TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + CallShader(0, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +[shader("closesthit")] +void closesthit( + // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-note@24{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + inout RTTYPE payload, + // expected-error@+3{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} + // expected-note@24{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + in RTTYPE attribs) { + RayDesc ray; + TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + CallShader(0, payload); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +[shader("anyhit")] +void AnyHit( + // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-note@24{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + inout RTTYPE payload, + // expected-error@+3{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} + // expected-note@24{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + in RTTYPE attribs) +{ +} + +[shader("miss")] +void Miss( + // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-note@24{{'dx::HitObject' field declared here}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + inout RTTYPE payload){ + RayDesc ray; + TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + CallShader(0, payload); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +[shader("intersection")] +void Intersection() { + float hitT = RayTCurrent(); + RTTYPE attr = (RTTYPE)0; + bool bReported = ReportHit(hitT, 0, attr); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +[shader("callable")] +void callable1( + // expected-error@+2{{callable parameter 'p' must be a user-defined type composed of only numeric types}} + // expected-error@+1{{HitObjects in entry function parameters are not supported}} + inout RTTYPE p) { + CallShader(0, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +groupshared TYPE as_pld; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + +[shader("amplification")] +[numthreads(1,1,1)] +void Amp() { + TYPE as_pld; + DispatchMesh(1,1,1,as_pld); // expected-error{{HitObjects in user-defined struct parameter are not supported}} +} + +struct NodeHitStruct { + uint3 grid : SV_DispatchGrid; + TYPE hit; +}; + +struct NodeHitStructSub : NodeHitStruct { + int3 is; +}; + +template +struct NodeHitTpl { + uint3 grid : SV_DispatchGrid; + T hit; +}; + +#define NTYPE PASTE(Node,TYPE) + +[Shader("node")] +[NodeLaunch("broadcasting")] +[NumThreads(8,1,1)] +[NodeMaxDispatchGrid(8, 1, 1)] +// Below error raised because the constructed node input record is invalid. Could be improved. +// expected-error@+1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} +void broadcast( + // expected-error@+2{{object 'dx::HitObject' may not appear in a node record}} + // expected-note@206{{'dx::HitObject' field declared here}} + DispatchNodeInputRecord input, + // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} + NodeOutput output) +{ + ThreadNodeOutputRecords touts; // expected-error{{object 'dx::HitObject' may not appear in a node record}} + GroupNodeOutputRecords gouts; // expected-error{{object 'dx::HitObject' may not appear in a node record}} +} + +[Shader("node")] +[NodeLaunch("coalescing")] +[NumThreads(8,1,1)] +void coalesce( + // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} + GroupNodeInputRecords input) {} + +[Shader("node")] +[NodeLaunch("thread")] +// expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} +void threader(ThreadNodeInputRecord input) {} From 57ff5a38b07fda82fb41b335ff0eb1a4bd5425aa Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Wed, 30 Apr 2025 13:21:47 +0200 Subject: [PATCH 02/29] Split-off from LongVector diagnostics / Fold err_hlsl_node_record_object and err_hlsl_objectintemplateargument --- tools/clang/include/clang/AST/DeclCXX.h | 9 - .../clang/Basic/DiagnosticSemaKinds.td | 19 +- tools/clang/include/clang/Sema/SemaHLSL.h | 31 +- tools/clang/lib/AST/DeclCXX.cpp | 9 +- tools/clang/lib/AST/HlslTypes.cpp | 7 +- tools/clang/lib/Sema/SemaDXR.cpp | 9 +- tools/clang/lib/Sema/SemaDecl.cpp | 13 +- tools/clang/lib/Sema/SemaHLSL.cpp | 264 ++++++++------ tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp | 22 +- .../HitObject/hitobject-in-buffer.hlsl | 2 +- .../hitobject_traceinvoke_payload_udt.hlsl | 3 +- .../types/invalid-hitobject-decls-hs.hlsl | 18 +- .../types/invalid-hitobject-decls-struct.hlsl | 244 +++++++++---- .../invalid-hitobject-decls-substruct.hlsl | 238 ------------- .../invalid-hitobject-decls-template.hlsl | 238 ------------- .../invalid-hitobject-decls-templated.hlsl | 337 ++++++++++++++++++ .../workgraph/invalid_node_record_type.hlsl | 14 +- .../clang/test/SemaHLSL/template-checks.hlsl | 6 +- 18 files changed, 758 insertions(+), 725 deletions(-) delete mode 100644 tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl delete mode 100644 tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-template.hlsl create mode 100644 tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl diff --git a/tools/clang/include/clang/AST/DeclCXX.h b/tools/clang/include/clang/AST/DeclCXX.h index 97e88ef10b..36e0f99c82 100644 --- a/tools/clang/include/clang/AST/DeclCXX.h +++ b/tools/clang/include/clang/AST/DeclCXX.h @@ -469,10 +469,6 @@ class CXXRecordDecl : public RecordDecl { /// class containing an HLSL vector longer than 4 elements. bool HasHLSLLongVector : 1; - /// \brief Whether this class contains at least one member or base - /// class containing an HLSL HitObject. - bool HasHLSLHitObject : 1; - /// \brief The number of base class specifiers in Bases. unsigned NumBases; @@ -1033,11 +1029,6 @@ class CXXRecordDecl : public RecordDecl { /// \brief Set that this class contains an HLSL long vector of over 4 elements bool setHasHLSLLongVector() { return data().HasHLSLLongVector = true; } - // \brief Determine whether this class contains an HLSL HitObject. - bool hasHLSLHitObject() { return data().HasHLSLHitObject; } - /// \brief Set that this class contains an HLSL HitObject. - bool setHasHLSLHitObject() { return data().HasHLSLHitObject = true; } - /// \brief Determine whether this class describes a lambda function object. bool isLambda() const { // An update record can't turn a non-lambda into a lambda. diff --git a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index 2112d8a9b0..1dba16ffeb 100644 --- a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7558,8 +7558,6 @@ def err_hlsl_missing_type_specifier : Error< // Patterened after err_missing_typ "HLSL requires a type specifier for all declarations">; def err_hlsl_multiple_concrete_bases : Error< "multiple concrete base types specified">; -def err_hlsl_objectintemplateargument : Error< - "%0 is an object and cannot be used as a type parameter">; def err_hlsl_packoffset_requires_cbuffer : Error< "packoffset is only allowed in a constant buffer">; def warn_hlsl_packoffset_mix : Warning< @@ -7878,14 +7876,23 @@ def err_hlsl_load_from_mesh_out_arrays: Error< "output arrays of a mesh shader can not be read from">; def err_hlsl_out_indices_array_incorrect_access: Error< "a vector in out indices array must be accessed as a whole">; -def err_hlsl_unsupported_type - : Error<"%select{vectors of over 4 elements|HitObjects}0 in " +def err_hlsl_unsupported_long_vector + : Error<"vectors of over 4 elements in " "%select{ConstantBuffers or TextureBuffers|" "tessellation patches|geometry streams|node records|" "cbuffers or tbuffers|user-defined struct parameter|" "entry function parameters|entry function return type|" "patch constant function parameters|patch constant function return type|" - "payload parameters|attributes}1 are not supported">; + "payload parameters|attributes}0 are not supported">; +// %select options must be compatible with err_hlsl_unsupported_long_vector (same index used) +def err_hlsl_unsupported_object_context + : Error<"object '%0' is not allowed in " + "%select{ConstantBuffers or TextureBuffers|" + "tessellation patches|geometry streams|node records|" + "cbuffers or tbuffers|user-defined struct parameter|" + "entry function parameters|entry function return type|" + "patch constant function parameters|patch constant function return type|" + "payload parameters|attributes|type parameters|structured buffers|global variables|groupshared variables}1">; def err_hlsl_logical_binop_scalar : Error< "operands for short-circuiting logical binary operator must be scalar, for non-scalar types use '%select{and|or}0'">; def err_hlsl_ternary_scalar : Error< @@ -7970,8 +7977,6 @@ def err_hlsl_too_many_node_inputs : Error< "Node shader '%0' may not have more than one input record">; def err_hlsl_node_record_type : Error< "%0 is not valid as a node record type - struct/class required">; -def err_hlsl_node_record_object : Error< - "object %0 may not appear in a node record">; def err_hlsl_array_disallowed : Error< "%select{entry parameter|declaration}1 of type %0 may not be an array">; def err_hlsl_inputpatch_size: Error< diff --git a/tools/clang/include/clang/Sema/SemaHLSL.h b/tools/clang/include/clang/Sema/SemaHLSL.h index 8f21ceec65..c40cd48754 100644 --- a/tools/clang/include/clang/Sema/SemaHLSL.h +++ b/tools/clang/include/clang/Sema/SemaHLSL.h @@ -59,6 +59,29 @@ bool DiagnoseNodeStructArgument(clang::Sema *self, clang::QualType ArgTy, bool &Empty, const clang::FieldDecl *FD = nullptr); +// Keep this in sync with err_hlsl_unsupported_object in DiagnosticSemaKinds.td +enum class TypeDiagContext { + ConstantBuffersOrTextureBuffers = 0, + TessellationPatches = 1, + GeometryStreams = 2, + NodeRecords = 3, + CBuffersOrTBuffers = 4, + UserDefinedStructParameter = 5, + EntryFunctionParameters = 6, + EntryFunctionReturnType = 7, + PatchConstantFunctionParameters = 8, + PatchConstantFunctionReturnType = 9, + PayloadParameters = 10, + Attributes = 11, + TypeParameter = 12, + StructuredBuffers = 13, + GlobalVariables = 14, + GroupShared = 15, +}; +bool DiagnoseTypeElements(clang::Sema &S, clang::SourceLocation Loc, + clang::QualType Ty, TypeDiagContext DiagContext, + const clang::FieldDecl *FD = nullptr); + void DiagnoseControlFlowConditionForHLSL(clang::Sema *self, clang::Expr *condExpr, llvm::StringRef StmtName); @@ -129,14 +152,6 @@ unsigned CaculateInitListArraySizeForHLSL(clang::Sema *sema, const clang::QualType EltTy); bool ContainsLongVector(clang::QualType); -bool ContainsHitObject(clang::QualType); - -/// \brief Determine if the given type contains a long vector or a hit object. -/// \param QT The type to check. -/// \param DiagTypeIdx The index of the type in the diagnostic message. -/// \returns True if the type contains a long vector or a hit object, false -/// otherwise. -bool ContainsLongVecOrHitObject(clang::QualType QT, unsigned &DiagTypeIdx); bool IsConversionToLessOrEqualElements(clang::Sema *self, const clang::ExprResult &sourceExpr, diff --git a/tools/clang/lib/AST/DeclCXX.cpp b/tools/clang/lib/AST/DeclCXX.cpp index 14cf7c208d..baed44667f 100644 --- a/tools/clang/lib/AST/DeclCXX.cpp +++ b/tools/clang/lib/AST/DeclCXX.cpp @@ -72,9 +72,8 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) ImplicitCopyAssignmentHasConstParam(true), HasDeclaredCopyConstructorWithConstParam(false), HasDeclaredCopyAssignmentWithConstParam(false), IsLambda(false), - IsParsingBaseSpecifiers(false), HasHLSLLongVector(false), - HasHLSLHitObject(false), NumBases(0), NumVBases(0), Bases(), VBases(), - Definition(D), FirstFriend() {} + IsParsingBaseSpecifiers(false), HasHLSLLongVector(false), NumBases(0), + NumVBases(0), Bases(), VBases(), Definition(D), FirstFriend() {} // HLSL Change End - Add HasLongVector and clang-format CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const { @@ -207,8 +206,6 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, // HLSL Change Begin - Propagate presence of long vector to child classes. if (BaseClassDecl->hasHLSLLongVector()) data().HasHLSLLongVector = true; - if (BaseClassDecl->hasHLSLHitObject()) - data().HasHLSLHitObject = true; // HLSL Change End // Record if this base is the first non-literal field or base. @@ -396,8 +393,6 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) { // HLSL Change Begin - Propagate presence of long vector to child classes. if (Subobj->hasHLSLLongVector()) data().HasHLSLLongVector = true; - if (Subobj->hasHLSLHitObject()) - data().HasHLSLHitObject = true; // HLSL Change End } diff --git a/tools/clang/lib/AST/HlslTypes.cpp b/tools/clang/lib/AST/HlslTypes.cpp index 0a7cf87ecd..186f24eaa2 100644 --- a/tools/clang/lib/AST/HlslTypes.cpp +++ b/tools/clang/lib/AST/HlslTypes.cpp @@ -113,6 +113,11 @@ bool IsHLSLNumericUserDefinedType(clang::QualType type) { for (auto member : RD->fields()) { if (!IsHLSLNumericOrAggregateOfNumericType(member->getType())) return false; + if (auto *Child = dyn_cast(RD)) + // Walk up the inheritance chain and check base class fields + for (auto &Base : Child->bases()) + if (!IsHLSLNumericOrAggregateOfNumericType(Base.getType())) + return false; } return true; } @@ -125,8 +130,6 @@ bool IsHLSLNumericUserDefinedType(clang::QualType type) { // which can't be annotated. But includes UDTs of trivially copyable data and // the builtin trivially copyable raytracing structs. bool IsHLSLCopyableAnnotatableRecord(clang::QualType QT) { - if (ContainsHitObject(QT)) - return false; return IsHLSLNumericUserDefinedType(QT) || IsHLSLBuiltinRayAttributeStruct(QT); } diff --git a/tools/clang/lib/Sema/SemaDXR.cpp b/tools/clang/lib/Sema/SemaDXR.cpp index fa87a3db5c..efdf90b2be 100644 --- a/tools/clang/lib/Sema/SemaDXR.cpp +++ b/tools/clang/lib/Sema/SemaDXR.cpp @@ -827,6 +827,9 @@ void DiagnoseBuiltinCallWithPayload(Sema &S, const VarDecl *Payload, } // Verify that the payload type is legal + if (DiagnoseTypeElements(S, Payload->getLocation(), Payload->getType(), + TypeDiagContext::PayloadParameters)) + return; if (!hlsl::IsHLSLCopyableAnnotatableRecord(Payload->getType())) { S.Diag(Payload->getLocation(), diag::err_payload_attrs_must_be_udt) << /*payload|attributes|callable*/ 0 << /*parameter %2|type*/ 0 @@ -835,11 +838,9 @@ void DiagnoseBuiltinCallWithPayload(Sema &S, const VarDecl *Payload, } if (ContainsLongVector(Payload->getType())) { - // No need to check for HitObject, checked with payload diagnosis. - const unsigned LongVectorIdx = 0; const unsigned PayloadParametersIdx = 10; - S.Diag(Payload->getLocation(), diag::err_hlsl_unsupported_type) - << LongVectorIdx << PayloadParametersIdx; + S.Diag(Payload->getLocation(), diag::err_hlsl_unsupported_long_vector) + << PayloadParametersIdx; return; } diff --git a/tools/clang/lib/Sema/SemaDecl.cpp b/tools/clang/lib/Sema/SemaDecl.cpp index a3a597db42..e09bf4623c 100644 --- a/tools/clang/lib/Sema/SemaDecl.cpp +++ b/tools/clang/lib/Sema/SemaDecl.cpp @@ -13247,16 +13247,10 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, SmallVector RecFields; bool ARCErrReported = false; - bool HasHitObject = false; for (ArrayRef::iterator i = Fields.begin(), end = Fields.end(); i != end; ++i) { FieldDecl *FD = cast(*i); - // HLSL Change Begin - set HitObject bit for fields - if (!HasHitObject && hlsl::ContainsHitObject(FD->getType())) - HasHitObject = true; - // HLSL Change End - // Get the type for the field. const Type *FDTy = FD->getType().getTypePtr(); @@ -13445,12 +13439,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, I = CXXRecord->conversion_begin(), E = CXXRecord->conversion_end(); I != E; ++I) I.setAccess((*I)->getAccess()); - - // HLSL Change Begin - set HitObject bit for fields - if (HasHitObject) - CXXRecord->setHasHLSLHitObject(); - // HLSL Change End - + if (!CXXRecord->isDependentType()) { if (CXXRecord->hasUserDeclaredDestructor()) { // Adjust user-defined destructor exception spec. diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index a9c71c63e5..179e92ebc9 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -46,6 +46,7 @@ #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -5394,7 +5395,8 @@ class HLSLExternalSource : public ExternalSemaSource { objectKind = ClassifyRecordType(recordType); switch (objectKind) { case AR_TOBJ_OBJECT: - m_sema->Diag(argLoc, diag::err_hlsl_objectintemplateargument) << type; + m_sema->Diag(argLoc, diag::err_hlsl_unsupported_object_context) + << type << static_cast(TypeDiagContext::TypeParameter); return false; case AR_TOBJ_COMPOUND: { const RecordDecl *recordDecl = recordType->getDecl(); @@ -5533,15 +5535,30 @@ class HLSLExternalSource : public ExternalSemaSource { m_sema->RequireCompleteType(argSrcLoc, argType, diag::err_typecheck_decl_incomplete_type); - unsigned DiagTypeIdx = 0; - if (hlsl::ContainsLongVecOrHitObject(argType, DiagTypeIdx)) { + if (ContainsLongVector(argType)) { const unsigned ConstantBuffersOrTextureBuffersIdx = 0; - m_sema->Diag(argSrcLoc, diag::err_hlsl_unsupported_type) - << DiagTypeIdx << ConstantBuffersOrTextureBuffersIdx; + m_sema->Diag(argSrcLoc, diag::err_hlsl_unsupported_long_vector) + << ConstantBuffersOrTextureBuffersIdx; return true; } + if (DiagnoseTypeElements( + *m_sema, argSrcLoc, argType, + TypeDiagContext::ConstantBuffersOrTextureBuffers)) + return true; } return false; + } else if (ResAttr && DXIL::IsStructuredBuffer(ResAttr->getResKind())) { + if (TemplateArgList.size() == 1) { + const TemplateArgumentLoc &ArgLoc = TemplateArgList[0]; + const TemplateArgument &Arg = ArgLoc.getArgument(); + if (Arg.getKind() == TemplateArgument::ArgKind::Type) { + QualType ArgType = Arg.getAsType(); + SourceLocation ArgSrcLoc = ArgLoc.getLocation(); + if (DiagnoseTypeElements(*m_sema, ArgSrcLoc, ArgType, + TypeDiagContext::StructuredBuffers)) + return true; + } + } } else if (Template->getTemplatedDecl()->hasAttr()) { @@ -5642,13 +5659,16 @@ class HLSLExternalSource : public ExternalSemaSource { CXXRecordDecl *Decl = arg.getAsType()->getAsCXXRecordDecl(); if (Decl && !Decl->isCompleteDefinition()) return true; - unsigned DiagTypeIdx = 0; - if (ContainsLongVecOrHitObject(arg.getAsType(), DiagTypeIdx)) { + if (ContainsLongVector(arg.getAsType())) { const unsigned TessellationPatchesIDx = 1; - m_sema->Diag(argLoc.getLocation(), diag::err_hlsl_unsupported_type) - << DiagTypeIdx << TessellationPatchesIDx; + m_sema->Diag(argLoc.getLocation(), + diag::err_hlsl_unsupported_long_vector) + << TessellationPatchesIDx; return true; } + if (DiagnoseTypeElements(*m_sema, argLoc.getLocation(), arg.getAsType(), + TypeDiagContext::TessellationPatches)) + return true; } else if (Template->getTemplatedDecl()->hasAttr()) { DXASSERT(TemplateArgList.size() > 0, "Geometry streams should have at least one template args"); @@ -5661,13 +5681,16 @@ class HLSLExternalSource : public ExternalSemaSource { CXXRecordDecl *Decl = arg.getAsType()->getAsCXXRecordDecl(); if (Decl && !Decl->isCompleteDefinition()) return true; - unsigned DiagTypeIdx = 0; - if (ContainsLongVecOrHitObject(arg.getAsType(), DiagTypeIdx)) { - const unsigned GeometryStreamsIdx = 2; - m_sema->Diag(argLoc.getLocation(), diag::err_hlsl_unsupported_type) - << DiagTypeIdx << GeometryStreamsIdx; + const unsigned GeometryStreamsIdx = 2; + if (ContainsLongVector(arg.getAsType())) { + m_sema->Diag(argLoc.getLocation(), + diag::err_hlsl_unsupported_long_vector) + << GeometryStreamsIdx; return true; } + if (DiagnoseTypeElements(*m_sema, argLoc.getLocation(), arg.getAsType(), + TypeDiagContext::GeometryStreams)) + return true; } bool isMatrix = Template->getCanonicalDecl() == @@ -10786,11 +10809,8 @@ bool DiagnoseIntersectionAttributes(Sema &S, SourceLocation Loc, QualType Ty) { } if (ContainsLongVector(Ty)) { - // No need to check for HitObject, checked with attributes diagnosis. - const unsigned LongVectorIdx = 0; const unsigned AttributesIdx = 11; - S.Diag(Loc, diag::err_hlsl_unsupported_type) - << LongVectorIdx << AttributesIdx; + S.Diag(Loc, diag::err_hlsl_unsupported_long_vector) << AttributesIdx; return false; } return true; @@ -10946,6 +10966,9 @@ HLSLExternalSource::DeduceTemplateArgumentsForHLSL( << intrinsicName; return Sema::TemplateDeductionResult::TDK_Invalid; } + if (DiagnoseTypeElements(*getSema(), Loc, functionTemplateTypeArg, + TypeDiagContext::TypeParameter)) + return Sema::TemplateDeductionResult::TDK_Invalid; } if (IsHitObjectGetAttributes && !DiagnoseIntersectionAttributes(*getSema(), Loc, @@ -12132,35 +12155,59 @@ void Sema::DiagnoseReachableHLSLCall(CallExpr *CE, const hlsl::ShaderModel *SM, ///////////////////////////////////////////////////////////////////////////// -bool hlsl::DiagnoseNodeStructArgument(Sema *self, TemplateArgumentLoc ArgLoc, - QualType ArgTy, bool &Empty, - const FieldDecl *FD) { - DXASSERT_NOMSG(!ArgTy.isNull()); +static bool AllowObjectInContext(QualType Ty, TypeDiagContext DiagContext) { + // Disallow all object in template type parameters (former + // err_hlsl_objectintemplateargument) + if (DiagContext == TypeDiagContext::TypeParameter) + return false; + // Disallow all objects in node records (former + // err_hlsl_node_record_object) + if (DiagContext == TypeDiagContext::NodeRecords) + return false; + // TODO: Extend this list for other object types. + if (IsHLSLHitObjectType(Ty)) + return false; + return true; +} - HLSLExternalSource *source = HLSLExternalSource::FromSema(self); - ArTypeObjectKind shapeKind = source->GetTypeObjectKind(ArgTy); - switch (shapeKind) { +static bool +DiagnoseElementTypes(Sema &S, SourceLocation Loc, QualType Ty, bool &Empty, + bool CheckLongVec, TypeDiagContext DiagContext, + llvm::SmallPtrSet &CheckedDecls, + const clang::FieldDecl *FD) { + if (Ty.isNull() || Ty->isDependentType()) + return false; + + while (const ArrayType *Arr = Ty->getAsArrayTypeUnsafe()) + Ty = Arr->getElementType(); + + const unsigned DiagContextIdx = static_cast(DiagContext); + + HLSLExternalSource *Source = HLSLExternalSource::FromSema(&S); + ArTypeObjectKind ShapeKind = Source->GetTypeObjectKind(Ty); + switch (ShapeKind) { case AR_TOBJ_VECTOR: - if (GetHLSLVecSize(ArgTy) > DXIL::kDefaultMaxVectorLength) { - const unsigned LongVectorIdx = 0; - const unsigned NodeRecordsIdx = 3; - self->Diag(ArgLoc.getLocation(), diag::err_hlsl_unsupported_type) - << LongVectorIdx << NodeRecordsIdx; + // TODO: This is only here because DiagnoseNodeStructArgument got folded + // into this function. Could fold all context-dependent long vector checks + // into this function. + if (CheckLongVec && GetHLSLVecSize(Ty) > DXIL::kDefaultMaxVectorLength) { + S.Diag(Loc, diag::err_hlsl_unsupported_long_vector) << DiagContextIdx; Empty = false; return false; } LLVM_FALLTHROUGH; - case AR_TOBJ_ARRAY: case AR_TOBJ_BASIC: case AR_TOBJ_MATRIX: Empty = false; return false; case AR_TOBJ_OBJECT: Empty = false; - self->Diag(ArgLoc.getLocation(), diag::err_hlsl_node_record_object) - << ArgTy << ArgLoc.getSourceRange(); + if (AllowObjectInContext(Ty, DiagContext)) + return false; + S.Diag(Loc, diag::err_hlsl_unsupported_object_context) + << Ty << DiagContextIdx; if (FD) - self->Diag(FD->getLocation(), diag::note_field_declared_here) + S.Diag(FD->getLocation(), diag::note_field_declared_here) << FD->getType() << FD->getSourceRange(); return true; case AR_TOBJ_DEPENDENT: @@ -12169,25 +12216,51 @@ bool hlsl::DiagnoseNodeStructArgument(Sema *self, TemplateArgumentLoc ArgLoc, return true; case AR_TOBJ_COMPOUND: { bool ErrorFound = false; - const RecordDecl *RD = ArgTy->getAs()->getDecl(); + const RecordDecl *RD = Ty->getAs()->getDecl(); + // Never recurse infinitely into related subtypes + if (!CheckedDecls.insert(RD).second) + return false; + // Check the fields of the RecordDecl - for (auto *FD : RD->fields()) + for (auto *ElemFD : RD->fields()) { ErrorFound |= - DiagnoseNodeStructArgument(self, ArgLoc, FD->getType(), Empty, FD); - if (RD->isCompleteDefinition()) - if (auto *Child = dyn_cast(RD)) - // Walk up the inheritance chain and check base class fields - for (auto &B : Child->bases()) - ErrorFound |= - DiagnoseNodeStructArgument(self, ArgLoc, B.getType(), Empty); + DiagnoseElementTypes(S, Loc, ElemFD->getType(), Empty, CheckLongVec, + DiagContext, CheckedDecls, ElemFD); + } + if (!RD->isCompleteDefinition()) + return ErrorFound; + + if (auto *Child = dyn_cast(RD)) + // Walk up the inheritance chain and check base class fields + for (auto &B : Child->bases()) + ErrorFound |= + DiagnoseElementTypes(S, Loc, B.getType(), Empty, CheckLongVec, + DiagContext, CheckedDecls, nullptr); return ErrorFound; } default: - DXASSERT(false, "unreachable"); return false; } } +bool hlsl::DiagnoseTypeElements(Sema &S, SourceLocation Loc, QualType Ty, + TypeDiagContext DiagContext, + const clang::FieldDecl *FD) { + bool Empty = false; + llvm::SmallPtrSet CheckedDecls; + return DiagnoseElementTypes(S, Loc, Ty, Empty, false /*CheckLongVec*/, + DiagContext, CheckedDecls, FD); +} + +bool hlsl::DiagnoseNodeStructArgument(Sema *self, TemplateArgumentLoc ArgLoc, + QualType ArgTy, bool &Empty, + const FieldDecl *FD) { + llvm::SmallPtrSet CheckedDecls; + return DiagnoseElementTypes(*self, ArgLoc.getLocation(), ArgTy, Empty, + true /*CheckLongVec*/, + TypeDiagContext::NodeRecords, CheckedDecls, FD); +} + // This function diagnoses whether or not all entry-point attributes // should exist on this shader stage void DiagnoseEntryAttrAllowedOnStage(clang::Sema *self, @@ -12615,24 +12688,6 @@ bool hlsl::ShouldSkipNRVO(clang::Sema &sema, clang::QualType returnType, return false; } -bool hlsl::ContainsHitObject(QualType QT) { - if (QT.isNull() || QT->isDependentType()) - return false; - - while (const ArrayType *Arr = QT->getAsArrayTypeUnsafe()) - QT = Arr->getElementType(); - - if (IsHLSLHitObjectType(QT)) - return true; - - if (CXXRecordDecl *Decl = QT->getAsCXXRecordDecl()) { - if (!Decl->isCompleteDefinition()) - return false; - return Decl->hasHLSLHitObject(); - } - return false; -} - bool hlsl::ContainsLongVector(QualType QT) { if (QT.isNull() || QT->isDependentType()) return false; @@ -12648,19 +12703,6 @@ bool hlsl::ContainsLongVector(QualType QT) { return false; } -bool hlsl::ContainsLongVecOrHitObject(clang::QualType QT, - unsigned &DiagTypeIdx) { - if (ContainsHitObject(QT)) { - DiagTypeIdx = 1; - return true; - } - if (ContainsLongVector(QT)) { - DiagTypeIdx = 0; - return true; - } - return false; -} - bool hlsl::IsConversionToLessOrEqualElements( clang::Sema *self, const clang::ExprResult &sourceExpr, const clang::QualType &targetType, bool explicitConversion) { @@ -15331,9 +15373,21 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth, result = false; } - // Disallow long vecs from $Global cbuffers. - const unsigned CbuffersOrTbuffersIdx = 4; - if (isGlobal && !isStatic) { + if (isGroupShared) { + // Suppress actual emitting of errors for incompletable types here + // They are redundant to those produced in ActOnUninitializedDecl. + struct SilentDiagnoser : public TypeDiagnoser { + SilentDiagnoser() : TypeDiagnoser(true) {} + virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {} + } SD; + RequireCompleteType(D.getLocStart(), qt, SD); + if (DiagnoseTypeElements(*this, D.getLocStart(), qt, + TypeDiagContext::GroupShared)) + result = false; + } + + // Disallow intangible HLSL objects in the global scope. + if (isGlobal) { // Suppress actual emitting of errors for incompletable types here // They are redundant to those produced in ActOnUninitializedDecl. struct SilentDiagnoser : public TypeDiagnoser { @@ -15341,18 +15395,20 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth, virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {} } SD; RequireCompleteType(D.getLocStart(), qt, SD); - unsigned DiagTypeIdx = 0; - bool HasError = false; - if (!isGroupShared && !IS_BASIC_OBJECT(basicKind) && ContainsLongVector(qt)) - HasError = true; - else if (ContainsHitObject(qt)) { - const unsigned HitObjectTypeIdx = 1; - DiagTypeIdx = HitObjectTypeIdx; - HasError = true; - } - if (HasError) { - Diag(D.getLocStart(), diag::err_hlsl_unsupported_type) - << DiagTypeIdx << CbuffersOrTbuffersIdx; + TypeDiagContext DiagContext = TypeDiagContext::CBuffersOrTBuffers; + if (isStatic) + DiagContext = TypeDiagContext::GlobalVariables; + if (DiagnoseTypeElements(*this, D.getLocStart(), qt, DiagContext)) + result = false; + } + + // Disallow long vecs from $Global cbuffers. + if (isGlobal && !isStatic && !isGroupShared && !IS_BASIC_OBJECT(basicKind)) { + const unsigned CbuffersOrTbuffersIdx = 4; + if (ContainsLongVector(qt)) { + Diag(D.getLocStart(), diag::err_hlsl_unsupported_long_vector) + << CbuffersOrTbuffersIdx; + result = false; } } @@ -16259,14 +16315,14 @@ static bool isRelatedDeclMarkedNointerpolation(Expr *E) { // Verify that user-defined intrinsic struct args contain no long vectors static bool CheckUDTIntrinsicArg(Sema *S, Expr *Arg) { - unsigned DiagTypeIdx = 0; - if (ContainsLongVecOrHitObject(Arg->getType(), DiagTypeIdx)) { + if (ContainsLongVector(Arg->getType())) { const unsigned UserDefinedStructParameterIdx = 5; - S->Diag(Arg->getExprLoc(), diag::err_hlsl_unsupported_type) - << DiagTypeIdx << UserDefinedStructParameterIdx; + S->Diag(Arg->getExprLoc(), diag::err_hlsl_unsupported_long_vector) + << UserDefinedStructParameterIdx; return true; } - return false; + return DiagnoseTypeElements(*S, Arg->getExprLoc(), Arg->getType(), + TypeDiagContext::UserDefinedStructParameter); } static bool CheckIntrinsicGetAttributeAtVertex(Sema *S, FunctionDecl *FDecl, @@ -17003,20 +17059,22 @@ void DiagnoseEntry(Sema &S, FunctionDecl *FD) { // Would be nice to check for resources here as they crash the compiler now. // See issue #7186. for (const auto *param : FD->params()) { - unsigned DiagTypeIdx = 0; - if (ContainsLongVecOrHitObject(param->getType(), DiagTypeIdx)) { + if (ContainsLongVector(param->getType())) { const unsigned EntryFunctionParametersIdx = 6; - S.Diag(param->getLocation(), diag::err_hlsl_unsupported_type) - << DiagTypeIdx << EntryFunctionParametersIdx; + S.Diag(param->getLocation(), diag::err_hlsl_unsupported_long_vector) + << EntryFunctionParametersIdx; } + hlsl::DiagnoseTypeElements(S, param->getLocation(), param->getType(), + TypeDiagContext::EntryFunctionParameters); } - unsigned DiagTypeIdx = 0; - if (ContainsLongVecOrHitObject(FD->getReturnType(), DiagTypeIdx)) { + if (ContainsLongVector(FD->getReturnType())) { const unsigned EntryFunctionReturnIdx = 7; - S.Diag(FD->getLocation(), diag::err_hlsl_unsupported_type) - << DiagTypeIdx << EntryFunctionReturnIdx; + S.Diag(FD->getLocation(), diag::err_hlsl_unsupported_long_vector) + << EntryFunctionReturnIdx; } + DiagnoseTypeElements(S, FD->getLocation(), FD->getReturnType(), + TypeDiagContext::EntryFunctionReturnType); DXIL::ShaderKind Stage = ShaderModel::KindFromFullName(shaderAttr->getStage()); diff --git a/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp b/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp index c8ad298081..92aaefab53 100644 --- a/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp +++ b/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp @@ -710,20 +710,24 @@ void hlsl::DiagnoseTranslationUnit(clang::Sema *self) { } } for (const auto *param : pPatchFnDecl->params()) { - unsigned TypeDiagIdx = 0; const unsigned PatchConstantFunctionParametersIdx = 8; - if (ContainsLongVecOrHitObject(param->getType(), TypeDiagIdx)) - self->Diag(param->getLocation(), diag::err_hlsl_unsupported_type) - << TypeDiagIdx << PatchConstantFunctionParametersIdx; + if (ContainsLongVector(param->getType())) + self->Diag(param->getLocation(), + diag::err_hlsl_unsupported_long_vector) + << PatchConstantFunctionParametersIdx; + DiagnoseTypeElements(*self, param->getLocation(), param->getType(), + TypeDiagContext::PatchConstantFunctionParameters); } - unsigned TypeDiagIdx = 0; - if (ContainsLongVecOrHitObject(pPatchFnDecl->getReturnType(), - TypeDiagIdx)) { + if (ContainsLongVector(pPatchFnDecl->getReturnType())) { const unsigned PatchConstantFunctionReturnIdx = 9; - self->Diag(pPatchFnDecl->getLocation(), diag::err_hlsl_unsupported_type) - << TypeDiagIdx << PatchConstantFunctionReturnIdx; + self->Diag(pPatchFnDecl->getLocation(), + diag::err_hlsl_unsupported_long_vector) + << PatchConstantFunctionReturnIdx; } + DiagnoseTypeElements(*self, pPatchFnDecl->getLocation(), + pPatchFnDecl->getReturnType(), + TypeDiagContext::PatchConstantFunctionReturnType); } DXIL::ShaderKind EntrySK = shaderModel->GetKind(); DXIL::NodeLaunchType NodeLaunchTy = DXIL::NodeLaunchType::Invalid; diff --git a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject-in-buffer.hlsl b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject-in-buffer.hlsl index baa3a07a5b..05eb6d4f54 100644 --- a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject-in-buffer.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject-in-buffer.hlsl @@ -1,4 +1,4 @@ // RUN: %dxc -T lib_6_9 %s -verify -// expected-error@+1{{'dx::HitObject' is an object and cannot be used as a type parameter}} +// expected-error@+1{{object ''dx::HitObject'' is not allowed in structured buffers}} RWStructuredBuffer InvalidBuffer; diff --git a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl index e89e33a78f..29b93fd16e 100644 --- a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl @@ -16,7 +16,8 @@ struct Attribs [shader("raygeneration")] void RayGen() { - // expected-error@+1{{payload parameter 'payload_in_rg' must be a user-defined type composed of only numeric types}} + // expected-error@+2{{object ''dx::HitObject'' is not allowed in payload parameters}} + // expected-note@8{{'dx::HitObject' field declared here}} Payload payload_in_rg; dx::HitObject::Invoke( dx::HitObject(), payload_in_rg ); } \ No newline at end of file diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-hs.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-hs.hlsl index 6020594a69..485b149886 100644 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-hs.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-hs.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -DTYPE=float -T hs_6_9 -verify %s +// RUN: %dxc -T hs_6_9 -verify %s struct HsConstantData { float Edges[3] : SV_TessFactor; @@ -10,10 +10,18 @@ struct LongVec { dx::HitObject hit; }; -HsConstantData PatchConstantFunction( // expected-error{{HitObjects in patch constant function return type are not supported}} - dx::HitObject hit : V, // expected-error{{HitObjects in patch constant function parameters are not supported}} - LongVec lv : L) { // expected-error{{HitObjects in patch constant function parameters are not supported}} - return (HsConstantData)0; +HsConstantData +PatchConstantFunction( + // expected-error@-1{{object ''dx::HitObject'' is not allowed in patch constant function return type}} + // expected-note@5{{'dx::HitObject' field declared here}} + dx::HitObject hit : V, + // expected-error@-1{{object ''dx::HitObject'' is not allowed in patch constant function parameters}} + LongVec lv : L) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in patch constant function parameters}} + // expected-note@10{{'dx::HitObject' field declared here}} +{ + HsConstantData empty; + return empty; } [domain("tri")] diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl index ed4b03280a..e59fc8ec7a 100644 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl @@ -1,4 +1,6 @@ // RUN: %dxc -T lib_6_9 -DTYPE=HitStruct -verify %s +// RUN: %dxc -T lib_6_9 -DTYPE=HitStructSub -verify %s + #define PASTE_(x,y) x##y #define PASTE(x,y) PASTE_(x,y) @@ -24,33 +26,83 @@ struct HitTpl { T val; }; -dx::HitObject global_hit; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} -dx::HitObject global_hit_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} +TYPE global_type; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} +// expected-note@16{{'dx::HitObject' field declared here}} +dx::HitObject global_hit; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} +dx::HitObject global_hit_arr[10]; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + +static TYPE static_gv; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in global variables}} +// expected-note@16{{'dx::HitObject' field declared here}} cbuffer BadBuffy { - dx::HitObject cb_hit; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - dx::HitObject cb_hit_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + dx::HitObject cb_hit; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + dx::HitObject cb_hit_arr[10]; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} }; tbuffer BadTuffy { - dx::HitObject tb_vec; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - dx::HitObject tb_vec_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - TYPE tb_vec_rec; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - TYPE tb_vec_rec_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} + dx::HitObject tb_vec; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + dx::HitObject tb_vec_arr[10]; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + TYPE tb_vec_rec; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-note@16{{'dx::HitObject' field declared here}} + TYPE tb_vec_rec_arr[10]; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-note@16{{'dx::HitObject' field declared here}} }; -ConstantBuffer const_buf; // expected-error{{HitObjects in ConstantBuffers or TextureBuffers are not supported}} -TextureBuffer tex_buf; // expected-error{{HitObjects in ConstantBuffers or TextureBuffers are not supported}} +StructuredBuffer struct_buf; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in structured buffers}} +// expected-note@16{{'dx::HitObject' field declared here}} +RWStructuredBuffer rw_struct_buf; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in structured buffers}} +// expected-note@16{{'dx::HitObject' field declared here}} +ConstantBuffer const_buf; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in ConstantBuffers or TextureBuffers}} +// expected-note@16{{'dx::HitObject' field declared here}} +TextureBuffer tex_buf; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in ConstantBuffers or TextureBuffers}} +// expected-note@16{{'dx::HitObject' field declared here}} + +ByteAddressBuffer bab; +RWByteAddressBuffer rw_bab; + +[Shader("raygeneration")] +void main() +{ + bab.Load(0); + // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} + rw_bab.Load(0); + // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} + TYPE val; + rw_bab.Store(0, val); + // expected-error@-1{{Explicit template arguments on intrinsic Store must be a single numeric type}} +} [shader("pixel")] -TYPE main( // expected-error{{HitObjects in entry function return type are not supported}} - TYPE vec : V) : SV_Target { // expected-error{{HitObjects in entry function parameters are not supported}} +TYPE ps_main( +// expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function return type}} +// expected-note@16{{'dx::HitObject' field declared here}} + TYPE vec : V) : SV_Target { + // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} return vec; } [shader("vertex")] -TYPE vs_main( // expected-error{{HitObjects in entry function return type are not supported}} - TYPE parm : P) : SV_Target { // expected-error{{HitObjects in entry function parameters are not supported}} +TYPE vs_main( +// expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function return type}} +// expected-note@16{{'dx::HitObject' field declared here}} + TYPE parm : P) : SV_Target { + // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} parm.f = 0; return parm; } @@ -59,47 +111,62 @@ TYPE vs_main( // expected-error{{HitObjects in entry function return type are no [shader("geometry")] [maxvertexcount(3)] void gs_point( - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - line TYPE e, - // expected-error@+1{{HitObjects in geometry streams are not supported}} - inout PointStream OutputStream0) {} + line TYPE e, + // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + inout PointStream OutputStream0) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in geometry streams}} + // expected-note@16{{'dx::HitObject' field declared here}} +{} [shader("geometry")] [maxvertexcount(12)] void gs_line( - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - line TYPE a, - // expected-error@+1{{HitObjects in geometry streams are not supported}} - inout LineStream OutputStream0) {} + line TYPE a, + // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + inout LineStream OutputStream0) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in geometry streams}} + // expected-note@16{{'dx::HitObject' field declared here}} +{} [shader("geometry")] [maxvertexcount(12)] void gs_line( - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - line TYPE a, - // expected-error@+1{{HitObjects in geometry streams are not supported}} - inout TriangleStream OutputStream0) {} + line TYPE a, + // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + inout TriangleStream OutputStream0) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in geometry streams}} + // expected-note@16{{'dx::HitObject' field declared here}} +{} [shader("domain")] [domain("tri")] void ds_main( - // expected-error@+1{{HitObjects in tessellation patches are not supported}} - OutputPatch TrianglePatch) {} + OutputPatch TrianglePatch) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} + // expected-note@16{{'dx::HitObject' field declared here}} +{} void patch_const( - // expected-error@+1{{HitObjects in tessellation patches are not supported}} - InputPatch inpatch, - // expected-error@+1{{HitObjects in tessellation patches are not supported}} - OutputPatch outpatch) {} + InputPatch inpatch, + // expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} + // expected-note@16{{'dx::HitObject' field declared here}} + OutputPatch outpatch) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} + // expected-note@16{{'dx::HitObject' field declared here}} +{} [shader("hull")] [domain("tri")] [outputtopology("triangle_cw")] [outputcontrolpoints(32)] [patchconstantfunc("patch_const")] -// expected-error@+1{{HitObjects in tessellation patches are not supported}} void hs_main(InputPatch TrianglePatch) {} +// expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} +// expected-note@16{{'dx::HitObject' field declared here}} RaytracingAccelerationStructure RTAS; @@ -120,76 +187,105 @@ struct [raypayload] DXRHitTpl { #define RTTYPE PASTE(DXR,TYPE) + +TYPE userFunc(TYPE arg) { + return arg; +} + [shader("raygeneration")] void raygen() { RTTYPE p = (RTTYPE)0; RayDesc ray = (RayDesc)0; - TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} - CallShader(0, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} + CallShader(0, p); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} + TYPE val; + TYPE res = userFunc(val); } [shader("closesthit")] void closesthit( - // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-note@14{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} inout RTTYPE payload, - // expected-error@+3{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} - // expected-note@14{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} + // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} in RTTYPE attribs) { + // expected-error@-1{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} + // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} RayDesc ray; - TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error{{HitObjects in user-defined struct parameter are not supported}} - CallShader(0, payload); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} + CallShader(0, payload); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} } [shader("anyhit")] void AnyHit( - // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-note@14{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} inout RTTYPE payload, - // expected-error@+3{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} - // expected-note@14{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} + // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} in RTTYPE attribs) + // expected-error@-1{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} + // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} { } [shader("miss")] void Miss( - // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-note@14{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} inout RTTYPE payload){ + // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} RayDesc ray; - TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error{{HitObjects in user-defined struct parameter are not supported}} - CallShader(0, payload); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} + CallShader(0, payload); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} } [shader("intersection")] void Intersection() { float hitT = RayTCurrent(); RTTYPE attr = (RTTYPE)0; - bool bReported = ReportHit(hitT, 0, attr); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + bool bReported = ReportHit(hitT, 0, attr); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} } [shader("callable")] void callable1( - // expected-error@+3{{callable parameter 'p' must be a user-defined type composed of only numeric types}} - // expected-note@14{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} inout RTTYPE p) { - CallShader(0, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + // expected-error@-3{{callable parameter 'p' must be a user-defined type composed of only numeric types}} + CallShader(0, p); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} } -groupshared TYPE as_pld; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} +static groupshared TYPE gs_var; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in groupshared variables}} +// expected-note@16{{'dx::HitObject' field declared here}} +// expected-error@-3{{object ''dx::HitObject'' is not allowed in global variables}} +// expected-note@16{{'dx::HitObject' field declared here}} [shader("amplification")] [numthreads(1,1,1)] void Amp() { TYPE as_pld; - DispatchMesh(1,1,1,as_pld); // expected-error{{HitObjects in user-defined struct parameter are not supported}} + DispatchMesh(1,1,1,as_pld); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} } struct NodeHitStruct { @@ -213,26 +309,32 @@ struct NodeHitTpl { [NodeLaunch("broadcasting")] [NumThreads(8,1,1)] [NodeMaxDispatchGrid(8, 1, 1)] -// Below error raised because the constructed node input record is invalid. Could be improved. -// expected-error@+1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} void broadcast( - // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} +// expected-error@-1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} DispatchNodeInputRecord input, - // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} + // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-note@16{{'dx::HitObject' field declared here}} NodeOutput output) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-note@16{{'dx::HitObject' field declared here}} { - ThreadNodeOutputRecords touts; // expected-error{{object 'dx::HitObject' may not appear in a node record}} - GroupNodeOutputRecords gouts; // expected-error{{object 'dx::HitObject' may not appear in a node record}} + ThreadNodeOutputRecords touts; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-note@16{{'dx::HitObject' field declared here}} + GroupNodeOutputRecords gouts; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-note@16{{'dx::HitObject' field declared here}} } [Shader("node")] [NodeLaunch("coalescing")] [NumThreads(8,1,1)] -void coalesce( - // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} - GroupNodeInputRecords input) {} +void coalesce(GroupNodeInputRecords input) {} +// expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} +// expected-note@16{{'dx::HitObject' field declared here}} [Shader("node")] [NodeLaunch("thread")] -// expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} void threader(ThreadNodeInputRecord input) {} +// expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} +// expected-note@16{{'dx::HitObject' field declared here}} diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl deleted file mode 100644 index 04e9f69939..0000000000 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl +++ /dev/null @@ -1,238 +0,0 @@ -// RUN: %dxc -T lib_6_9 -DTYPE=HitStructSub -verify %s - -#define PASTE_(x,y) x##y -#define PASTE(x,y) PASTE_(x,y) - -#ifndef TYPE -#define TYPE HitTpl -#endif - -// Add tests for base types and instantiated template classes with HitObjects - -struct HitStruct { - float4 f; - dx::HitObject hit; -}; - -struct HitStructSub : HitStruct { - int3 is; -}; - -template -struct HitTpl { - float4 f; - T val; -}; - -dx::HitObject global_hit; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} -dx::HitObject global_hit_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - -cbuffer BadBuffy { - dx::HitObject cb_hit; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - dx::HitObject cb_hit_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} -}; - -tbuffer BadTuffy { - dx::HitObject tb_vec; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - dx::HitObject tb_vec_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - TYPE tb_vec_rec; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - TYPE tb_vec_rec_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} -}; - -ConstantBuffer const_buf; // expected-error{{HitObjects in ConstantBuffers or TextureBuffers are not supported}} -TextureBuffer tex_buf; // expected-error{{HitObjects in ConstantBuffers or TextureBuffers are not supported}} - -[shader("pixel")] -TYPE main( // expected-error{{HitObjects in entry function return type are not supported}} - TYPE vec : V) : SV_Target { // expected-error{{HitObjects in entry function parameters are not supported}} - return vec; -} - -[shader("vertex")] -TYPE vs_main( // expected-error{{HitObjects in entry function return type are not supported}} - TYPE parm : P) : SV_Target { // expected-error{{HitObjects in entry function parameters are not supported}} - parm.f = 0; - return parm; -} - - -[shader("geometry")] -[maxvertexcount(3)] -void gs_point( - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - line TYPE e, - // expected-error@+1{{HitObjects in geometry streams are not supported}} - inout PointStream OutputStream0) {} - -[shader("geometry")] -[maxvertexcount(12)] -void gs_line( - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - line TYPE a, - // expected-error@+1{{HitObjects in geometry streams are not supported}} - inout LineStream OutputStream0) {} - - -[shader("geometry")] -[maxvertexcount(12)] -void gs_line( - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - line TYPE a, - // expected-error@+1{{HitObjects in geometry streams are not supported}} - inout TriangleStream OutputStream0) {} - -[shader("domain")] -[domain("tri")] -void ds_main( - // expected-error@+1{{HitObjects in tessellation patches are not supported}} - OutputPatch TrianglePatch) {} - -void patch_const( - // expected-error@+1{{HitObjects in tessellation patches are not supported}} - InputPatch inpatch, - // expected-error@+1{{HitObjects in tessellation patches are not supported}} - OutputPatch outpatch) {} - -[shader("hull")] -[domain("tri")] -[outputtopology("triangle_cw")] -[outputcontrolpoints(32)] -[patchconstantfunc("patch_const")] -// expected-error@+1{{HitObjects in tessellation patches are not supported}} -void hs_main(InputPatch TrianglePatch) {} - -RaytracingAccelerationStructure RTAS; - -struct [raypayload] DXRHitStruct { - float4 f : write(closesthit) : read(caller); - TYPE hit : write(closesthit) : read(caller); -}; - -struct [raypayload] DXRHitStructSub : DXRHitStruct { - int3 is : write(closesthit) : read(caller); -}; - -template -struct [raypayload] DXRHitTpl { - float4 f : write(closesthit) : read(caller); - T hit : write(closesthit) : read(caller); -}; - -#define RTTYPE PASTE(DXR,TYPE) - -[shader("raygeneration")] -void raygen() { - RTTYPE p = (RTTYPE)0; - RayDesc ray = (RayDesc)0; - TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} - CallShader(0, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} -} - -[shader("closesthit")] -void closesthit( - // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-note@14{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - inout RTTYPE payload, - // expected-error@+3{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} - // expected-note@14{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - in RTTYPE attribs) { - RayDesc ray; - TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error{{HitObjects in user-defined struct parameter are not supported}} - CallShader(0, payload); // expected-error{{HitObjects in user-defined struct parameter are not supported}} -} - -[shader("anyhit")] -void AnyHit( - // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-note@14{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - inout RTTYPE payload, - // expected-error@+3{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} - // expected-note@14{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - in RTTYPE attribs) -{ -} - -[shader("miss")] -void Miss( - // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-note@14{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - inout RTTYPE payload){ - RayDesc ray; - TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error{{HitObjects in user-defined struct parameter are not supported}} - CallShader(0, payload); // expected-error{{HitObjects in user-defined struct parameter are not supported}} -} - -[shader("intersection")] -void Intersection() { - float hitT = RayTCurrent(); - RTTYPE attr = (RTTYPE)0; - bool bReported = ReportHit(hitT, 0, attr); // expected-error{{HitObjects in user-defined struct parameter are not supported}} -} - -[shader("callable")] -void callable1( - // expected-error@+3{{callable parameter 'p' must be a user-defined type composed of only numeric types}} - // expected-note@14{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - inout RTTYPE p) { - CallShader(0, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} -} - -groupshared TYPE as_pld; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - -[shader("amplification")] -[numthreads(1,1,1)] -void Amp() { - TYPE as_pld; - DispatchMesh(1,1,1,as_pld); // expected-error{{HitObjects in user-defined struct parameter are not supported}} -} - -struct NodeHitStruct { - uint3 grid : SV_DispatchGrid; - TYPE hit; -}; - -struct NodeHitStructSub : NodeHitStruct { - int3 is; -}; - -template -struct NodeHitTpl { - uint3 grid : SV_DispatchGrid; - T hit; -}; - -#define NTYPE PASTE(Node,TYPE) - -[Shader("node")] -[NodeLaunch("broadcasting")] -[NumThreads(8,1,1)] -[NodeMaxDispatchGrid(8, 1, 1)] -// Below error raised because the constructed node input record is invalid. Could be improved. -// expected-error@+1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} -void broadcast( - // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} - DispatchNodeInputRecord input, - // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} - NodeOutput output) -{ - ThreadNodeOutputRecords touts; // expected-error{{object 'dx::HitObject' may not appear in a node record}} - GroupNodeOutputRecords gouts; // expected-error{{object 'dx::HitObject' may not appear in a node record}} -} - -[Shader("node")] -[NodeLaunch("coalescing")] -[NumThreads(8,1,1)] -void coalesce( - // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} - GroupNodeInputRecords input) {} - -[Shader("node")] -[NodeLaunch("thread")] -// expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} -void threader(ThreadNodeInputRecord input) {} diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-template.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-template.hlsl deleted file mode 100644 index 95d25d4c82..0000000000 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-template.hlsl +++ /dev/null @@ -1,238 +0,0 @@ -// RUN: %dxc -T lib_6_9 -verify %s - -#define PASTE_(x,y) x##y -#define PASTE(x,y) PASTE_(x,y) - -#ifndef TYPE -#define TYPE HitTpl -#endif - -// Add tests for base types and instantiated template classes with HitObjects - -struct HitStruct { - float4 f; - dx::HitObject hit; -}; - -struct HitStructSub : HitStruct { - int3 is; -}; - -template -struct HitTpl { - float4 f; - T val; -}; - -dx::HitObject global_hit; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} -dx::HitObject global_hit_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - -cbuffer BadBuffy { - dx::HitObject cb_hit; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - dx::HitObject cb_hit_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} -}; - -tbuffer BadTuffy { - dx::HitObject tb_vec; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - dx::HitObject tb_vec_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - TYPE tb_vec_rec; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - TYPE tb_vec_rec_arr[10]; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} -}; - -ConstantBuffer const_buf; // expected-error{{HitObjects in ConstantBuffers or TextureBuffers are not supported}} -TextureBuffer tex_buf; // expected-error{{HitObjects in ConstantBuffers or TextureBuffers are not supported}} - -[shader("pixel")] -TYPE main( // expected-error{{HitObjects in entry function return type are not supported}} - TYPE vec : V) : SV_Target { // expected-error{{HitObjects in entry function parameters are not supported}} - return vec; -} - -[shader("vertex")] -TYPE vs_main( // expected-error{{HitObjects in entry function return type are not supported}} - TYPE parm : P) : SV_Target { // expected-error{{HitObjects in entry function parameters are not supported}} - parm.f = 0; - return parm; -} - - -[shader("geometry")] -[maxvertexcount(3)] -void gs_point( - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - line TYPE e, - // expected-error@+1{{HitObjects in geometry streams are not supported}} - inout PointStream OutputStream0) {} - -[shader("geometry")] -[maxvertexcount(12)] -void gs_line( - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - line TYPE a, - // expected-error@+1{{HitObjects in geometry streams are not supported}} - inout LineStream OutputStream0) {} - - -[shader("geometry")] -[maxvertexcount(12)] -void gs_line( - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - line TYPE a, - // expected-error@+1{{HitObjects in geometry streams are not supported}} - inout TriangleStream OutputStream0) {} - -[shader("domain")] -[domain("tri")] -void ds_main( - // expected-error@+1{{HitObjects in tessellation patches are not supported}} - OutputPatch TrianglePatch) {} - -void patch_const( - // expected-error@+1{{HitObjects in tessellation patches are not supported}} - InputPatch inpatch, - // expected-error@+1{{HitObjects in tessellation patches are not supported}} - OutputPatch outpatch) {} - -[shader("hull")] -[domain("tri")] -[outputtopology("triangle_cw")] -[outputcontrolpoints(32)] -[patchconstantfunc("patch_const")] -// expected-error@+1{{HitObjects in tessellation patches are not supported}} -void hs_main(InputPatch TrianglePatch) {} - -RaytracingAccelerationStructure RTAS; - -struct [raypayload] DXRHitStruct { - float4 f : write(closesthit) : read(caller); - TYPE hit : write(closesthit) : read(caller); -}; - -struct [raypayload] DXRHitStructSub : DXRHitStruct { - int3 is : write(closesthit) : read(caller); -}; - -template -struct [raypayload] DXRHitTpl { - float4 f : write(closesthit) : read(caller); - T hit : write(closesthit) : read(caller); -}; - -#define RTTYPE PASTE(DXR,TYPE) - -[shader("raygeneration")] -void raygen() { - RTTYPE p = (RTTYPE)0; - RayDesc ray = (RayDesc)0; - TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} - CallShader(0, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} -} - -[shader("closesthit")] -void closesthit( - // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-note@24{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - inout RTTYPE payload, - // expected-error@+3{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} - // expected-note@24{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - in RTTYPE attribs) { - RayDesc ray; - TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error{{HitObjects in user-defined struct parameter are not supported}} - CallShader(0, payload); // expected-error{{HitObjects in user-defined struct parameter are not supported}} -} - -[shader("anyhit")] -void AnyHit( - // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-note@24{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - inout RTTYPE payload, - // expected-error@+3{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} - // expected-note@24{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - in RTTYPE attribs) -{ -} - -[shader("miss")] -void Miss( - // expected-error@+3{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-note@24{{'dx::HitObject' field declared here}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - inout RTTYPE payload){ - RayDesc ray; - TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error{{HitObjects in user-defined struct parameter are not supported}} - CallShader(0, payload); // expected-error{{HitObjects in user-defined struct parameter are not supported}} -} - -[shader("intersection")] -void Intersection() { - float hitT = RayTCurrent(); - RTTYPE attr = (RTTYPE)0; - bool bReported = ReportHit(hitT, 0, attr); // expected-error{{HitObjects in user-defined struct parameter are not supported}} -} - -[shader("callable")] -void callable1( - // expected-error@+2{{callable parameter 'p' must be a user-defined type composed of only numeric types}} - // expected-error@+1{{HitObjects in entry function parameters are not supported}} - inout RTTYPE p) { - CallShader(0, p); // expected-error{{HitObjects in user-defined struct parameter are not supported}} -} - -groupshared TYPE as_pld; // expected-error{{HitObjects in cbuffers or tbuffers are not supported}} - -[shader("amplification")] -[numthreads(1,1,1)] -void Amp() { - TYPE as_pld; - DispatchMesh(1,1,1,as_pld); // expected-error{{HitObjects in user-defined struct parameter are not supported}} -} - -struct NodeHitStruct { - uint3 grid : SV_DispatchGrid; - TYPE hit; -}; - -struct NodeHitStructSub : NodeHitStruct { - int3 is; -}; - -template -struct NodeHitTpl { - uint3 grid : SV_DispatchGrid; - T hit; -}; - -#define NTYPE PASTE(Node,TYPE) - -[Shader("node")] -[NodeLaunch("broadcasting")] -[NumThreads(8,1,1)] -[NodeMaxDispatchGrid(8, 1, 1)] -// Below error raised because the constructed node input record is invalid. Could be improved. -// expected-error@+1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} -void broadcast( - // expected-error@+2{{object 'dx::HitObject' may not appear in a node record}} - // expected-note@206{{'dx::HitObject' field declared here}} - DispatchNodeInputRecord input, - // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} - NodeOutput output) -{ - ThreadNodeOutputRecords touts; // expected-error{{object 'dx::HitObject' may not appear in a node record}} - GroupNodeOutputRecords gouts; // expected-error{{object 'dx::HitObject' may not appear in a node record}} -} - -[Shader("node")] -[NodeLaunch("coalescing")] -[NumThreads(8,1,1)] -void coalesce( - // expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} - GroupNodeInputRecords input) {} - -[Shader("node")] -[NodeLaunch("thread")] -// expected-error@+1{{object 'dx::HitObject' may not appear in a node record}} -void threader(ThreadNodeInputRecord input) {} diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl new file mode 100644 index 0000000000..5d6325c289 --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl @@ -0,0 +1,337 @@ +// RUN: %dxc -T lib_6_9 -verify %s + + +#define PASTE_(x,y) x##y +#define PASTE(x,y) PASTE_(x,y) + +#define TYPE HitTpl + +// Add tests for base types and instantiated template classes with HitObjects + +struct HitStruct { + float4 f; + dx::HitObject hit; +}; + +struct HitStructSub : HitStruct { + int3 is; +}; + +template +struct HitTpl { + float4 f; + T val; +}; + +TYPE global_type; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} +// expected-note@23{{'dx::HitObject' field declared here}} +dx::HitObject global_hit; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} +dx::HitObject global_hit_arr[10]; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + +static TYPE static_gv; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in global variables}} +// expected-note@23{{'dx::HitObject' field declared here}} + +cbuffer BadBuffy { + dx::HitObject cb_hit; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + dx::HitObject cb_hit_arr[10]; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} +}; + +tbuffer BadTuffy { + dx::HitObject tb_vec; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + dx::HitObject tb_vec_arr[10]; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + TYPE tb_vec_rec; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-note@23{{'dx::HitObject' field declared here}} + TYPE tb_vec_rec_arr[10]; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-note@23{{'dx::HitObject' field declared here}} +}; + +StructuredBuffer struct_buf; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in structured buffers}} +// expected-note@23{{'dx::HitObject' field declared here}} +RWStructuredBuffer rw_struct_buf; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in structured buffers}} +// expected-note@23{{'dx::HitObject' field declared here}} +ConstantBuffer const_buf; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in ConstantBuffers or TextureBuffers}} +// expected-note@23{{'dx::HitObject' field declared here}} +TextureBuffer tex_buf; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in ConstantBuffers or TextureBuffers}} +// expected-note@23{{'dx::HitObject' field declared here}} + +ByteAddressBuffer bab; +RWByteAddressBuffer rw_bab; + +[Shader("raygeneration")] +void main() +{ + bab.Load(0); + // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} + rw_bab.Load(0); + // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} + TYPE val; + rw_bab.Store(0, val); + // expected-error@-1{{Explicit template arguments on intrinsic Store must be a single numeric type}} +} + +[shader("pixel")] +TYPE ps_main( +// expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function return type}} +// expected-note@23{{'dx::HitObject' field declared here}} + TYPE vec : V) : SV_Target { + // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@23{{'dx::HitObject' field declared here}} + return vec; +} + +[shader("vertex")] +TYPE vs_main( +// expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function return type}} +// expected-note@23{{'dx::HitObject' field declared here}} + TYPE parm : P) : SV_Target { + // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@23{{'dx::HitObject' field declared here}} + parm.f = 0; + return parm; +} + + +[shader("geometry")] +[maxvertexcount(3)] +void gs_point( + line TYPE e, + // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@23{{'dx::HitObject' field declared here}} + inout PointStream OutputStream0) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in geometry streams}} + // expected-note@23{{'dx::HitObject' field declared here}} +{} + +[shader("geometry")] +[maxvertexcount(12)] +void gs_line( + line TYPE a, + // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@23{{'dx::HitObject' field declared here}} + inout LineStream OutputStream0) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in geometry streams}} + // expected-note@23{{'dx::HitObject' field declared here}} +{} + + +[shader("geometry")] +[maxvertexcount(12)] +void gs_line( + line TYPE a, + // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@23{{'dx::HitObject' field declared here}} + inout TriangleStream OutputStream0) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in geometry streams}} + // expected-note@23{{'dx::HitObject' field declared here}} +{} + +[shader("domain")] +[domain("tri")] +void ds_main( + OutputPatch TrianglePatch) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} + // expected-note@23{{'dx::HitObject' field declared here}} +{} + +void patch_const( + InputPatch inpatch, + // expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} + // expected-note@23{{'dx::HitObject' field declared here}} + OutputPatch outpatch) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} + // expected-note@23{{'dx::HitObject' field declared here}} +{} + +[shader("hull")] +[domain("tri")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(32)] +[patchconstantfunc("patch_const")] +void hs_main(InputPatch TrianglePatch) {} +// expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} +// expected-note@23{{'dx::HitObject' field declared here}} + +RaytracingAccelerationStructure RTAS; + +struct [raypayload] DXRHitStruct { + float4 f : write(closesthit) : read(caller); + TYPE hit : write(closesthit) : read(caller); +}; + +struct [raypayload] DXRHitStructSub : DXRHitStruct { + int3 is : write(closesthit) : read(caller); +}; + +template +struct [raypayload] DXRHitTpl { + float4 f : write(closesthit) : read(caller); + T hit : write(closesthit) : read(caller); +}; + +#define RTTYPE PASTE(DXR,TYPE) + + +TYPE userFunc(TYPE arg) { + return arg; +} + +[shader("raygeneration")] +void raygen() { + RTTYPE p = (RTTYPE)0; + RayDesc ray = (RayDesc)0; + TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@182{{'dx::HitObject' field declared here}} + CallShader(0, p); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@182{{'dx::HitObject' field declared here}} + TYPE val; + TYPE res = userFunc(val); +} + +[shader("closesthit")] +void closesthit( + inout RTTYPE payload, + // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@182{{'dx::HitObject' field declared here}} + in RTTYPE attribs) { + // expected-error@-1{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} + // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@182{{'dx::HitObject' field declared here}} + RayDesc ray; + TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@182{{'dx::HitObject' field declared here}} + CallShader(0, payload); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@182{{'dx::HitObject' field declared here}} +} + +[shader("anyhit")] +void AnyHit( + inout RTTYPE payload, + // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@182{{'dx::HitObject' field declared here}} + in RTTYPE attribs) + // expected-error@-1{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} + // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@182{{'dx::HitObject' field declared here}} +{ +} + +[shader("miss")] +void Miss( + inout RTTYPE payload){ + // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} + // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@182{{'dx::HitObject' field declared here}} + RayDesc ray; + TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@182{{'dx::HitObject' field declared here}} + CallShader(0, payload); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@182{{'dx::HitObject' field declared here}} +} + +[shader("intersection")] +void Intersection() { + float hitT = RayTCurrent(); + RTTYPE attr = (RTTYPE)0; + bool bReported = ReportHit(hitT, 0, attr); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@182{{'dx::HitObject' field declared here}} +} + +[shader("callable")] +void callable1( + inout RTTYPE p) { + // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-note@182{{'dx::HitObject' field declared here}} + // expected-error@-3{{callable parameter 'p' must be a user-defined type composed of only numeric types}} + CallShader(0, p); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@182{{'dx::HitObject' field declared here}} +} + +static groupshared TYPE gs_var; +// expected-error@-1{{object ''dx::HitObject'' is not allowed in groupshared variables}} +// expected-note@23{{'dx::HitObject' field declared here}} +// expected-error@-3{{object ''dx::HitObject'' is not allowed in global variables}} +// expected-note@23{{'dx::HitObject' field declared here}} + +[shader("amplification")] +[numthreads(1,1,1)] +void Amp() { + TYPE as_pld; + DispatchMesh(1,1,1,as_pld); + // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-note@23{{'dx::HitObject' field declared here}} +} + +struct NodeHitStruct { + uint3 grid : SV_DispatchGrid; + TYPE hit; +}; + +struct NodeHitStructSub : NodeHitStruct { + int3 is; +}; + +template +struct NodeHitTpl { + uint3 grid : SV_DispatchGrid; + T hit; +}; + +#define NTYPE PASTE(Node,TYPE) + +[Shader("node")] +[NodeLaunch("broadcasting")] +[NumThreads(8,1,1)] +[NodeMaxDispatchGrid(8, 1, 1)] +void broadcast( +// expected-error@-1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} + DispatchNodeInputRecord input, + // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-note@300{{'dx::HitObject' field declared here}} + NodeOutput output) + // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-note@23{{'dx::HitObject' field declared here}} +{ + ThreadNodeOutputRecords touts; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-note@23{{'dx::HitObject' field declared here}} + GroupNodeOutputRecords gouts; + // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-note@23{{'dx::HitObject' field declared here}} +} + +[Shader("node")] +[NodeLaunch("coalescing")] +[NumThreads(8,1,1)] +void coalesce(GroupNodeInputRecords input) {} +// expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} +// expected-note@23{{'dx::HitObject' field declared here}} + +[Shader("node")] +[NodeLaunch("thread")] +void threader(ThreadNodeInputRecord input) {} +// expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} +// expected-note@23{{'dx::HitObject' field declared here}} diff --git a/tools/clang/test/SemaHLSL/hlsl/workgraph/invalid_node_record_type.hlsl b/tools/clang/test/SemaHLSL/hlsl/workgraph/invalid_node_record_type.hlsl index 40b820a1b4..2bd1db8dfd 100644 --- a/tools/clang/test/SemaHLSL/hlsl/workgraph/invalid_node_record_type.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/workgraph/invalid_node_record_type.hlsl @@ -76,7 +76,7 @@ void node07(RWThreadNodeInputRecord input) // expected-error {{'f2x2' (aka [Shader("node")] [NodeLaunch("thread")] -void node08(ThreadNodeInputRecord input) // expected-error {{object 'SamplerState' may not appear in a node record}} +void node08(ThreadNodeInputRecord input) // expected-error {{object ''SamplerState'' is not allowed in node records}} { } [Shader("node")] @@ -86,17 +86,17 @@ void node09(ThreadNodeInputRecord input) // expected-error {{'BAD [Shader("node")] [NodeLaunch("thread")] -void node10(RWThreadNodeInputRecord input) // expected-error {{object 'SamplerState' may not appear in a node record}} +void node10(RWThreadNodeInputRecord input) // expected-error {{object ''SamplerState'' is not allowed in node records}} { } [Shader("node")] [NodeLaunch("thread")] -void node11(NodeOutput input) // expected-error {{object 'SamplerState' may not appear in a node record}} +void node11(NodeOutput input) // expected-error {{object ''SamplerState'' is not allowed in node records}} { } [Shader("node")] [NodeLaunch("thread")] -void node12(NodeOutputArray output) // expected-error {{object 'SamplerState' may not appear in a node record}} +void node12(NodeOutputArray output) // expected-error {{object ''SamplerState'' is not allowed in node records}} { } [Shader("node")] @@ -129,7 +129,7 @@ void node16() ThreadNodeOutputRecords outrec2; // expected-error {{'f2x2' (aka 'matrix') is not valid as a node record type - struct/class required}} - GroupNodeOutputRecords outrec3; // expected-error {{object 'SamplerState' may not appear in a node record}} + GroupNodeOutputRecords outrec3; // expected-error {{object ''SamplerState'' is not allowed in node records}} ThreadNodeOutputRecords outrec4; // expected-error {{'SamplerState' is not valid as a node record type - struct/class required}} } @@ -151,10 +151,10 @@ void node17(ThreadNodeInputRecord > input) [Shader("node")] [NodeLaunch("thread")] -void node18(ThreadNodeInputRecord > input) // expected-error {{object 'SamplerState' may not appear in a node record}} +void node18(ThreadNodeInputRecord > input) // expected-error {{object ''SamplerState'' is not allowed in node records}} { } [Shader("node")] [NodeLaunch("thread")] -void node19(RWThreadNodeInputRecord input) // expected-error {{object 'SamplerState' may not appear in a node record}} +void node19(RWThreadNodeInputRecord input) // expected-error {{object ''SamplerState'' is not allowed in node records}} { } diff --git a/tools/clang/test/SemaHLSL/template-checks.hlsl b/tools/clang/test/SemaHLSL/template-checks.hlsl index d0d736fc1f..ebc79e13e8 100644 --- a/tools/clang/test/SemaHLSL/template-checks.hlsl +++ b/tools/clang/test/SemaHLSL/template-checks.hlsl @@ -1,8 +1,8 @@ // RUN: %dxc -Tlib_6_3 -verify %s Texture2D t_float4; -Texture2D t_obj_sampler; /* expected-error {{'SamplerState' is an object and cannot be used as a type parameter}} fxc-error {{X3124: object element type cannot be an object type}} */ -Texture2D > t_obj_tex; /* expected-error {{'Texture2D' is an object and cannot be used as a type parameter}} fxc-error {{X3124: object element type cannot be an object type}} */ +Texture2D t_obj_sampler; /* expected-error {{object ''SamplerState'' is not allowed in type parameters}} fxc-error {{X3124: object element type cannot be an object type}} */ +Texture2D > t_obj_tex; /* expected-error {{object ''Texture2D'' is not allowed in type parameters}} fxc-error {{X3124: object element type cannot be an object type}} */ matrix m_obj_sampler; /* expected-error {{'SamplerState' cannot be used as a type parameter where a scalar is required}} fxc-error {{X3123: matrix element type must be a scalar type}} */ matrix m_bool; @@ -15,7 +15,7 @@ matrix m_bool; RWBuffer rwb_struct; /* expected-error {{elements of typed buffers and textures must fit in four 32-bit quantities}} fxc-error {{X3037: elements of typed buffers and textures must fit in four 32-bit quantities}} */ -RWBuffer rwb_struct_objs; /* expected-error {{'SamplerState' is an object and cannot be used as a type parameter}} */ +RWBuffer rwb_struct_objs; /* expected-error {{object ''SamplerState'' is not allowed in type parameters}} */ void vain() { // Nothing to do here. From 2c128effee33d146df8ac1e3e4ae76055d032cff Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Fri, 9 May 2025 12:56:53 +0200 Subject: [PATCH 03/29] Remove redundant '' around %0 in unsupported_object_context diag msg --- .../clang/Basic/DiagnosticSemaKinds.td | 2 +- .../HitObject/hitobject-in-buffer.hlsl | 2 +- .../hitobject_traceinvoke_payload_udt.hlsl | 2 +- .../types/invalid-hitobject-decls-hs.hlsl | 6 +- .../types/invalid-hitobject-decls-struct.hlsl | 102 +++++++++--------- .../invalid-hitobject-decls-templated.hlsl | 102 +++++++++--------- .../workgraph/invalid_node_record_type.hlsl | 14 +-- .../clang/test/SemaHLSL/template-checks.hlsl | 6 +- 8 files changed, 118 insertions(+), 118 deletions(-) diff --git a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1dba16ffeb..e8854dffed 100644 --- a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7886,7 +7886,7 @@ def err_hlsl_unsupported_long_vector "payload parameters|attributes}0 are not supported">; // %select options must be compatible with err_hlsl_unsupported_long_vector (same index used) def err_hlsl_unsupported_object_context - : Error<"object '%0' is not allowed in " + : Error<"object %0 is not allowed in " "%select{ConstantBuffers or TextureBuffers|" "tessellation patches|geometry streams|node records|" "cbuffers or tbuffers|user-defined struct parameter|" diff --git a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject-in-buffer.hlsl b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject-in-buffer.hlsl index 05eb6d4f54..b091bd2ac5 100644 --- a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject-in-buffer.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject-in-buffer.hlsl @@ -1,4 +1,4 @@ // RUN: %dxc -T lib_6_9 %s -verify -// expected-error@+1{{object ''dx::HitObject'' is not allowed in structured buffers}} +// expected-error@+1{{object 'dx::HitObject' is not allowed in structured buffers}} RWStructuredBuffer InvalidBuffer; diff --git a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl index 29b93fd16e..50587d09e7 100644 --- a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl @@ -16,7 +16,7 @@ struct Attribs [shader("raygeneration")] void RayGen() { - // expected-error@+2{{object ''dx::HitObject'' is not allowed in payload parameters}} + // expected-error@+2{{object 'dx::HitObject' is not allowed in payload parameters}} // expected-note@8{{'dx::HitObject' field declared here}} Payload payload_in_rg; dx::HitObject::Invoke( dx::HitObject(), payload_in_rg ); diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-hs.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-hs.hlsl index 485b149886..3a4457bd5f 100644 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-hs.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-hs.hlsl @@ -12,12 +12,12 @@ struct LongVec { HsConstantData PatchConstantFunction( - // expected-error@-1{{object ''dx::HitObject'' is not allowed in patch constant function return type}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in patch constant function return type}} // expected-note@5{{'dx::HitObject' field declared here}} dx::HitObject hit : V, - // expected-error@-1{{object ''dx::HitObject'' is not allowed in patch constant function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in patch constant function parameters}} LongVec lv : L) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in patch constant function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in patch constant function parameters}} // expected-note@10{{'dx::HitObject' field declared here}} { HsConstantData empty; diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl index e59fc8ec7a..660429be45 100644 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl @@ -27,48 +27,48 @@ struct HitTpl { }; TYPE global_type; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} // expected-note@16{{'dx::HitObject' field declared here}} dx::HitObject global_hit; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} dx::HitObject global_hit_arr[10]; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} static TYPE static_gv; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in global variables}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in global variables}} // expected-note@16{{'dx::HitObject' field declared here}} cbuffer BadBuffy { dx::HitObject cb_hit; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} dx::HitObject cb_hit_arr[10]; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} }; tbuffer BadTuffy { dx::HitObject tb_vec; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} dx::HitObject tb_vec_arr[10]; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} TYPE tb_vec_rec; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} // expected-note@16{{'dx::HitObject' field declared here}} TYPE tb_vec_rec_arr[10]; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} // expected-note@16{{'dx::HitObject' field declared here}} }; StructuredBuffer struct_buf; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in structured buffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in structured buffers}} // expected-note@16{{'dx::HitObject' field declared here}} RWStructuredBuffer rw_struct_buf; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in structured buffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in structured buffers}} // expected-note@16{{'dx::HitObject' field declared here}} ConstantBuffer const_buf; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in ConstantBuffers or TextureBuffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in ConstantBuffers or TextureBuffers}} // expected-note@16{{'dx::HitObject' field declared here}} TextureBuffer tex_buf; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in ConstantBuffers or TextureBuffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in ConstantBuffers or TextureBuffers}} // expected-note@16{{'dx::HitObject' field declared here}} ByteAddressBuffer bab; @@ -88,20 +88,20 @@ void main() [shader("pixel")] TYPE ps_main( -// expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function return type}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in entry function return type}} // expected-note@16{{'dx::HitObject' field declared here}} TYPE vec : V) : SV_Target { - // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@16{{'dx::HitObject' field declared here}} return vec; } [shader("vertex")] TYPE vs_main( -// expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function return type}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in entry function return type}} // expected-note@16{{'dx::HitObject' field declared here}} TYPE parm : P) : SV_Target { - // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@16{{'dx::HitObject' field declared here}} parm.f = 0; return parm; @@ -112,10 +112,10 @@ TYPE vs_main( [maxvertexcount(3)] void gs_point( line TYPE e, - // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@16{{'dx::HitObject' field declared here}} inout PointStream OutputStream0) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in geometry streams}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in geometry streams}} // expected-note@16{{'dx::HitObject' field declared here}} {} @@ -123,10 +123,10 @@ void gs_point( [maxvertexcount(12)] void gs_line( line TYPE a, - // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@16{{'dx::HitObject' field declared here}} inout LineStream OutputStream0) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in geometry streams}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in geometry streams}} // expected-note@16{{'dx::HitObject' field declared here}} {} @@ -135,10 +135,10 @@ void gs_line( [maxvertexcount(12)] void gs_line( line TYPE a, - // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@16{{'dx::HitObject' field declared here}} inout TriangleStream OutputStream0) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in geometry streams}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in geometry streams}} // expected-note@16{{'dx::HitObject' field declared here}} {} @@ -146,16 +146,16 @@ void gs_line( [domain("tri")] void ds_main( OutputPatch TrianglePatch) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} // expected-note@16{{'dx::HitObject' field declared here}} {} void patch_const( InputPatch inpatch, - // expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} // expected-note@16{{'dx::HitObject' field declared here}} OutputPatch outpatch) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} // expected-note@16{{'dx::HitObject' field declared here}} {} @@ -165,7 +165,7 @@ void patch_const( [outputcontrolpoints(32)] [patchconstantfunc("patch_const")] void hs_main(InputPatch TrianglePatch) {} -// expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} // expected-note@16{{'dx::HitObject' field declared here}} RaytracingAccelerationStructure RTAS; @@ -197,10 +197,10 @@ void raygen() { RTTYPE p = (RTTYPE)0; RayDesc ray = (RayDesc)0; TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@16{{'dx::HitObject' field declared here}} CallShader(0, p); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@16{{'dx::HitObject' field declared here}} TYPE val; TYPE res = userFunc(val); @@ -210,18 +210,18 @@ void raygen() { void closesthit( inout RTTYPE payload, // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@16{{'dx::HitObject' field declared here}} in RTTYPE attribs) { // expected-error@-1{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} - // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@16{{'dx::HitObject' field declared here}} RayDesc ray; TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@16{{'dx::HitObject' field declared here}} CallShader(0, payload); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@16{{'dx::HitObject' field declared here}} } @@ -229,11 +229,11 @@ void closesthit( void AnyHit( inout RTTYPE payload, // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@16{{'dx::HitObject' field declared here}} in RTTYPE attribs) // expected-error@-1{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} - // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@16{{'dx::HitObject' field declared here}} { } @@ -242,14 +242,14 @@ void AnyHit( void Miss( inout RTTYPE payload){ // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@16{{'dx::HitObject' field declared here}} RayDesc ray; TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@16{{'dx::HitObject' field declared here}} CallShader(0, payload); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@16{{'dx::HitObject' field declared here}} } @@ -258,25 +258,25 @@ void Intersection() { float hitT = RayTCurrent(); RTTYPE attr = (RTTYPE)0; bool bReported = ReportHit(hitT, 0, attr); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@16{{'dx::HitObject' field declared here}} } [shader("callable")] void callable1( inout RTTYPE p) { - // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@16{{'dx::HitObject' field declared here}} // expected-error@-3{{callable parameter 'p' must be a user-defined type composed of only numeric types}} CallShader(0, p); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@16{{'dx::HitObject' field declared here}} } static groupshared TYPE gs_var; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in groupshared variables}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in groupshared variables}} // expected-note@16{{'dx::HitObject' field declared here}} -// expected-error@-3{{object ''dx::HitObject'' is not allowed in global variables}} +// expected-error@-3{{object 'dx::HitObject' is not allowed in global variables}} // expected-note@16{{'dx::HitObject' field declared here}} [shader("amplification")] @@ -284,7 +284,7 @@ static groupshared TYPE gs_var; void Amp() { TYPE as_pld; DispatchMesh(1,1,1,as_pld); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@16{{'dx::HitObject' field declared here}} } @@ -312,17 +312,17 @@ struct NodeHitTpl { void broadcast( // expected-error@-1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} DispatchNodeInputRecord input, - // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@16{{'dx::HitObject' field declared here}} NodeOutput output) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@16{{'dx::HitObject' field declared here}} { ThreadNodeOutputRecords touts; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@16{{'dx::HitObject' field declared here}} GroupNodeOutputRecords gouts; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@16{{'dx::HitObject' field declared here}} } @@ -330,11 +330,11 @@ void broadcast( [NodeLaunch("coalescing")] [NumThreads(8,1,1)] void coalesce(GroupNodeInputRecords input) {} -// expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@16{{'dx::HitObject' field declared here}} [Shader("node")] [NodeLaunch("thread")] void threader(ThreadNodeInputRecord input) {} -// expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@16{{'dx::HitObject' field declared here}} diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl index 5d6325c289..c960323f46 100644 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl @@ -24,48 +24,48 @@ struct HitTpl { }; TYPE global_type; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} // expected-note@23{{'dx::HitObject' field declared here}} dx::HitObject global_hit; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} dx::HitObject global_hit_arr[10]; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} static TYPE static_gv; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in global variables}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in global variables}} // expected-note@23{{'dx::HitObject' field declared here}} cbuffer BadBuffy { dx::HitObject cb_hit; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} dx::HitObject cb_hit_arr[10]; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} }; tbuffer BadTuffy { dx::HitObject tb_vec; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} dx::HitObject tb_vec_arr[10]; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} TYPE tb_vec_rec; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} // expected-note@23{{'dx::HitObject' field declared here}} TYPE tb_vec_rec_arr[10]; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in cbuffers or tbuffers}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} // expected-note@23{{'dx::HitObject' field declared here}} }; StructuredBuffer struct_buf; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in structured buffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in structured buffers}} // expected-note@23{{'dx::HitObject' field declared here}} RWStructuredBuffer rw_struct_buf; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in structured buffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in structured buffers}} // expected-note@23{{'dx::HitObject' field declared here}} ConstantBuffer const_buf; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in ConstantBuffers or TextureBuffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in ConstantBuffers or TextureBuffers}} // expected-note@23{{'dx::HitObject' field declared here}} TextureBuffer tex_buf; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in ConstantBuffers or TextureBuffers}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in ConstantBuffers or TextureBuffers}} // expected-note@23{{'dx::HitObject' field declared here}} ByteAddressBuffer bab; @@ -85,20 +85,20 @@ void main() [shader("pixel")] TYPE ps_main( -// expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function return type}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in entry function return type}} // expected-note@23{{'dx::HitObject' field declared here}} TYPE vec : V) : SV_Target { - // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@23{{'dx::HitObject' field declared here}} return vec; } [shader("vertex")] TYPE vs_main( -// expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function return type}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in entry function return type}} // expected-note@23{{'dx::HitObject' field declared here}} TYPE parm : P) : SV_Target { - // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@23{{'dx::HitObject' field declared here}} parm.f = 0; return parm; @@ -109,10 +109,10 @@ TYPE vs_main( [maxvertexcount(3)] void gs_point( line TYPE e, - // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@23{{'dx::HitObject' field declared here}} inout PointStream OutputStream0) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in geometry streams}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in geometry streams}} // expected-note@23{{'dx::HitObject' field declared here}} {} @@ -120,10 +120,10 @@ void gs_point( [maxvertexcount(12)] void gs_line( line TYPE a, - // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@23{{'dx::HitObject' field declared here}} inout LineStream OutputStream0) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in geometry streams}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in geometry streams}} // expected-note@23{{'dx::HitObject' field declared here}} {} @@ -132,10 +132,10 @@ void gs_line( [maxvertexcount(12)] void gs_line( line TYPE a, - // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@23{{'dx::HitObject' field declared here}} inout TriangleStream OutputStream0) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in geometry streams}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in geometry streams}} // expected-note@23{{'dx::HitObject' field declared here}} {} @@ -143,16 +143,16 @@ void gs_line( [domain("tri")] void ds_main( OutputPatch TrianglePatch) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} // expected-note@23{{'dx::HitObject' field declared here}} {} void patch_const( InputPatch inpatch, - // expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} // expected-note@23{{'dx::HitObject' field declared here}} OutputPatch outpatch) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} // expected-note@23{{'dx::HitObject' field declared here}} {} @@ -162,7 +162,7 @@ void patch_const( [outputcontrolpoints(32)] [patchconstantfunc("patch_const")] void hs_main(InputPatch TrianglePatch) {} -// expected-error@-1{{object ''dx::HitObject'' is not allowed in tessellation patches}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} // expected-note@23{{'dx::HitObject' field declared here}} RaytracingAccelerationStructure RTAS; @@ -194,10 +194,10 @@ void raygen() { RTTYPE p = (RTTYPE)0; RayDesc ray = (RayDesc)0; TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@182{{'dx::HitObject' field declared here}} CallShader(0, p); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@182{{'dx::HitObject' field declared here}} TYPE val; TYPE res = userFunc(val); @@ -207,18 +207,18 @@ void raygen() { void closesthit( inout RTTYPE payload, // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@182{{'dx::HitObject' field declared here}} in RTTYPE attribs) { // expected-error@-1{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} - // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@182{{'dx::HitObject' field declared here}} RayDesc ray; TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@182{{'dx::HitObject' field declared here}} CallShader(0, payload); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@182{{'dx::HitObject' field declared here}} } @@ -226,11 +226,11 @@ void closesthit( void AnyHit( inout RTTYPE payload, // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@182{{'dx::HitObject' field declared here}} in RTTYPE attribs) // expected-error@-1{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} - // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@182{{'dx::HitObject' field declared here}} { } @@ -239,14 +239,14 @@ void AnyHit( void Miss( inout RTTYPE payload){ // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} - // expected-error@-2{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@182{{'dx::HitObject' field declared here}} RayDesc ray; TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@182{{'dx::HitObject' field declared here}} CallShader(0, payload); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@182{{'dx::HitObject' field declared here}} } @@ -255,25 +255,25 @@ void Intersection() { float hitT = RayTCurrent(); RTTYPE attr = (RTTYPE)0; bool bReported = ReportHit(hitT, 0, attr); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@182{{'dx::HitObject' field declared here}} } [shader("callable")] void callable1( inout RTTYPE p) { - // expected-error@-1{{object ''dx::HitObject'' is not allowed in entry function parameters}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@182{{'dx::HitObject' field declared here}} // expected-error@-3{{callable parameter 'p' must be a user-defined type composed of only numeric types}} CallShader(0, p); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@182{{'dx::HitObject' field declared here}} } static groupshared TYPE gs_var; -// expected-error@-1{{object ''dx::HitObject'' is not allowed in groupshared variables}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in groupshared variables}} // expected-note@23{{'dx::HitObject' field declared here}} -// expected-error@-3{{object ''dx::HitObject'' is not allowed in global variables}} +// expected-error@-3{{object 'dx::HitObject' is not allowed in global variables}} // expected-note@23{{'dx::HitObject' field declared here}} [shader("amplification")] @@ -281,7 +281,7 @@ static groupshared TYPE gs_var; void Amp() { TYPE as_pld; DispatchMesh(1,1,1,as_pld); - // expected-error@-1{{object ''dx::HitObject'' is not allowed in user-defined struct parameter}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} // expected-note@23{{'dx::HitObject' field declared here}} } @@ -309,17 +309,17 @@ struct NodeHitTpl { void broadcast( // expected-error@-1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} DispatchNodeInputRecord input, - // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@300{{'dx::HitObject' field declared here}} NodeOutput output) - // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@23{{'dx::HitObject' field declared here}} { ThreadNodeOutputRecords touts; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@23{{'dx::HitObject' field declared here}} GroupNodeOutputRecords gouts; - // expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} + // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@23{{'dx::HitObject' field declared here}} } @@ -327,11 +327,11 @@ void broadcast( [NodeLaunch("coalescing")] [NumThreads(8,1,1)] void coalesce(GroupNodeInputRecords input) {} -// expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@23{{'dx::HitObject' field declared here}} [Shader("node")] [NodeLaunch("thread")] void threader(ThreadNodeInputRecord input) {} -// expected-error@-1{{object ''dx::HitObject'' is not allowed in node records}} +// expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@23{{'dx::HitObject' field declared here}} diff --git a/tools/clang/test/SemaHLSL/hlsl/workgraph/invalid_node_record_type.hlsl b/tools/clang/test/SemaHLSL/hlsl/workgraph/invalid_node_record_type.hlsl index 2bd1db8dfd..de523d51d1 100644 --- a/tools/clang/test/SemaHLSL/hlsl/workgraph/invalid_node_record_type.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/workgraph/invalid_node_record_type.hlsl @@ -76,7 +76,7 @@ void node07(RWThreadNodeInputRecord input) // expected-error {{'f2x2' (aka [Shader("node")] [NodeLaunch("thread")] -void node08(ThreadNodeInputRecord input) // expected-error {{object ''SamplerState'' is not allowed in node records}} +void node08(ThreadNodeInputRecord input) // expected-error {{object 'SamplerState' is not allowed in node records}} { } [Shader("node")] @@ -86,17 +86,17 @@ void node09(ThreadNodeInputRecord input) // expected-error {{'BAD [Shader("node")] [NodeLaunch("thread")] -void node10(RWThreadNodeInputRecord input) // expected-error {{object ''SamplerState'' is not allowed in node records}} +void node10(RWThreadNodeInputRecord input) // expected-error {{object 'SamplerState' is not allowed in node records}} { } [Shader("node")] [NodeLaunch("thread")] -void node11(NodeOutput input) // expected-error {{object ''SamplerState'' is not allowed in node records}} +void node11(NodeOutput input) // expected-error {{object 'SamplerState' is not allowed in node records}} { } [Shader("node")] [NodeLaunch("thread")] -void node12(NodeOutputArray output) // expected-error {{object ''SamplerState'' is not allowed in node records}} +void node12(NodeOutputArray output) // expected-error {{object 'SamplerState' is not allowed in node records}} { } [Shader("node")] @@ -129,7 +129,7 @@ void node16() ThreadNodeOutputRecords outrec2; // expected-error {{'f2x2' (aka 'matrix') is not valid as a node record type - struct/class required}} - GroupNodeOutputRecords outrec3; // expected-error {{object ''SamplerState'' is not allowed in node records}} + GroupNodeOutputRecords outrec3; // expected-error {{object 'SamplerState' is not allowed in node records}} ThreadNodeOutputRecords outrec4; // expected-error {{'SamplerState' is not valid as a node record type - struct/class required}} } @@ -151,10 +151,10 @@ void node17(ThreadNodeInputRecord > input) [Shader("node")] [NodeLaunch("thread")] -void node18(ThreadNodeInputRecord > input) // expected-error {{object ''SamplerState'' is not allowed in node records}} +void node18(ThreadNodeInputRecord > input) // expected-error {{object 'SamplerState' is not allowed in node records}} { } [Shader("node")] [NodeLaunch("thread")] -void node19(RWThreadNodeInputRecord input) // expected-error {{object ''SamplerState'' is not allowed in node records}} +void node19(RWThreadNodeInputRecord input) // expected-error {{object 'SamplerState' is not allowed in node records}} { } diff --git a/tools/clang/test/SemaHLSL/template-checks.hlsl b/tools/clang/test/SemaHLSL/template-checks.hlsl index ebc79e13e8..4db2ebc369 100644 --- a/tools/clang/test/SemaHLSL/template-checks.hlsl +++ b/tools/clang/test/SemaHLSL/template-checks.hlsl @@ -1,8 +1,8 @@ // RUN: %dxc -Tlib_6_3 -verify %s Texture2D t_float4; -Texture2D t_obj_sampler; /* expected-error {{object ''SamplerState'' is not allowed in type parameters}} fxc-error {{X3124: object element type cannot be an object type}} */ -Texture2D > t_obj_tex; /* expected-error {{object ''Texture2D'' is not allowed in type parameters}} fxc-error {{X3124: object element type cannot be an object type}} */ +Texture2D t_obj_sampler; /* expected-error {{object 'SamplerState' is not allowed in type parameters}} fxc-error {{X3124: object element type cannot be an object type}} */ +Texture2D > t_obj_tex; /* expected-error {{object 'Texture2D' is not allowed in type parameters}} fxc-error {{X3124: object element type cannot be an object type}} */ matrix m_obj_sampler; /* expected-error {{'SamplerState' cannot be used as a type parameter where a scalar is required}} fxc-error {{X3123: matrix element type must be a scalar type}} */ matrix m_bool; @@ -15,7 +15,7 @@ matrix m_bool; RWBuffer rwb_struct; /* expected-error {{elements of typed buffers and textures must fit in four 32-bit quantities}} fxc-error {{X3037: elements of typed buffers and textures must fit in four 32-bit quantities}} */ -RWBuffer rwb_struct_objs; /* expected-error {{object ''SamplerState'' is not allowed in type parameters}} */ +RWBuffer rwb_struct_objs; /* expected-error {{object 'SamplerState' is not allowed in type parameters}} */ void vain() { // Nothing to do here. From e39fe2fa82cbb7687186fe9e1f61d123c613a9fb Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Fri, 9 May 2025 18:50:13 +0200 Subject: [PATCH 04/29] 'type parameters' -> 'builtin template parameters' --- tools/clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- tools/clang/test/SemaHLSL/template-checks.hlsl | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index e8854dffed..ce20b1684f 100644 --- a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7892,7 +7892,7 @@ def err_hlsl_unsupported_object_context "cbuffers or tbuffers|user-defined struct parameter|" "entry function parameters|entry function return type|" "patch constant function parameters|patch constant function return type|" - "payload parameters|attributes|type parameters|structured buffers|global variables|groupshared variables}1">; + "payload parameters|attributes|builtin template parameters|structured buffers|global variables|groupshared variables}1">; def err_hlsl_logical_binop_scalar : Error< "operands for short-circuiting logical binary operator must be scalar, for non-scalar types use '%select{and|or}0'">; def err_hlsl_ternary_scalar : Error< diff --git a/tools/clang/test/SemaHLSL/template-checks.hlsl b/tools/clang/test/SemaHLSL/template-checks.hlsl index 4db2ebc369..751e89b652 100644 --- a/tools/clang/test/SemaHLSL/template-checks.hlsl +++ b/tools/clang/test/SemaHLSL/template-checks.hlsl @@ -1,8 +1,8 @@ // RUN: %dxc -Tlib_6_3 -verify %s Texture2D t_float4; -Texture2D t_obj_sampler; /* expected-error {{object 'SamplerState' is not allowed in type parameters}} fxc-error {{X3124: object element type cannot be an object type}} */ -Texture2D > t_obj_tex; /* expected-error {{object 'Texture2D' is not allowed in type parameters}} fxc-error {{X3124: object element type cannot be an object type}} */ +Texture2D t_obj_sampler; /* expected-error {{object 'SamplerState' is not allowed in builtin template parameters}} fxc-error {{X3124: object element type cannot be an object type}} */ +Texture2D > t_obj_tex; /* expected-error {{object 'Texture2D' is not allowed in builtin template parameters}} fxc-error {{X3124: object element type cannot be an object type}} */ matrix m_obj_sampler; /* expected-error {{'SamplerState' cannot be used as a type parameter where a scalar is required}} fxc-error {{X3123: matrix element type must be a scalar type}} */ matrix m_bool; @@ -15,7 +15,7 @@ matrix m_bool; RWBuffer rwb_struct; /* expected-error {{elements of typed buffers and textures must fit in four 32-bit quantities}} fxc-error {{X3037: elements of typed buffers and textures must fit in four 32-bit quantities}} */ -RWBuffer rwb_struct_objs; /* expected-error {{object 'SamplerState' is not allowed in type parameters}} */ +RWBuffer rwb_struct_objs; /* expected-error {{object 'SamplerState' is not allowed in builtin template parameters}} */ void vain() { // Nothing to do here. From 92bb7fc7c20b60b7ed263782eeb16f14722ef263 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 06:24:37 +0200 Subject: [PATCH 05/29] Update tools/clang/include/clang/Basic/DiagnosticSemaKinds.td Co-authored-by: Greg Roth --- tools/clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index ce20b1684f..003aa50795 100644 --- a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7884,7 +7884,7 @@ def err_hlsl_unsupported_long_vector "entry function parameters|entry function return type|" "patch constant function parameters|patch constant function return type|" "payload parameters|attributes}0 are not supported">; -// %select options must be compatible with err_hlsl_unsupported_long_vector (same index used) +// First %select options must match err_hlsl_unsupported_long_vector (same index used) def err_hlsl_unsupported_object_context : Error<"object %0 is not allowed in " "%select{ConstantBuffers or TextureBuffers|" From 6bb2dbfabbe36890c12e35b45e53ff48eb3a9a44 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 06:31:33 +0200 Subject: [PATCH 06/29] Update tools/clang/lib/Sema/SemaHLSL.cpp Co-authored-by: Greg Roth --- tools/clang/lib/Sema/SemaHLSL.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 179e92ebc9..e0c158b597 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -17069,9 +17069,8 @@ void DiagnoseEntry(Sema &S, FunctionDecl *FD) { } if (ContainsLongVector(FD->getReturnType())) { - const unsigned EntryFunctionReturnIdx = 7; S.Diag(FD->getLocation(), diag::err_hlsl_unsupported_long_vector) - << EntryFunctionReturnIdx; + << TypeDiagContext::EntryFunctionReturnType; } DiagnoseTypeElements(S, FD->getLocation(), FD->getReturnType(), TypeDiagContext::EntryFunctionReturnType); From e0e063ad936ac91ad1e8df88ec53ec7ec486c8a4 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 06:31:40 +0200 Subject: [PATCH 07/29] Update tools/clang/lib/Sema/SemaHLSL.cpp Co-authored-by: Greg Roth --- tools/clang/lib/Sema/SemaHLSL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index e0c158b597..92d686e04a 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -15407,7 +15407,7 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth, const unsigned CbuffersOrTbuffersIdx = 4; if (ContainsLongVector(qt)) { Diag(D.getLocStart(), diag::err_hlsl_unsupported_long_vector) - << CbuffersOrTbuffersIdx; + << TypeDiagContext::CbuffersOrTbuffers; result = false; } From c039f8c41063468caa95e6fecd838f85e56a0f54 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 06:31:55 +0200 Subject: [PATCH 08/29] Update tools/clang/lib/Sema/SemaHLSL.cpp Co-authored-by: Greg Roth --- tools/clang/lib/Sema/SemaHLSL.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 92d686e04a..59c297c0fa 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -15404,7 +15404,6 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth, // Disallow long vecs from $Global cbuffers. if (isGlobal && !isStatic && !isGroupShared && !IS_BASIC_OBJECT(basicKind)) { - const unsigned CbuffersOrTbuffersIdx = 4; if (ContainsLongVector(qt)) { Diag(D.getLocStart(), diag::err_hlsl_unsupported_long_vector) << TypeDiagContext::CbuffersOrTbuffers; From 2a7b39cd70f6e4b3ebfd6c2e4ce42ae0436c9ff7 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 06:32:16 +0200 Subject: [PATCH 09/29] Update tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp Co-authored-by: Greg Roth --- tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp b/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp index 92aaefab53..dc2c4137fc 100644 --- a/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp +++ b/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp @@ -714,7 +714,7 @@ void hlsl::DiagnoseTranslationUnit(clang::Sema *self) { if (ContainsLongVector(param->getType())) self->Diag(param->getLocation(), diag::err_hlsl_unsupported_long_vector) - << PatchConstantFunctionParametersIdx; + << TypeDiagContext::PatchConstantFunctionParameters; DiagnoseTypeElements(*self, param->getLocation(), param->getType(), TypeDiagContext::PatchConstantFunctionParameters); } From 21447bc083f5fddb6cc85c2b5d8892bf88169777 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 06:32:32 +0200 Subject: [PATCH 10/29] Update tools/clang/lib/Sema/SemaHLSL.cpp Co-authored-by: Greg Roth --- tools/clang/lib/Sema/SemaHLSL.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 59c297c0fa..8c4adfd632 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -5681,7 +5681,6 @@ class HLSLExternalSource : public ExternalSemaSource { CXXRecordDecl *Decl = arg.getAsType()->getAsCXXRecordDecl(); if (Decl && !Decl->isCompleteDefinition()) return true; - const unsigned GeometryStreamsIdx = 2; if (ContainsLongVector(arg.getAsType())) { m_sema->Diag(argLoc.getLocation(), diag::err_hlsl_unsupported_long_vector) From 2be84a2fc60faf1b681ecd0c26498e24eb4dadb7 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 06:32:47 +0200 Subject: [PATCH 11/29] Update tools/clang/lib/Sema/SemaHLSL.cpp Co-authored-by: Greg Roth --- tools/clang/lib/Sema/SemaHLSL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 8c4adfd632..62ac46f01a 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -5684,7 +5684,7 @@ class HLSLExternalSource : public ExternalSemaSource { if (ContainsLongVector(arg.getAsType())) { m_sema->Diag(argLoc.getLocation(), diag::err_hlsl_unsupported_long_vector) - << GeometryStreamsIdx; + << TypeDiagContext::GeometryStreams; return true; } if (DiagnoseTypeElements(*m_sema, argLoc.getLocation(), arg.getAsType(), From 85746fbb37a3c10b8a32389c8d50bb5a12b923d2 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 06:32:58 +0200 Subject: [PATCH 12/29] Update tools/clang/lib/Sema/SemaHLSL.cpp Co-authored-by: Greg Roth --- tools/clang/lib/Sema/SemaHLSL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 62ac46f01a..90aee79990 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -5663,7 +5663,7 @@ class HLSLExternalSource : public ExternalSemaSource { const unsigned TessellationPatchesIDx = 1; m_sema->Diag(argLoc.getLocation(), diag::err_hlsl_unsupported_long_vector) - << TessellationPatchesIDx; + << TypeDiagContext::TessellationPatches; return true; } if (DiagnoseTypeElements(*m_sema, argLoc.getLocation(), arg.getAsType(), From 36d678c0896a9a56c2af67fd761c94a4dd52954f Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 06:33:11 +0200 Subject: [PATCH 13/29] Update tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl Co-authored-by: Greg Roth --- .../SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl index 660429be45..8030946a59 100644 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl @@ -133,8 +133,8 @@ void gs_line( [shader("geometry")] [maxvertexcount(12)] -void gs_line( - line TYPE a, +void gs_tri( + triangle TYPE a, // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} // expected-note@16{{'dx::HitObject' field declared here}} inout TriangleStream OutputStream0) From 96c6b8c16f0e2d2a8ff7db9aec8d770de1c29663 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 06:33:29 +0200 Subject: [PATCH 14/29] Update tools/clang/lib/Sema/SemaHLSL.cpp Co-authored-by: Greg Roth --- tools/clang/lib/Sema/SemaHLSL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 90aee79990..2312910abe 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -5538,7 +5538,7 @@ class HLSLExternalSource : public ExternalSemaSource { if (ContainsLongVector(argType)) { const unsigned ConstantBuffersOrTextureBuffersIdx = 0; m_sema->Diag(argSrcLoc, diag::err_hlsl_unsupported_long_vector) - << ConstantBuffersOrTextureBuffersIdx; + << TypeDiagContext::ConstantBuffersOrTextureBuffers; return true; } if (DiagnoseTypeElements( From c07e5480b89f0c5f683a0947935ce92d3dd0d8cb Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 06:50:42 +0200 Subject: [PATCH 15/29] static_cast(TypeDiagContext) --- tools/clang/lib/Sema/SemaHLSL.cpp | 21 ++++++++------------- tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp | 6 ++---- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 2312910abe..cc41120537 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -5536,9 +5536,8 @@ class HLSLExternalSource : public ExternalSemaSource { diag::err_typecheck_decl_incomplete_type); if (ContainsLongVector(argType)) { - const unsigned ConstantBuffersOrTextureBuffersIdx = 0; m_sema->Diag(argSrcLoc, diag::err_hlsl_unsupported_long_vector) - << TypeDiagContext::ConstantBuffersOrTextureBuffers; + << static_cast(TypeDiagContext::ConstantBuffersOrTextureBuffers); return true; } if (DiagnoseTypeElements( @@ -5660,10 +5659,9 @@ class HLSLExternalSource : public ExternalSemaSource { if (Decl && !Decl->isCompleteDefinition()) return true; if (ContainsLongVector(arg.getAsType())) { - const unsigned TessellationPatchesIDx = 1; m_sema->Diag(argLoc.getLocation(), diag::err_hlsl_unsupported_long_vector) - << TypeDiagContext::TessellationPatches; + << static_cast(TypeDiagContext::TessellationPatches); return true; } if (DiagnoseTypeElements(*m_sema, argLoc.getLocation(), arg.getAsType(), @@ -5684,7 +5682,7 @@ class HLSLExternalSource : public ExternalSemaSource { if (ContainsLongVector(arg.getAsType())) { m_sema->Diag(argLoc.getLocation(), diag::err_hlsl_unsupported_long_vector) - << TypeDiagContext::GeometryStreams; + << static_cast(TypeDiagContext::GeometryStreams); return true; } if (DiagnoseTypeElements(*m_sema, argLoc.getLocation(), arg.getAsType(), @@ -10808,8 +10806,7 @@ bool DiagnoseIntersectionAttributes(Sema &S, SourceLocation Loc, QualType Ty) { } if (ContainsLongVector(Ty)) { - const unsigned AttributesIdx = 11; - S.Diag(Loc, diag::err_hlsl_unsupported_long_vector) << AttributesIdx; + S.Diag(Loc, diag::err_hlsl_unsupported_long_vector) << static_cast(TypeDiagContext::Attributes); return false; } return true; @@ -15405,7 +15402,7 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth, if (isGlobal && !isStatic && !isGroupShared && !IS_BASIC_OBJECT(basicKind)) { if (ContainsLongVector(qt)) { Diag(D.getLocStart(), diag::err_hlsl_unsupported_long_vector) - << TypeDiagContext::CbuffersOrTbuffers; + << static_cast(TypeDiagContext::CBuffersOrTBuffers); result = false; } @@ -16314,9 +16311,8 @@ static bool isRelatedDeclMarkedNointerpolation(Expr *E) { // Verify that user-defined intrinsic struct args contain no long vectors static bool CheckUDTIntrinsicArg(Sema *S, Expr *Arg) { if (ContainsLongVector(Arg->getType())) { - const unsigned UserDefinedStructParameterIdx = 5; S->Diag(Arg->getExprLoc(), diag::err_hlsl_unsupported_long_vector) - << UserDefinedStructParameterIdx; + << static_cast(TypeDiagContext::UserDefinedStructParameter); return true; } return DiagnoseTypeElements(*S, Arg->getExprLoc(), Arg->getType(), @@ -17058,9 +17054,8 @@ void DiagnoseEntry(Sema &S, FunctionDecl *FD) { // See issue #7186. for (const auto *param : FD->params()) { if (ContainsLongVector(param->getType())) { - const unsigned EntryFunctionParametersIdx = 6; S.Diag(param->getLocation(), diag::err_hlsl_unsupported_long_vector) - << EntryFunctionParametersIdx; + << static_cast(TypeDiagContext::EntryFunctionParameters); } hlsl::DiagnoseTypeElements(S, param->getLocation(), param->getType(), TypeDiagContext::EntryFunctionParameters); @@ -17068,7 +17063,7 @@ void DiagnoseEntry(Sema &S, FunctionDecl *FD) { if (ContainsLongVector(FD->getReturnType())) { S.Diag(FD->getLocation(), diag::err_hlsl_unsupported_long_vector) - << TypeDiagContext::EntryFunctionReturnType; + << static_cast(TypeDiagContext::EntryFunctionReturnType); } DiagnoseTypeElements(S, FD->getLocation(), FD->getReturnType(), TypeDiagContext::EntryFunctionReturnType); diff --git a/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp b/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp index dc2c4137fc..c1ea0b589f 100644 --- a/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp +++ b/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp @@ -710,20 +710,18 @@ void hlsl::DiagnoseTranslationUnit(clang::Sema *self) { } } for (const auto *param : pPatchFnDecl->params()) { - const unsigned PatchConstantFunctionParametersIdx = 8; if (ContainsLongVector(param->getType())) self->Diag(param->getLocation(), diag::err_hlsl_unsupported_long_vector) - << TypeDiagContext::PatchConstantFunctionParameters; + << static_cast(TypeDiagContext::PatchConstantFunctionParameters); DiagnoseTypeElements(*self, param->getLocation(), param->getType(), TypeDiagContext::PatchConstantFunctionParameters); } if (ContainsLongVector(pPatchFnDecl->getReturnType())) { - const unsigned PatchConstantFunctionReturnIdx = 9; self->Diag(pPatchFnDecl->getLocation(), diag::err_hlsl_unsupported_long_vector) - << PatchConstantFunctionReturnIdx; + << static_cast(TypeDiagContext::PatchConstantFunctionReturnType); } DiagnoseTypeElements(*self, pPatchFnDecl->getLocation(), pPatchFnDecl->getReturnType(), From 004dc1da6f8bcd75fb6adc562bb0fba974049723 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 06:58:39 +0200 Subject: [PATCH 16/29] Default case: accept as non-Empty and add comment that only recursive types need to be checked --- tools/clang/lib/Sema/SemaHLSL.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index cc41120537..bbe03d61e3 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -12235,6 +12235,8 @@ DiagnoseElementTypes(Sema &S, SourceLocation Loc, QualType Ty, bool &Empty, return ErrorFound; } default: + // Not a recursive type, no element types to check here + Empty = false; return false; } } From 244c59cd9582b9213c932e7c6764bcf869c93836 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 07:20:23 +0200 Subject: [PATCH 17/29] Update tools/clang/lib/Sema/SemaHLSL.cpp Co-authored-by: Greg Roth --- tools/clang/lib/Sema/SemaHLSL.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index bbe03d61e3..fb89f45172 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -12166,6 +12166,11 @@ static bool AllowObjectInContext(QualType Ty, TypeDiagContext DiagContext) { return true; } +// Determine if `Ty` is valid and/or empty. If invalid returns false and Sema `S`, location `Loc`, +// error index `DiagContext`, and FieldDecl `FD` are used to emit diagnostics. +// If `CheckLongVec` is set, errors are produced if `Ty` is a long vector. +// If the type is not empty, `Empty` is set to false. +// `CheckedDecls` is used to prevent redundant recursive type checks. static bool DiagnoseElementTypes(Sema &S, SourceLocation Loc, QualType Ty, bool &Empty, bool CheckLongVec, TypeDiagContext DiagContext, From fa895f7f4fe431f7e0505a03ea3762d9ce800ee2 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 07:23:05 +0200 Subject: [PATCH 18/29] function description --- tools/clang/lib/Sema/SemaHLSL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index fb89f45172..40d1e52197 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -12166,7 +12166,7 @@ static bool AllowObjectInContext(QualType Ty, TypeDiagContext DiagContext) { return true; } -// Determine if `Ty` is valid and/or empty. If invalid returns false and Sema `S`, location `Loc`, +// Determine if `Ty` is valid in this `DiagContext` and/or an empty type. If invalid returns false and Sema `S`, location `Loc`, // error index `DiagContext`, and FieldDecl `FD` are used to emit diagnostics. // If `CheckLongVec` is set, errors are produced if `Ty` is a long vector. // If the type is not empty, `Empty` is set to false. From 9db0556e6eb17c432ae13701f506e0384b5c8591 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 07:23:27 +0200 Subject: [PATCH 19/29] Clang format --- tools/clang/lib/Sema/SemaHLSL.cpp | 17 ++++++++++------- tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp | 6 ++++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 40d1e52197..36004d092c 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -5537,7 +5537,8 @@ class HLSLExternalSource : public ExternalSemaSource { if (ContainsLongVector(argType)) { m_sema->Diag(argSrcLoc, diag::err_hlsl_unsupported_long_vector) - << static_cast(TypeDiagContext::ConstantBuffersOrTextureBuffers); + << static_cast( + TypeDiagContext::ConstantBuffersOrTextureBuffers); return true; } if (DiagnoseTypeElements( @@ -10806,7 +10807,8 @@ bool DiagnoseIntersectionAttributes(Sema &S, SourceLocation Loc, QualType Ty) { } if (ContainsLongVector(Ty)) { - S.Diag(Loc, diag::err_hlsl_unsupported_long_vector) << static_cast(TypeDiagContext::Attributes); + S.Diag(Loc, diag::err_hlsl_unsupported_long_vector) + << static_cast(TypeDiagContext::Attributes); return false; } return true; @@ -12166,11 +12168,12 @@ static bool AllowObjectInContext(QualType Ty, TypeDiagContext DiagContext) { return true; } -// Determine if `Ty` is valid in this `DiagContext` and/or an empty type. If invalid returns false and Sema `S`, location `Loc`, -// error index `DiagContext`, and FieldDecl `FD` are used to emit diagnostics. -// If `CheckLongVec` is set, errors are produced if `Ty` is a long vector. -// If the type is not empty, `Empty` is set to false. -// `CheckedDecls` is used to prevent redundant recursive type checks. +// Determine if `Ty` is valid in this `DiagContext` and/or an empty type. If +// invalid returns false and Sema `S`, location `Loc`, error index +// `DiagContext`, and FieldDecl `FD` are used to emit diagnostics. If +// `CheckLongVec` is set, errors are produced if `Ty` is a long vector. If the +// type is not empty, `Empty` is set to false. `CheckedDecls` is used to prevent +// redundant recursive type checks. static bool DiagnoseElementTypes(Sema &S, SourceLocation Loc, QualType Ty, bool &Empty, bool CheckLongVec, TypeDiagContext DiagContext, diff --git a/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp b/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp index c1ea0b589f..6d876a9f1e 100644 --- a/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp +++ b/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp @@ -713,7 +713,8 @@ void hlsl::DiagnoseTranslationUnit(clang::Sema *self) { if (ContainsLongVector(param->getType())) self->Diag(param->getLocation(), diag::err_hlsl_unsupported_long_vector) - << static_cast(TypeDiagContext::PatchConstantFunctionParameters); + << static_cast( + TypeDiagContext::PatchConstantFunctionParameters); DiagnoseTypeElements(*self, param->getLocation(), param->getType(), TypeDiagContext::PatchConstantFunctionParameters); } @@ -721,7 +722,8 @@ void hlsl::DiagnoseTranslationUnit(clang::Sema *self) { if (ContainsLongVector(pPatchFnDecl->getReturnType())) { self->Diag(pPatchFnDecl->getLocation(), diag::err_hlsl_unsupported_long_vector) - << static_cast(TypeDiagContext::PatchConstantFunctionReturnType); + << static_cast( + TypeDiagContext::PatchConstantFunctionReturnType); } DiagnoseTypeElements(*self, pPatchFnDecl->getLocation(), pPatchFnDecl->getReturnType(), From e7f8c5a1d9dc02c34cf885cc8f7c35627d9cafc6 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 07:32:35 +0200 Subject: [PATCH 20/29] Assert TypeDiagContext enum value compatible with unsupported_long_vector --- tools/clang/include/clang/Sema/SemaHLSL.h | 4 ++++ tools/clang/lib/Sema/SemaHLSL.cpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/tools/clang/include/clang/Sema/SemaHLSL.h b/tools/clang/include/clang/Sema/SemaHLSL.h index c40cd48754..d0c4972cdb 100644 --- a/tools/clang/include/clang/Sema/SemaHLSL.h +++ b/tools/clang/include/clang/Sema/SemaHLSL.h @@ -61,6 +61,8 @@ bool DiagnoseNodeStructArgument(clang::Sema *self, // Keep this in sync with err_hlsl_unsupported_object in DiagnosticSemaKinds.td enum class TypeDiagContext { + // Supported indices for both `err_hlsl_unsupported_object_context` and + // `err_hlsl_unsupported_long_vector` ConstantBuffersOrTextureBuffers = 0, TessellationPatches = 1, GeometryStreams = 2, @@ -74,6 +76,8 @@ enum class TypeDiagContext { PayloadParameters = 10, Attributes = 11, TypeParameter = 12, + LongVecDiagMaxSelectIndex = TypeParameter, + // Below only supported for `err_hlsl_diag_unsupported_object_context` StructuredBuffers = 13, GlobalVariables = 14, GroupShared = 15, diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 36004d092c..ca5512b965 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -12195,6 +12195,9 @@ DiagnoseElementTypes(Sema &S, SourceLocation Loc, QualType Ty, bool &Empty, // into this function. Could fold all context-dependent long vector checks // into this function. if (CheckLongVec && GetHLSLVecSize(Ty) > DXIL::kDefaultMaxVectorLength) { + DXASSERT_NOMSG( + DiagContextIdx <= + static_cast(TypeDiagContext::LongVecDiagMaxSelectIndex)); S.Diag(Loc, diag::err_hlsl_unsupported_long_vector) << DiagContextIdx; Empty = false; return false; From fea88fb53b7c919f1071e1054cf23cf9e3b14f53 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 07:38:09 +0200 Subject: [PATCH 21/29] Update tools/clang/lib/Sema/SemaHLSL.cpp Co-authored-by: Greg Roth --- tools/clang/lib/Sema/SemaHLSL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index ca5512b965..746daa392d 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -12224,7 +12224,7 @@ DiagnoseElementTypes(Sema &S, SourceLocation Loc, QualType Ty, bool &Empty, case AR_TOBJ_COMPOUND: { bool ErrorFound = false; const RecordDecl *RD = Ty->getAs()->getDecl(); - // Never recurse infinitely into related subtypes + // Never recurse redundantly into related subtypes that have already been checked. if (!CheckedDecls.insert(RD).second) return false; From 701c6809b1872cddd59d1ef8c7f176fe954c3cc7 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 07:41:00 +0200 Subject: [PATCH 22/29] Fold isGroupShared in with isStatic/isGlobal diag case --- tools/clang/lib/Sema/SemaHLSL.cpp | 17 +++-------------- .../types/invalid-hitobject-decls-struct.hlsl | 2 -- .../invalid-hitobject-decls-templated.hlsl | 4 +--- 3 files changed, 4 insertions(+), 19 deletions(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 746daa392d..778b66dd1c 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -15382,19 +15382,6 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth, result = false; } - if (isGroupShared) { - // Suppress actual emitting of errors for incompletable types here - // They are redundant to those produced in ActOnUninitializedDecl. - struct SilentDiagnoser : public TypeDiagnoser { - SilentDiagnoser() : TypeDiagnoser(true) {} - virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {} - } SD; - RequireCompleteType(D.getLocStart(), qt, SD); - if (DiagnoseTypeElements(*this, D.getLocStart(), qt, - TypeDiagContext::GroupShared)) - result = false; - } - // Disallow intangible HLSL objects in the global scope. if (isGlobal) { // Suppress actual emitting of errors for incompletable types here @@ -15405,7 +15392,9 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth, } SD; RequireCompleteType(D.getLocStart(), qt, SD); TypeDiagContext DiagContext = TypeDiagContext::CBuffersOrTBuffers; - if (isStatic) + if (isGroupShared) + DiagContext = TypeDiagContext::GroupShared; + else if (isStatic) DiagContext = TypeDiagContext::GlobalVariables; if (DiagnoseTypeElements(*this, D.getLocStart(), qt, DiagContext)) result = false; diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl index 8030946a59..8b8c20fc1a 100644 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl @@ -276,8 +276,6 @@ void callable1( static groupshared TYPE gs_var; // expected-error@-1{{object 'dx::HitObject' is not allowed in groupshared variables}} // expected-note@16{{'dx::HitObject' field declared here}} -// expected-error@-3{{object 'dx::HitObject' is not allowed in global variables}} -// expected-note@16{{'dx::HitObject' field declared here}} [shader("amplification")] [numthreads(1,1,1)] diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl index c960323f46..cda6ac4e13 100644 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl @@ -273,8 +273,6 @@ void callable1( static groupshared TYPE gs_var; // expected-error@-1{{object 'dx::HitObject' is not allowed in groupshared variables}} // expected-note@23{{'dx::HitObject' field declared here}} -// expected-error@-3{{object 'dx::HitObject' is not allowed in global variables}} -// expected-note@23{{'dx::HitObject' field declared here}} [shader("amplification")] [numthreads(1,1,1)] @@ -310,7 +308,7 @@ void broadcast( // expected-error@-1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} DispatchNodeInputRecord input, // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} - // expected-note@300{{'dx::HitObject' field declared here}} + // expected-note@298{{'dx::HitObject' field declared here}} NodeOutput output) // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@23{{'dx::HitObject' field declared here}} From 001eb50fe21cacbafa245ed0157eb571facbdfe5 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 07:51:39 +0200 Subject: [PATCH 23/29] Clang format --- tools/clang/lib/Sema/SemaHLSL.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 778b66dd1c..03a9389422 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -12224,7 +12224,8 @@ DiagnoseElementTypes(Sema &S, SourceLocation Loc, QualType Ty, bool &Empty, case AR_TOBJ_COMPOUND: { bool ErrorFound = false; const RecordDecl *RD = Ty->getAs()->getDecl(); - // Never recurse redundantly into related subtypes that have already been checked. + // Never recurse redundantly into related subtypes that have already been + // checked. if (!CheckedDecls.insert(RD).second) return false; From ae98e48265fb1cafbb2f4383e5d61cacb94667e8 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 10:26:16 +0200 Subject: [PATCH 24/29] Fold unsupported_long_vec into DiagnoseElementTypes --- tools/clang/include/clang/Sema/SemaHLSL.h | 7 +- tools/clang/lib/Sema/SemaDXR.cpp | 10 +- tools/clang/lib/Sema/SemaHLSL.cpp | 142 +++++++++----------- tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp | 21 +-- 4 files changed, 78 insertions(+), 102 deletions(-) diff --git a/tools/clang/include/clang/Sema/SemaHLSL.h b/tools/clang/include/clang/Sema/SemaHLSL.h index d0c4972cdb..80ce8ddd7d 100644 --- a/tools/clang/include/clang/Sema/SemaHLSL.h +++ b/tools/clang/include/clang/Sema/SemaHLSL.h @@ -61,6 +61,9 @@ bool DiagnoseNodeStructArgument(clang::Sema *self, // Keep this in sync with err_hlsl_unsupported_object in DiagnosticSemaKinds.td enum class TypeDiagContext { + // Indices that the type context is valid and no diagnostics should be emitted + // for this type category. + Valid = -1, // Supported indices for both `err_hlsl_unsupported_object_context` and // `err_hlsl_unsupported_long_vector` ConstantBuffersOrTextureBuffers = 0, @@ -81,9 +84,11 @@ enum class TypeDiagContext { StructuredBuffers = 13, GlobalVariables = 14, GroupShared = 15, + DiagMaxSelectIndex = 15, }; bool DiagnoseTypeElements(clang::Sema &S, clang::SourceLocation Loc, - clang::QualType Ty, TypeDiagContext DiagContext, + clang::QualType Ty, TypeDiagContext ObjDiagContext, + TypeDiagContext LongVecDiagContext, const clang::FieldDecl *FD = nullptr); void DiagnoseControlFlowConditionForHLSL(clang::Sema *self, diff --git a/tools/clang/lib/Sema/SemaDXR.cpp b/tools/clang/lib/Sema/SemaDXR.cpp index efdf90b2be..6ccb7199f3 100644 --- a/tools/clang/lib/Sema/SemaDXR.cpp +++ b/tools/clang/lib/Sema/SemaDXR.cpp @@ -827,8 +827,9 @@ void DiagnoseBuiltinCallWithPayload(Sema &S, const VarDecl *Payload, } // Verify that the payload type is legal + const TypeDiagContext DiagContext = TypeDiagContext::PayloadParameters; if (DiagnoseTypeElements(S, Payload->getLocation(), Payload->getType(), - TypeDiagContext::PayloadParameters)) + DiagContext, DiagContext)) return; if (!hlsl::IsHLSLCopyableAnnotatableRecord(Payload->getType())) { S.Diag(Payload->getLocation(), diag::err_payload_attrs_must_be_udt) @@ -837,13 +838,6 @@ void DiagnoseBuiltinCallWithPayload(Sema &S, const VarDecl *Payload, return; } - if (ContainsLongVector(Payload->getType())) { - const unsigned PayloadParametersIdx = 10; - S.Diag(Payload->getLocation(), diag::err_hlsl_unsupported_long_vector) - << PayloadParametersIdx; - return; - } - CollectNonAccessableFields(PayloadType, CallerStage, {}, {}, NonWriteableFields, NonReadableFields); diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 03a9389422..6bff2fa39e 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -5535,15 +5535,10 @@ class HLSLExternalSource : public ExternalSemaSource { m_sema->RequireCompleteType(argSrcLoc, argType, diag::err_typecheck_decl_incomplete_type); - if (ContainsLongVector(argType)) { - m_sema->Diag(argSrcLoc, diag::err_hlsl_unsupported_long_vector) - << static_cast( - TypeDiagContext::ConstantBuffersOrTextureBuffers); - return true; - } - if (DiagnoseTypeElements( - *m_sema, argSrcLoc, argType, - TypeDiagContext::ConstantBuffersOrTextureBuffers)) + TypeDiagContext DiagContext = + TypeDiagContext::ConstantBuffersOrTextureBuffers; + if (DiagnoseTypeElements(*m_sema, argSrcLoc, argType, DiagContext, + DiagContext)) return true; } return false; @@ -5554,8 +5549,10 @@ class HLSLExternalSource : public ExternalSemaSource { if (Arg.getKind() == TemplateArgument::ArgKind::Type) { QualType ArgType = Arg.getAsType(); SourceLocation ArgSrcLoc = ArgLoc.getLocation(); - if (DiagnoseTypeElements(*m_sema, ArgSrcLoc, ArgType, - TypeDiagContext::StructuredBuffers)) + if (DiagnoseTypeElements( + *m_sema, ArgSrcLoc, ArgType, + TypeDiagContext::StructuredBuffers /*ObjDiagContext*/, + TypeDiagContext::Valid /*LongVecDiagContext*/)) return true; } } @@ -5659,14 +5656,9 @@ class HLSLExternalSource : public ExternalSemaSource { CXXRecordDecl *Decl = arg.getAsType()->getAsCXXRecordDecl(); if (Decl && !Decl->isCompleteDefinition()) return true; - if (ContainsLongVector(arg.getAsType())) { - m_sema->Diag(argLoc.getLocation(), - diag::err_hlsl_unsupported_long_vector) - << static_cast(TypeDiagContext::TessellationPatches); - return true; - } + const TypeDiagContext DiagContext = TypeDiagContext::TessellationPatches; if (DiagnoseTypeElements(*m_sema, argLoc.getLocation(), arg.getAsType(), - TypeDiagContext::TessellationPatches)) + DiagContext, DiagContext)) return true; } else if (Template->getTemplatedDecl()->hasAttr()) { DXASSERT(TemplateArgList.size() > 0, @@ -5680,14 +5672,9 @@ class HLSLExternalSource : public ExternalSemaSource { CXXRecordDecl *Decl = arg.getAsType()->getAsCXXRecordDecl(); if (Decl && !Decl->isCompleteDefinition()) return true; - if (ContainsLongVector(arg.getAsType())) { - m_sema->Diag(argLoc.getLocation(), - diag::err_hlsl_unsupported_long_vector) - << static_cast(TypeDiagContext::GeometryStreams); - return true; - } + const TypeDiagContext DiagContext = TypeDiagContext::GeometryStreams; if (DiagnoseTypeElements(*m_sema, argLoc.getLocation(), arg.getAsType(), - TypeDiagContext::GeometryStreams)) + DiagContext, DiagContext)) return true; } @@ -10806,11 +10793,9 @@ bool DiagnoseIntersectionAttributes(Sema &S, SourceLocation Loc, QualType Ty) { return false; } - if (ContainsLongVector(Ty)) { - S.Diag(Loc, diag::err_hlsl_unsupported_long_vector) - << static_cast(TypeDiagContext::Attributes); + const TypeDiagContext DiagContext = TypeDiagContext::Attributes; + if (DiagnoseTypeElements(S, Loc, Ty, DiagContext, DiagContext)) return false; - } return true; } @@ -10964,8 +10949,10 @@ HLSLExternalSource::DeduceTemplateArgumentsForHLSL( << intrinsicName; return Sema::TemplateDeductionResult::TDK_Invalid; } - if (DiagnoseTypeElements(*getSema(), Loc, functionTemplateTypeArg, - TypeDiagContext::TypeParameter)) + if (DiagnoseTypeElements( + *getSema(), Loc, functionTemplateTypeArg, + TypeDiagContext::TypeParameter /*ObjDiagContext*/, + TypeDiagContext::Valid /*LongVecDiagContext*/)) return Sema::TemplateDeductionResult::TDK_Invalid; } if (IsHitObjectGetAttributes && @@ -12176,29 +12163,34 @@ static bool AllowObjectInContext(QualType Ty, TypeDiagContext DiagContext) { // redundant recursive type checks. static bool DiagnoseElementTypes(Sema &S, SourceLocation Loc, QualType Ty, bool &Empty, - bool CheckLongVec, TypeDiagContext DiagContext, + TypeDiagContext ObjDiagContext, + TypeDiagContext LongVecDiagContext, llvm::SmallPtrSet &CheckedDecls, const clang::FieldDecl *FD) { if (Ty.isNull() || Ty->isDependentType()) return false; + const bool CheckLongVec = LongVecDiagContext != TypeDiagContext::Valid; + const bool CheckObjects = ObjDiagContext != TypeDiagContext::Valid; + while (const ArrayType *Arr = Ty->getAsArrayTypeUnsafe()) Ty = Arr->getElementType(); - const unsigned DiagContextIdx = static_cast(DiagContext); + const int ObjDiagContextIdx = static_cast(ObjDiagContext); + const int LongVecDiagContextIdx = static_cast(LongVecDiagContext); + DXASSERT_NOMSG( + LongVecDiagContext == TypeDiagContext::Valid || + (0 <= LongVecDiagContextIdx && + LongVecDiagContextIdx <= + static_cast(TypeDiagContext::LongVecDiagMaxSelectIndex))); HLSLExternalSource *Source = HLSLExternalSource::FromSema(&S); ArTypeObjectKind ShapeKind = Source->GetTypeObjectKind(Ty); switch (ShapeKind) { case AR_TOBJ_VECTOR: - // TODO: This is only here because DiagnoseNodeStructArgument got folded - // into this function. Could fold all context-dependent long vector checks - // into this function. if (CheckLongVec && GetHLSLVecSize(Ty) > DXIL::kDefaultMaxVectorLength) { - DXASSERT_NOMSG( - DiagContextIdx <= - static_cast(TypeDiagContext::LongVecDiagMaxSelectIndex)); - S.Diag(Loc, diag::err_hlsl_unsupported_long_vector) << DiagContextIdx; + S.Diag(Loc, diag::err_hlsl_unsupported_long_vector) + << LongVecDiagContextIdx; Empty = false; return false; } @@ -12209,10 +12201,10 @@ DiagnoseElementTypes(Sema &S, SourceLocation Loc, QualType Ty, bool &Empty, return false; case AR_TOBJ_OBJECT: Empty = false; - if (AllowObjectInContext(Ty, DiagContext)) + if (!CheckObjects || AllowObjectInContext(Ty, ObjDiagContext)) return false; S.Diag(Loc, diag::err_hlsl_unsupported_object_context) - << Ty << DiagContextIdx; + << Ty << ObjDiagContextIdx; if (FD) S.Diag(FD->getLocation(), diag::note_field_declared_here) << FD->getType() << FD->getSourceRange(); @@ -12232,8 +12224,8 @@ DiagnoseElementTypes(Sema &S, SourceLocation Loc, QualType Ty, bool &Empty, // Check the fields of the RecordDecl for (auto *ElemFD : RD->fields()) { ErrorFound |= - DiagnoseElementTypes(S, Loc, ElemFD->getType(), Empty, CheckLongVec, - DiagContext, CheckedDecls, ElemFD); + DiagnoseElementTypes(S, Loc, ElemFD->getType(), Empty, ObjDiagContext, + LongVecDiagContext, CheckedDecls, ElemFD); } if (!RD->isCompleteDefinition()) return ErrorFound; @@ -12242,8 +12234,8 @@ DiagnoseElementTypes(Sema &S, SourceLocation Loc, QualType Ty, bool &Empty, // Walk up the inheritance chain and check base class fields for (auto &B : Child->bases()) ErrorFound |= - DiagnoseElementTypes(S, Loc, B.getType(), Empty, CheckLongVec, - DiagContext, CheckedDecls, nullptr); + DiagnoseElementTypes(S, Loc, B.getType(), Empty, ObjDiagContext, + LongVecDiagContext, CheckedDecls, nullptr); return ErrorFound; } default: @@ -12254,12 +12246,13 @@ DiagnoseElementTypes(Sema &S, SourceLocation Loc, QualType Ty, bool &Empty, } bool hlsl::DiagnoseTypeElements(Sema &S, SourceLocation Loc, QualType Ty, - TypeDiagContext DiagContext, + TypeDiagContext ObjDiagContext, + TypeDiagContext LongVecDiagContext, const clang::FieldDecl *FD) { bool Empty = false; llvm::SmallPtrSet CheckedDecls; - return DiagnoseElementTypes(S, Loc, Ty, Empty, false /*CheckLongVec*/, - DiagContext, CheckedDecls, FD); + return DiagnoseElementTypes(S, Loc, Ty, Empty, ObjDiagContext, + LongVecDiagContext, CheckedDecls, FD); } bool hlsl::DiagnoseNodeStructArgument(Sema *self, TemplateArgumentLoc ArgLoc, @@ -12267,7 +12260,7 @@ bool hlsl::DiagnoseNodeStructArgument(Sema *self, TemplateArgumentLoc ArgLoc, const FieldDecl *FD) { llvm::SmallPtrSet CheckedDecls; return DiagnoseElementTypes(*self, ArgLoc.getLocation(), ArgTy, Empty, - true /*CheckLongVec*/, + TypeDiagContext::NodeRecords, TypeDiagContext::NodeRecords, CheckedDecls, FD); } @@ -15392,23 +15385,22 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth, virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {} } SD; RequireCompleteType(D.getLocStart(), qt, SD); - TypeDiagContext DiagContext = TypeDiagContext::CBuffersOrTBuffers; + + // Disallow objects in the global context + TypeDiagContext ObjDiagContext = TypeDiagContext::CBuffersOrTBuffers; if (isGroupShared) - DiagContext = TypeDiagContext::GroupShared; + ObjDiagContext = TypeDiagContext::GroupShared; else if (isStatic) - DiagContext = TypeDiagContext::GlobalVariables; - if (DiagnoseTypeElements(*this, D.getLocStart(), qt, DiagContext)) - result = false; - } + ObjDiagContext = TypeDiagContext::GlobalVariables; - // Disallow long vecs from $Global cbuffers. - if (isGlobal && !isStatic && !isGroupShared && !IS_BASIC_OBJECT(basicKind)) { - if (ContainsLongVector(qt)) { - Diag(D.getLocStart(), diag::err_hlsl_unsupported_long_vector) - << static_cast(TypeDiagContext::CBuffersOrTBuffers); + TypeDiagContext LongVecDiagContext = TypeDiagContext::Valid; + // Disallow long vecs from $Global cbuffers. + if (!isStatic && !isGroupShared && !IS_BASIC_OBJECT(basicKind)) + LongVecDiagContext = TypeDiagContext::CBuffersOrTBuffers; + if (DiagnoseTypeElements(*this, D.getLocStart(), qt, ObjDiagContext, + LongVecDiagContext)) result = false; - } } // SPIRV change starts @@ -16313,13 +16305,10 @@ static bool isRelatedDeclMarkedNointerpolation(Expr *E) { // Verify that user-defined intrinsic struct args contain no long vectors static bool CheckUDTIntrinsicArg(Sema *S, Expr *Arg) { - if (ContainsLongVector(Arg->getType())) { - S->Diag(Arg->getExprLoc(), diag::err_hlsl_unsupported_long_vector) - << static_cast(TypeDiagContext::UserDefinedStructParameter); - return true; - } + const TypeDiagContext DiagContext = + TypeDiagContext::UserDefinedStructParameter; return DiagnoseTypeElements(*S, Arg->getExprLoc(), Arg->getType(), - TypeDiagContext::UserDefinedStructParameter); + DiagContext, DiagContext); } static bool CheckIntrinsicGetAttributeAtVertex(Sema *S, FunctionDecl *FDecl, @@ -17056,20 +17045,15 @@ void DiagnoseEntry(Sema &S, FunctionDecl *FD) { // Would be nice to check for resources here as they crash the compiler now. // See issue #7186. for (const auto *param : FD->params()) { - if (ContainsLongVector(param->getType())) { - S.Diag(param->getLocation(), diag::err_hlsl_unsupported_long_vector) - << static_cast(TypeDiagContext::EntryFunctionParameters); - } + const TypeDiagContext DiagContext = + TypeDiagContext::EntryFunctionParameters; hlsl::DiagnoseTypeElements(S, param->getLocation(), param->getType(), - TypeDiagContext::EntryFunctionParameters); + DiagContext, DiagContext); } - if (ContainsLongVector(FD->getReturnType())) { - S.Diag(FD->getLocation(), diag::err_hlsl_unsupported_long_vector) - << static_cast(TypeDiagContext::EntryFunctionReturnType); - } - DiagnoseTypeElements(S, FD->getLocation(), FD->getReturnType(), - TypeDiagContext::EntryFunctionReturnType); + const TypeDiagContext DiagContext = TypeDiagContext::EntryFunctionReturnType; + DiagnoseTypeElements(S, FD->getLocation(), FD->getReturnType(), DiagContext, + DiagContext); DXIL::ShaderKind Stage = ShaderModel::KindFromFullName(shaderAttr->getStage()); diff --git a/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp b/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp index 6d876a9f1e..a3ca955802 100644 --- a/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp +++ b/tools/clang/lib/Sema/SemaHLSLDiagnoseTU.cpp @@ -710,24 +710,17 @@ void hlsl::DiagnoseTranslationUnit(clang::Sema *self) { } } for (const auto *param : pPatchFnDecl->params()) { - if (ContainsLongVector(param->getType())) - self->Diag(param->getLocation(), - diag::err_hlsl_unsupported_long_vector) - << static_cast( - TypeDiagContext::PatchConstantFunctionParameters); + const TypeDiagContext ParamDiagContext = + TypeDiagContext::PatchConstantFunctionParameters; DiagnoseTypeElements(*self, param->getLocation(), param->getType(), - TypeDiagContext::PatchConstantFunctionParameters); + ParamDiagContext, ParamDiagContext); } - if (ContainsLongVector(pPatchFnDecl->getReturnType())) { - self->Diag(pPatchFnDecl->getLocation(), - diag::err_hlsl_unsupported_long_vector) - << static_cast( - TypeDiagContext::PatchConstantFunctionReturnType); - } + const TypeDiagContext ReturnDiagContext = + TypeDiagContext::PatchConstantFunctionReturnType; DiagnoseTypeElements(*self, pPatchFnDecl->getLocation(), - pPatchFnDecl->getReturnType(), - TypeDiagContext::PatchConstantFunctionReturnType); + pPatchFnDecl->getReturnType(), ReturnDiagContext, + ReturnDiagContext); } DXIL::ShaderKind EntrySK = shaderModel->GetKind(); DXIL::NodeLaunchType NodeLaunchTy = DXIL::NodeLaunchType::Invalid; From 2fd825f2c5e7c9813acfd8bfa3306eb6f5b15e05 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Tue, 13 May 2025 10:38:01 +0200 Subject: [PATCH 25/29] Remove HLSLLongVector tracking bit (DiagnoseElementTypes descends into type instead) --- tools/clang/include/clang/AST/DeclCXX.h | 11 ----------- tools/clang/lib/AST/DeclCXX.cpp | 14 ++------------ tools/clang/lib/Sema/SemaHLSL.cpp | 15 --------------- tools/clang/lib/Sema/SemaTemplateInstantiate.cpp | 12 ------------ 4 files changed, 2 insertions(+), 50 deletions(-) diff --git a/tools/clang/include/clang/AST/DeclCXX.h b/tools/clang/include/clang/AST/DeclCXX.h index 36e0f99c82..3b07576545 100644 --- a/tools/clang/include/clang/AST/DeclCXX.h +++ b/tools/clang/include/clang/AST/DeclCXX.h @@ -465,10 +465,6 @@ class CXXRecordDecl : public RecordDecl { /// \brief Whether we are currently parsing base specifiers. bool IsParsingBaseSpecifiers : 1; - /// \brief Whether this class contains at least one member or base - /// class containing an HLSL vector longer than 4 elements. - bool HasHLSLLongVector : 1; - /// \brief The number of base class specifiers in Bases. unsigned NumBases; @@ -1022,13 +1018,6 @@ class CXXRecordDecl : public RecordDecl { return data().NeedOverloadResolutionForDestructor; } - // HLSL Change add HLSL Long vector bit. - /// \brief Determine whether this class contains an HLSL long vector - /// of over 4 elements. - bool hasHLSLLongVector() { return data().HasHLSLLongVector; } - /// \brief Set that this class contains an HLSL long vector of over 4 elements - bool setHasHLSLLongVector() { return data().HasHLSLLongVector = true; } - /// \brief Determine whether this class describes a lambda function object. bool isLambda() const { // An update record can't turn a non-lambda into a lambda. diff --git a/tools/clang/lib/AST/DeclCXX.cpp b/tools/clang/lib/AST/DeclCXX.cpp index baed44667f..8023a0a588 100644 --- a/tools/clang/lib/AST/DeclCXX.cpp +++ b/tools/clang/lib/AST/DeclCXX.cpp @@ -72,8 +72,8 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D) ImplicitCopyAssignmentHasConstParam(true), HasDeclaredCopyConstructorWithConstParam(false), HasDeclaredCopyAssignmentWithConstParam(false), IsLambda(false), - IsParsingBaseSpecifiers(false), HasHLSLLongVector(false), NumBases(0), - NumVBases(0), Bases(), VBases(), Definition(D), FirstFriend() {} + IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0), Bases(), + VBases(), Definition(D), FirstFriend() {} // HLSL Change End - Add HasLongVector and clang-format CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const { @@ -203,11 +203,6 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, if (!BaseClassDecl->isStandardLayout()) data().IsStandardLayout = false; - // HLSL Change Begin - Propagate presence of long vector to child classes. - if (BaseClassDecl->hasHLSLLongVector()) - data().HasHLSLLongVector = true; - // HLSL Change End - // Record if this base is the first non-literal field or base. if (!hasNonLiteralTypeFieldsOrBases() && !BaseType->isLiteralType(C)) data().HasNonLiteralTypeFieldsOrBases = true; @@ -389,11 +384,6 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) { data().NeedOverloadResolutionForMoveConstructor = true; data().NeedOverloadResolutionForDestructor = true; } - - // HLSL Change Begin - Propagate presence of long vector to child classes. - if (Subobj->hasHLSLLongVector()) - data().HasHLSLLongVector = true; - // HLSL Change End } /// Callback function for CXXRecordDecl::forallBases that acknowledges diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 6bff2fa39e..54b160a42c 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -12691,21 +12691,6 @@ bool hlsl::ShouldSkipNRVO(clang::Sema &sema, clang::QualType returnType, return false; } -bool hlsl::ContainsLongVector(QualType QT) { - if (QT.isNull() || QT->isDependentType()) - return false; - - while (const ArrayType *Arr = QT->getAsArrayTypeUnsafe()) - QT = Arr->getElementType(); - - if (CXXRecordDecl *Decl = QT->getAsCXXRecordDecl()) { - if (!Decl->isCompleteDefinition()) - return false; - return Decl->hasHLSLLongVector(); - } - return false; -} - bool hlsl::IsConversionToLessOrEqualElements( clang::Sema *self, const clang::ExprResult &sourceExpr, const clang::QualType &targetType, bool explicitConversion) { diff --git a/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp b/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp index 1eacedbb0b..a6ae05faa5 100644 --- a/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2139,18 +2139,6 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, SourceLocation(), SourceLocation(), nullptr); CheckCompletedCXXClass(Instantiation); - // HLSL Change Begin - set longvec bit for vectors of over 4 elements - ClassTemplateSpecializationDecl *Spec = - dyn_cast(Instantiation); - if (Spec && Spec->hasAttr()) { - const TemplateArgumentList &argList = Spec->getTemplateArgs(); - const TemplateArgument &arg1 = argList[1]; - llvm::APSInt vecSize = arg1.getAsIntegral(); - if (vecSize.getLimitedValue() > hlsl::DXIL::kDefaultMaxVectorLength) - Instantiation->setHasHLSLLongVector(); - } - // HLSL Change End - set longvec bit for vectors of over 4 elements - // Default arguments are parsed, if not instantiated. We can go instantiate // default arg exprs for default constructors if necessary now. ActOnFinishCXXMemberDefaultArgs(Instantiation); From 1b8af76424105717591a40022dbc6cca86474af1 Mon Sep 17 00:00:00 2001 From: Simon Moll Date: Thu, 15 May 2025 09:32:52 +0200 Subject: [PATCH 26/29] Update test after merge --- .../types/invalid-hitobject-decls-struct.hlsl | 4 +- .../invalid-hitobject-decls-substruct.hlsl | 335 ++++++++++++++++++ 2 files changed, 337 insertions(+), 2 deletions(-) create mode 100644 tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl index 8b8c20fc1a..42a767cc68 100644 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl @@ -1,5 +1,5 @@ // RUN: %dxc -T lib_6_9 -DTYPE=HitStruct -verify %s -// RUN: %dxc -T lib_6_9 -DTYPE=HitStructSub -verify %s + #define PASTE_(x,y) x##y @@ -77,7 +77,7 @@ RWByteAddressBuffer rw_bab; [Shader("raygeneration")] void main() { - bab.Load(0); + bab.Load(0); // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} rw_bab.Load(0); // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl new file mode 100644 index 0000000000..6247dfda3e --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl @@ -0,0 +1,335 @@ +// RUN: %dxc -T lib_6_9 -DTYPE=HitStructSub -verify %s + + + +#define PASTE_(x,y) x##y +#define PASTE(x,y) PASTE_(x,y) + +#ifndef TYPE +#define TYPE HitTpl +#endif + +// Add tests for base types and instantiated template classes with HitObjects + +struct HitStruct { + float4 f; + dx::HitObject hit; +}; + +struct HitStructSub : HitStruct { + int3 is; +}; + +template +struct HitTpl { + float4 f; + T val; +}; + +TYPE global_type; +// expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} +// expected-note@16{{'dx::HitObject' field declared here}} +dx::HitObject global_hit; +// expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} +dx::HitObject global_hit_arr[10]; +// expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} + +static TYPE static_gv; +// expected-error@-1{{object 'dx::HitObject' is not allowed in global variables}} +// expected-note@16{{'dx::HitObject' field declared here}} + +cbuffer BadBuffy { + dx::HitObject cb_hit; + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} + dx::HitObject cb_hit_arr[10]; + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} +}; + +tbuffer BadTuffy { + dx::HitObject tb_vec; + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} + dx::HitObject tb_vec_arr[10]; + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} + TYPE tb_vec_rec; + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} + // expected-note@16{{'dx::HitObject' field declared here}} + TYPE tb_vec_rec_arr[10]; + // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} + // expected-note@16{{'dx::HitObject' field declared here}} +}; + +StructuredBuffer struct_buf; +// expected-error@-1{{object 'dx::HitObject' is not allowed in structured buffers}} +// expected-note@16{{'dx::HitObject' field declared here}} +RWStructuredBuffer rw_struct_buf; +// expected-error@-1{{object 'dx::HitObject' is not allowed in structured buffers}} +// expected-note@16{{'dx::HitObject' field declared here}} +ConstantBuffer const_buf; +// expected-error@-1{{object 'dx::HitObject' is not allowed in ConstantBuffers or TextureBuffers}} +// expected-note@16{{'dx::HitObject' field declared here}} +TextureBuffer tex_buf; +// expected-error@-1{{object 'dx::HitObject' is not allowed in ConstantBuffers or TextureBuffers}} +// expected-note@16{{'dx::HitObject' field declared here}} + +ByteAddressBuffer bab; +RWByteAddressBuffer rw_bab; + +[Shader("raygeneration")] +void main() +{ + bab.Load(0); + // expected-error@-1{{object 'dx::HitObject' is not allowed in builtin template parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + rw_bab.Load(0); + // expected-error@-1{{object 'dx::HitObject' is not allowed in builtin template parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + TYPE val; + rw_bab.Store(0, val); + // expected-error@-1{{object 'dx::HitObject' is not allowed in builtin template parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} +} + +[shader("pixel")] +TYPE ps_main( +// expected-error@-1{{object 'dx::HitObject' is not allowed in entry function return type}} +// expected-note@16{{'dx::HitObject' field declared here}} + TYPE vec : V) : SV_Target { + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + return vec; +} + +[shader("vertex")] +TYPE vs_main( +// expected-error@-1{{object 'dx::HitObject' is not allowed in entry function return type}} +// expected-note@16{{'dx::HitObject' field declared here}} + TYPE parm : P) : SV_Target { + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + parm.f = 0; + return parm; +} + + +[shader("geometry")] +[maxvertexcount(3)] +void gs_point( + line TYPE e, + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + inout PointStream OutputStream0) + // expected-error@-1{{object 'dx::HitObject' is not allowed in geometry streams}} + // expected-note@16{{'dx::HitObject' field declared here}} +{} + +[shader("geometry")] +[maxvertexcount(12)] +void gs_line( + line TYPE a, + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + inout LineStream OutputStream0) + // expected-error@-1{{object 'dx::HitObject' is not allowed in geometry streams}} + // expected-note@16{{'dx::HitObject' field declared here}} +{} + + +[shader("geometry")] +[maxvertexcount(12)] +void gs_tri( + triangle TYPE a, + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + inout TriangleStream OutputStream0) + // expected-error@-1{{object 'dx::HitObject' is not allowed in geometry streams}} + // expected-note@16{{'dx::HitObject' field declared here}} +{} + +[shader("domain")] +[domain("tri")] +void ds_main( + OutputPatch TrianglePatch) + // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} + // expected-note@16{{'dx::HitObject' field declared here}} +{} + +void patch_const( + InputPatch inpatch, + // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} + // expected-note@16{{'dx::HitObject' field declared here}} + OutputPatch outpatch) + // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} + // expected-note@16{{'dx::HitObject' field declared here}} +{} + +[shader("hull")] +[domain("tri")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(32)] +[patchconstantfunc("patch_const")] +void hs_main(InputPatch TrianglePatch) {} +// expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} +// expected-note@16{{'dx::HitObject' field declared here}} + +RaytracingAccelerationStructure RTAS; + +struct [raypayload] DXRHitStruct { + float4 f : write(closesthit) : read(caller); + TYPE hit : write(closesthit) : read(caller); +}; + +struct [raypayload] DXRHitStructSub : DXRHitStruct { + int3 is : write(closesthit) : read(caller); +}; + +template +struct [raypayload] DXRHitTpl { + float4 f : write(closesthit) : read(caller); + T hit : write(closesthit) : read(caller); +}; + +#define RTTYPE PASTE(DXR,TYPE) + + +TYPE userFunc(TYPE arg) { + return arg; +} + +[shader("raygeneration")] +void raygen() { + RTTYPE p = (RTTYPE)0; + RayDesc ray = (RayDesc)0; + TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} + CallShader(0, p); + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} + TYPE val; + TYPE res = userFunc(val); +} + +[shader("closesthit")] +void closesthit( + inout RTTYPE payload, + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + in RTTYPE attribs) { + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + RayDesc ray; + TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} + CallShader(0, payload); + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} +} + +[shader("anyhit")] +void AnyHit( + inout RTTYPE payload, + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + in RTTYPE attribs) + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} +{ +} + +[shader("miss")] +void Miss( + inout RTTYPE payload){ + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + RayDesc ray; + TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} + CallShader(0, payload); + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} +} + +[shader("intersection")] +void Intersection() { + float hitT = RayTCurrent(); + RTTYPE attr = (RTTYPE)0; + bool bReported = ReportHit(hitT, 0, attr); + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} +} + +[shader("callable")] +void callable1( + inout RTTYPE p) { + // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + CallShader(0, p); + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} +} + +static groupshared TYPE gs_var; +// expected-error@-1{{object 'dx::HitObject' is not allowed in groupshared variables}} +// expected-note@16{{'dx::HitObject' field declared here}} + +[shader("amplification")] +[numthreads(1,1,1)] +void Amp() { + TYPE as_pld; + DispatchMesh(1,1,1,as_pld); + // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} + // expected-note@16{{'dx::HitObject' field declared here}} +} + +struct NodeHitStruct { + uint3 grid : SV_DispatchGrid; + TYPE hit; +}; + +struct NodeHitStructSub : NodeHitStruct { + int3 is; +}; + +template +struct NodeHitTpl { + uint3 grid : SV_DispatchGrid; + T hit; +}; + +#define NTYPE PASTE(Node,TYPE) + +[Shader("node")] +[NodeLaunch("broadcasting")] +[NumThreads(8,1,1)] +[NodeMaxDispatchGrid(8, 1, 1)] +void broadcast( +// expected-error@-1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} + DispatchNodeInputRecord input, + // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} + // expected-note@16{{'dx::HitObject' field declared here}} + NodeOutput output) + // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} + // expected-note@16{{'dx::HitObject' field declared here}} +{ + ThreadNodeOutputRecords touts; + // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} + // expected-note@16{{'dx::HitObject' field declared here}} + GroupNodeOutputRecords gouts; + // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} + // expected-note@16{{'dx::HitObject' field declared here}} +} + +[Shader("node")] +[NodeLaunch("coalescing")] +[NumThreads(8,1,1)] +void coalesce(GroupNodeInputRecords input) {} +// expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} +// expected-note@16{{'dx::HitObject' field declared here}} + +[Shader("node")] +[NodeLaunch("thread")] +void threader(ThreadNodeInputRecord input) {} +// expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} +// expected-note@16{{'dx::HitObject' field declared here}} From 36e9615c54720e6be004ce700b38e5a060465755 Mon Sep 17 00:00:00 2001 From: Tex Riddell Date: Thu, 15 May 2025 12:06:22 -0700 Subject: [PATCH 27/29] Revert "Update test after merge" This reverts commit 1b8af76424105717591a40022dbc6cca86474af1. --- .../types/invalid-hitobject-decls-struct.hlsl | 4 +- .../invalid-hitobject-decls-substruct.hlsl | 335 ------------------ 2 files changed, 2 insertions(+), 337 deletions(-) delete mode 100644 tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl index 42a767cc68..8b8c20fc1a 100644 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl @@ -1,5 +1,5 @@ // RUN: %dxc -T lib_6_9 -DTYPE=HitStruct -verify %s - +// RUN: %dxc -T lib_6_9 -DTYPE=HitStructSub -verify %s #define PASTE_(x,y) x##y @@ -77,7 +77,7 @@ RWByteAddressBuffer rw_bab; [Shader("raygeneration")] void main() { - bab.Load(0); + bab.Load(0); // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} rw_bab.Load(0); // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl deleted file mode 100644 index 6247dfda3e..0000000000 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-substruct.hlsl +++ /dev/null @@ -1,335 +0,0 @@ -// RUN: %dxc -T lib_6_9 -DTYPE=HitStructSub -verify %s - - - -#define PASTE_(x,y) x##y -#define PASTE(x,y) PASTE_(x,y) - -#ifndef TYPE -#define TYPE HitTpl -#endif - -// Add tests for base types and instantiated template classes with HitObjects - -struct HitStruct { - float4 f; - dx::HitObject hit; -}; - -struct HitStructSub : HitStruct { - int3 is; -}; - -template -struct HitTpl { - float4 f; - T val; -}; - -TYPE global_type; -// expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} -// expected-note@16{{'dx::HitObject' field declared here}} -dx::HitObject global_hit; -// expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} -dx::HitObject global_hit_arr[10]; -// expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} - -static TYPE static_gv; -// expected-error@-1{{object 'dx::HitObject' is not allowed in global variables}} -// expected-note@16{{'dx::HitObject' field declared here}} - -cbuffer BadBuffy { - dx::HitObject cb_hit; - // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} - dx::HitObject cb_hit_arr[10]; - // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} -}; - -tbuffer BadTuffy { - dx::HitObject tb_vec; - // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} - dx::HitObject tb_vec_arr[10]; - // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} - TYPE tb_vec_rec; - // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} - // expected-note@16{{'dx::HitObject' field declared here}} - TYPE tb_vec_rec_arr[10]; - // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} - // expected-note@16{{'dx::HitObject' field declared here}} -}; - -StructuredBuffer struct_buf; -// expected-error@-1{{object 'dx::HitObject' is not allowed in structured buffers}} -// expected-note@16{{'dx::HitObject' field declared here}} -RWStructuredBuffer rw_struct_buf; -// expected-error@-1{{object 'dx::HitObject' is not allowed in structured buffers}} -// expected-note@16{{'dx::HitObject' field declared here}} -ConstantBuffer const_buf; -// expected-error@-1{{object 'dx::HitObject' is not allowed in ConstantBuffers or TextureBuffers}} -// expected-note@16{{'dx::HitObject' field declared here}} -TextureBuffer tex_buf; -// expected-error@-1{{object 'dx::HitObject' is not allowed in ConstantBuffers or TextureBuffers}} -// expected-note@16{{'dx::HitObject' field declared here}} - -ByteAddressBuffer bab; -RWByteAddressBuffer rw_bab; - -[Shader("raygeneration")] -void main() -{ - bab.Load(0); - // expected-error@-1{{object 'dx::HitObject' is not allowed in builtin template parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} - rw_bab.Load(0); - // expected-error@-1{{object 'dx::HitObject' is not allowed in builtin template parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} - TYPE val; - rw_bab.Store(0, val); - // expected-error@-1{{object 'dx::HitObject' is not allowed in builtin template parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} -} - -[shader("pixel")] -TYPE ps_main( -// expected-error@-1{{object 'dx::HitObject' is not allowed in entry function return type}} -// expected-note@16{{'dx::HitObject' field declared here}} - TYPE vec : V) : SV_Target { - // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} - return vec; -} - -[shader("vertex")] -TYPE vs_main( -// expected-error@-1{{object 'dx::HitObject' is not allowed in entry function return type}} -// expected-note@16{{'dx::HitObject' field declared here}} - TYPE parm : P) : SV_Target { - // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} - parm.f = 0; - return parm; -} - - -[shader("geometry")] -[maxvertexcount(3)] -void gs_point( - line TYPE e, - // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} - inout PointStream OutputStream0) - // expected-error@-1{{object 'dx::HitObject' is not allowed in geometry streams}} - // expected-note@16{{'dx::HitObject' field declared here}} -{} - -[shader("geometry")] -[maxvertexcount(12)] -void gs_line( - line TYPE a, - // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} - inout LineStream OutputStream0) - // expected-error@-1{{object 'dx::HitObject' is not allowed in geometry streams}} - // expected-note@16{{'dx::HitObject' field declared here}} -{} - - -[shader("geometry")] -[maxvertexcount(12)] -void gs_tri( - triangle TYPE a, - // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} - inout TriangleStream OutputStream0) - // expected-error@-1{{object 'dx::HitObject' is not allowed in geometry streams}} - // expected-note@16{{'dx::HitObject' field declared here}} -{} - -[shader("domain")] -[domain("tri")] -void ds_main( - OutputPatch TrianglePatch) - // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} - // expected-note@16{{'dx::HitObject' field declared here}} -{} - -void patch_const( - InputPatch inpatch, - // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} - // expected-note@16{{'dx::HitObject' field declared here}} - OutputPatch outpatch) - // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} - // expected-note@16{{'dx::HitObject' field declared here}} -{} - -[shader("hull")] -[domain("tri")] -[outputtopology("triangle_cw")] -[outputcontrolpoints(32)] -[patchconstantfunc("patch_const")] -void hs_main(InputPatch TrianglePatch) {} -// expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} -// expected-note@16{{'dx::HitObject' field declared here}} - -RaytracingAccelerationStructure RTAS; - -struct [raypayload] DXRHitStruct { - float4 f : write(closesthit) : read(caller); - TYPE hit : write(closesthit) : read(caller); -}; - -struct [raypayload] DXRHitStructSub : DXRHitStruct { - int3 is : write(closesthit) : read(caller); -}; - -template -struct [raypayload] DXRHitTpl { - float4 f : write(closesthit) : read(caller); - T hit : write(closesthit) : read(caller); -}; - -#define RTTYPE PASTE(DXR,TYPE) - - -TYPE userFunc(TYPE arg) { - return arg; -} - -[shader("raygeneration")] -void raygen() { - RTTYPE p = (RTTYPE)0; - RayDesc ray = (RayDesc)0; - TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); - // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@16{{'dx::HitObject' field declared here}} - CallShader(0, p); - // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@16{{'dx::HitObject' field declared here}} - TYPE val; - TYPE res = userFunc(val); -} - -[shader("closesthit")] -void closesthit( - inout RTTYPE payload, - // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} - in RTTYPE attribs) { - // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} - RayDesc ray; - TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); - // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@16{{'dx::HitObject' field declared here}} - CallShader(0, payload); - // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@16{{'dx::HitObject' field declared here}} -} - -[shader("anyhit")] -void AnyHit( - inout RTTYPE payload, - // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} - in RTTYPE attribs) - // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} -{ -} - -[shader("miss")] -void Miss( - inout RTTYPE payload){ - // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} - RayDesc ray; - TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); - // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@16{{'dx::HitObject' field declared here}} - CallShader(0, payload); - // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@16{{'dx::HitObject' field declared here}} -} - -[shader("intersection")] -void Intersection() { - float hitT = RayTCurrent(); - RTTYPE attr = (RTTYPE)0; - bool bReported = ReportHit(hitT, 0, attr); - // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@16{{'dx::HitObject' field declared here}} -} - -[shader("callable")] -void callable1( - inout RTTYPE p) { - // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@16{{'dx::HitObject' field declared here}} - CallShader(0, p); - // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@16{{'dx::HitObject' field declared here}} -} - -static groupshared TYPE gs_var; -// expected-error@-1{{object 'dx::HitObject' is not allowed in groupshared variables}} -// expected-note@16{{'dx::HitObject' field declared here}} - -[shader("amplification")] -[numthreads(1,1,1)] -void Amp() { - TYPE as_pld; - DispatchMesh(1,1,1,as_pld); - // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@16{{'dx::HitObject' field declared here}} -} - -struct NodeHitStruct { - uint3 grid : SV_DispatchGrid; - TYPE hit; -}; - -struct NodeHitStructSub : NodeHitStruct { - int3 is; -}; - -template -struct NodeHitTpl { - uint3 grid : SV_DispatchGrid; - T hit; -}; - -#define NTYPE PASTE(Node,TYPE) - -[Shader("node")] -[NodeLaunch("broadcasting")] -[NumThreads(8,1,1)] -[NodeMaxDispatchGrid(8, 1, 1)] -void broadcast( -// expected-error@-1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} - DispatchNodeInputRecord input, - // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} - // expected-note@16{{'dx::HitObject' field declared here}} - NodeOutput output) - // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} - // expected-note@16{{'dx::HitObject' field declared here}} -{ - ThreadNodeOutputRecords touts; - // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} - // expected-note@16{{'dx::HitObject' field declared here}} - GroupNodeOutputRecords gouts; - // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} - // expected-note@16{{'dx::HitObject' field declared here}} -} - -[Shader("node")] -[NodeLaunch("coalescing")] -[NumThreads(8,1,1)] -void coalesce(GroupNodeInputRecords input) {} -// expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} -// expected-note@16{{'dx::HitObject' field declared here}} - -[Shader("node")] -[NodeLaunch("thread")] -void threader(ThreadNodeInputRecord input) {} -// expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} -// expected-note@16{{'dx::HitObject' field declared here}} From 4b345188675d15767f2e81a84bfe688e4ad847d4 Mon Sep 17 00:00:00 2001 From: Tex Riddell Date: Thu, 15 May 2025 12:41:14 -0700 Subject: [PATCH 28/29] Recurse bases in IsHLSLCopyableAnnotatableRecord - Recurse bases in IsHLSLCopyableAnnotatableRecord - Don't skip DiagnoseTypeElements for templated Load/Store - Don't skip existing Payload diagnostics when DiagnoseTypeElements fails - Update tests, including moving fields pointed to by notes to beginning to avoid shifting fixed location references when modifying test cases --- tools/clang/lib/AST/HlslTypes.cpp | 7 ++ tools/clang/lib/Sema/SemaDXR.cpp | 7 +- tools/clang/lib/Sema/SemaHLSL.cpp | 9 +- .../hitobject_traceinvoke_payload_udt.hlsl | 1 + .../types/invalid-hitobject-decls-struct.hlsl | 20 +-- .../invalid-hitobject-decls-templated.hlsl | 115 +++++++++--------- .../test/SemaHLSL/template-udt-load.hlsl | 4 +- 7 files changed, 91 insertions(+), 72 deletions(-) diff --git a/tools/clang/lib/AST/HlslTypes.cpp b/tools/clang/lib/AST/HlslTypes.cpp index 07efb53c8c..871937aaa4 100644 --- a/tools/clang/lib/AST/HlslTypes.cpp +++ b/tools/clang/lib/AST/HlslTypes.cpp @@ -118,6 +118,13 @@ bool IsHLSLCopyableAnnotatableRecord(clang::QualType QT) { if (!IsHLSLNumericOrAggregateOfNumericType(Member->getType())) return false; } + if (auto *CXXRD = dyn_cast(RD)) { + // Walk up the inheritance chain and check base class fields + for (const auto &Base : CXXRD->bases()) { + if (!IsHLSLCopyableAnnotatableRecord(Base.getType())) + return false; + } + } return true; } return false; diff --git a/tools/clang/lib/Sema/SemaDXR.cpp b/tools/clang/lib/Sema/SemaDXR.cpp index 6ccb7199f3..d1602f2c40 100644 --- a/tools/clang/lib/Sema/SemaDXR.cpp +++ b/tools/clang/lib/Sema/SemaDXR.cpp @@ -827,14 +827,13 @@ void DiagnoseBuiltinCallWithPayload(Sema &S, const VarDecl *Payload, } // Verify that the payload type is legal - const TypeDiagContext DiagContext = TypeDiagContext::PayloadParameters; - if (DiagnoseTypeElements(S, Payload->getLocation(), Payload->getType(), - DiagContext, DiagContext)) - return; if (!hlsl::IsHLSLCopyableAnnotatableRecord(Payload->getType())) { S.Diag(Payload->getLocation(), diag::err_payload_attrs_must_be_udt) << /*payload|attributes|callable*/ 0 << /*parameter %2|type*/ 0 << Payload; + const TypeDiagContext DiagContext = TypeDiagContext::PayloadParameters; + DiagnoseTypeElements(S, Payload->getLocation(), Payload->getType(), + DiagContext, DiagContext); return; } diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index f3bf74a977..e5424ecdde 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -10947,13 +10947,12 @@ HLSLExternalSource::DeduceTemplateArgumentsForHLSL( if (!IsLegalTemplate) { getSema()->Diag(Loc, diag::err_hlsl_intrinsic_template_arg_numeric) << intrinsicName; + DiagnoseTypeElements( + *getSema(), Loc, functionTemplateTypeArg, + TypeDiagContext::TypeParameter /*ObjDiagContext*/, + TypeDiagContext::Valid /*LongVecDiagContext*/); return Sema::TemplateDeductionResult::TDK_Invalid; } - if (DiagnoseTypeElements( - *getSema(), Loc, functionTemplateTypeArg, - TypeDiagContext::TypeParameter /*ObjDiagContext*/, - TypeDiagContext::Valid /*LongVecDiagContext*/)) - return Sema::TemplateDeductionResult::TDK_Invalid; } if (IsHitObjectGetAttributes && !DiagnoseIntersectionAttributes(*getSema(), Loc, diff --git a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl index 50587d09e7..a129f98d62 100644 --- a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl @@ -16,6 +16,7 @@ struct Attribs [shader("raygeneration")] void RayGen() { + // expected-error@+3{{payload parameter 'payload_in_rg' must be a user-defined type composed of only numeric types}} // expected-error@+2{{object 'dx::HitObject' is not allowed in payload parameters}} // expected-note@8{{'dx::HitObject' field declared here}} Payload payload_in_rg; diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl index 8b8c20fc1a..b6b28700a9 100644 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-struct.hlsl @@ -77,13 +77,19 @@ RWByteAddressBuffer rw_bab; [Shader("raygeneration")] void main() { - bab.Load(0); - // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} - rw_bab.Load(0); - // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} - TYPE val; - rw_bab.Store(0, val); - // expected-error@-1{{Explicit template arguments on intrinsic Store must be a single numeric type}} + bab.Load(0); + // expected-error@-1{{object 'dx::HitObject' is not allowed in builtin template parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + // expected-error@-3{{Explicit template arguments on intrinsic Load must be a single numeric type}} + rw_bab.Load(0); + // expected-error@-1{{object 'dx::HitObject' is not allowed in builtin template parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + // expected-error@-3{{Explicit template arguments on intrinsic Load must be a single numeric type}} + TYPE val; + rw_bab.Store(0, val); + // expected-error@-1{{object 'dx::HitObject' is not allowed in builtin template parameters}} + // expected-note@16{{'dx::HitObject' field declared here}} + // expected-error@-3{{Explicit template arguments on intrinsic Store must be a single numeric type}} } [shader("pixel")] diff --git a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl index cda6ac4e13..4ffd53878d 100644 --- a/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/types/invalid-hitobject-decls-templated.hlsl @@ -23,6 +23,38 @@ struct HitTpl { T val; }; +RaytracingAccelerationStructure RTAS; + +struct [raypayload] DXRHitStruct { + float4 f : write(closesthit) : read(caller); + TYPE hit : write(closesthit) : read(caller); +}; + +struct [raypayload] DXRHitStructSub : DXRHitStruct { + int3 is : write(closesthit) : read(caller); +}; + +template +struct [raypayload] DXRHitTpl { + float4 f : write(closesthit) : read(caller); + T hit : write(closesthit) : read(caller); +}; + +struct NodeHitStruct { + uint3 grid : SV_DispatchGrid; + TYPE hit; +}; + +struct NodeHitStructSub : NodeHitStruct { + int3 is; +}; + +template +struct NodeHitTpl { + uint3 grid : SV_DispatchGrid; + T hit; +}; + TYPE global_type; // expected-error@-1{{object 'dx::HitObject' is not allowed in cbuffers or tbuffers}} // expected-note@23{{'dx::HitObject' field declared here}} @@ -74,13 +106,19 @@ RWByteAddressBuffer rw_bab; [Shader("raygeneration")] void main() { - bab.Load(0); - // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} - rw_bab.Load(0); - // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} - TYPE val; - rw_bab.Store(0, val); - // expected-error@-1{{Explicit template arguments on intrinsic Store must be a single numeric type}} + bab.Load(0); + // expected-error@-1{{object 'dx::HitObject' is not allowed in builtin template parameters}} + // expected-note@23{{'dx::HitObject' field declared here}} + // expected-error@-3{{Explicit template arguments on intrinsic Load must be a single numeric type}} + rw_bab.Load(0); + // expected-error@-1{{object 'dx::HitObject' is not allowed in builtin template parameters}} + // expected-note@23{{'dx::HitObject' field declared here}} + // expected-error@-3{{Explicit template arguments on intrinsic Load must be a single numeric type}} + TYPE val; + rw_bab.Store(0, val); + // expected-error@-1{{object 'dx::HitObject' is not allowed in builtin template parameters}} + // expected-note@23{{'dx::HitObject' field declared here}} + // expected-error@-3{{Explicit template arguments on intrinsic Store must be a single numeric type}} } [shader("pixel")] @@ -165,26 +203,8 @@ void hs_main(InputPatch TrianglePatch) {} // expected-error@-1{{object 'dx::HitObject' is not allowed in tessellation patches}} // expected-note@23{{'dx::HitObject' field declared here}} -RaytracingAccelerationStructure RTAS; - -struct [raypayload] DXRHitStruct { - float4 f : write(closesthit) : read(caller); - TYPE hit : write(closesthit) : read(caller); -}; - -struct [raypayload] DXRHitStructSub : DXRHitStruct { - int3 is : write(closesthit) : read(caller); -}; - -template -struct [raypayload] DXRHitTpl { - float4 f : write(closesthit) : read(caller); - T hit : write(closesthit) : read(caller); -}; - #define RTTYPE PASTE(DXR,TYPE) - TYPE userFunc(TYPE arg) { return arg; } @@ -195,10 +215,10 @@ void raygen() { RayDesc ray = (RayDesc)0; TraceRay(RTAS, RAY_FLAG_NONE, 0, 0, 1, 0, ray, p); // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} CallShader(0, p); // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} TYPE val; TYPE res = userFunc(val); } @@ -208,18 +228,18 @@ void closesthit( inout RTTYPE payload, // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} in RTTYPE attribs) { // expected-error@-1{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} RayDesc ray; TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} CallShader(0, payload); // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} } [shader("anyhit")] @@ -227,11 +247,11 @@ void AnyHit( inout RTTYPE payload, // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} in RTTYPE attribs) // expected-error@-1{{attributes parameter 'attribs' must be a user-defined type composed of only numeric types}} // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} { } @@ -240,14 +260,14 @@ void Miss( inout RTTYPE payload){ // expected-error@-1{{payload parameter 'payload' must be a user-defined type composed of only numeric types}} // expected-error@-2{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} RayDesc ray; TraceRay( RTAS, RAY_FLAG_NONE, 0xff, 0, 1, 0, ray, payload ); // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} CallShader(0, payload); // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} } [shader("intersection")] @@ -256,18 +276,18 @@ void Intersection() { RTTYPE attr = (RTTYPE)0; bool bReported = ReportHit(hitT, 0, attr); // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} } [shader("callable")] void callable1( inout RTTYPE p) { // expected-error@-1{{object 'dx::HitObject' is not allowed in entry function parameters}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} // expected-error@-3{{callable parameter 'p' must be a user-defined type composed of only numeric types}} CallShader(0, p); // expected-error@-1{{object 'dx::HitObject' is not allowed in user-defined struct parameter}} - // expected-note@182{{'dx::HitObject' field declared here}} + // expected-note@40{{'dx::HitObject' field declared here}} } static groupshared TYPE gs_var; @@ -283,21 +303,6 @@ void Amp() { // expected-note@23{{'dx::HitObject' field declared here}} } -struct NodeHitStruct { - uint3 grid : SV_DispatchGrid; - TYPE hit; -}; - -struct NodeHitStructSub : NodeHitStruct { - int3 is; -}; - -template -struct NodeHitTpl { - uint3 grid : SV_DispatchGrid; - T hit; -}; - #define NTYPE PASTE(Node,TYPE) [Shader("node")] @@ -308,7 +313,7 @@ void broadcast( // expected-error@-1{{Broadcasting node shader 'broadcast' with NodeMaxDispatchGrid attribute must declare an input record containing a field with SV_DispatchGrid semantic}} DispatchNodeInputRecord input, // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} - // expected-note@298{{'dx::HitObject' field declared here}} + // expected-note@55{{'dx::HitObject' field declared here}} NodeOutput output) // expected-error@-1{{object 'dx::HitObject' is not allowed in node records}} // expected-note@23{{'dx::HitObject' field declared here}} diff --git a/tools/clang/test/SemaHLSL/template-udt-load.hlsl b/tools/clang/test/SemaHLSL/template-udt-load.hlsl index 591f27b384..f666297bb9 100644 --- a/tools/clang/test/SemaHLSL/template-udt-load.hlsl +++ b/tools/clang/test/SemaHLSL/template-udt-load.hlsl @@ -8,6 +8,8 @@ RWBuffer Out; [numthreads(1,1,1)] void main() { - RWBuffer FB = In.Load >(0); // expected-error {{Explicit template arguments on intrinsic Load must be a single numeric type}} + RWBuffer FB = In.Load >(0); + // expected-error@-1{{Explicit template arguments on intrinsic Load must be a single numeric type}} + // expected-error@-2{{object 'RWBuffer' is not allowed in builtin template parameters}} Out[0] = FB[0]; } From 58b764220669d0ba5216c7903704926b5e85ab05 Mon Sep 17 00:00:00 2001 From: Tex Riddell Date: Thu, 15 May 2025 14:21:03 -0700 Subject: [PATCH 29/29] Diagnose long vector in payload call argument case --- tools/clang/lib/Sema/SemaDXR.cpp | 11 ++++++----- .../hitobject_traceinvoke_payload_udt.hlsl | 13 ++++++++++--- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/clang/lib/Sema/SemaDXR.cpp b/tools/clang/lib/Sema/SemaDXR.cpp index d1602f2c40..04e1582513 100644 --- a/tools/clang/lib/Sema/SemaDXR.cpp +++ b/tools/clang/lib/Sema/SemaDXR.cpp @@ -827,15 +827,16 @@ void DiagnoseBuiltinCallWithPayload(Sema &S, const VarDecl *Payload, } // Verify that the payload type is legal - if (!hlsl::IsHLSLCopyableAnnotatableRecord(Payload->getType())) { + if (!hlsl::IsHLSLCopyableAnnotatableRecord(Payload->getType())) S.Diag(Payload->getLocation(), diag::err_payload_attrs_must_be_udt) << /*payload|attributes|callable*/ 0 << /*parameter %2|type*/ 0 << Payload; - const TypeDiagContext DiagContext = TypeDiagContext::PayloadParameters; - DiagnoseTypeElements(S, Payload->getLocation(), Payload->getType(), - DiagContext, DiagContext); + + // This will produce more details, but also catch disallowed long vectors + const TypeDiagContext DiagContext = TypeDiagContext::PayloadParameters; + if (DiagnoseTypeElements(S, Payload->getLocation(), Payload->getType(), + DiagContext, DiagContext)) return; - } CollectNonAccessableFields(PayloadType, CallerStage, {}, {}, NonWriteableFields, NonReadableFields); diff --git a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl index a129f98d62..ee4ff8c020 100644 --- a/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl +++ b/tools/clang/test/SemaHLSL/hlsl/objects/HitObject/hitobject_traceinvoke_payload_udt.hlsl @@ -4,13 +4,16 @@ struct [raypayload] Payload { - int a : read(caller, closesthit, miss) : write(caller, closesthit, miss); + int a : read(closesthit, miss) : write(anyhit); dx::HitObject hit; }; -struct Attribs +struct +[raypayload] +PayloadLV { - float2 barys; + int a : read(closesthit, miss) : write(anyhit); + vector b : read(closesthit, miss) : write(anyhit); }; [shader("raygeneration")] @@ -21,4 +24,8 @@ void RayGen() // expected-note@8{{'dx::HitObject' field declared here}} Payload payload_in_rg; dx::HitObject::Invoke( dx::HitObject(), payload_in_rg ); + + // expected-error@+1{{vectors of over 4 elements in payload parameters are not supported}} + PayloadLV payload_with_lv; + dx::HitObject::Invoke( dx::HitObject(), payload_with_lv ); } \ No newline at end of file