Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -8070,6 +8070,9 @@ def err_hlsl_auto_descriptor_heap : Error<
"'auto' cannot deduce the type of '%select{ResourceDescriptorHeap|SamplerDescriptorHeap}0'; "
"use a specific resource or sampler type instead">;

def err_hlsl_auto_undeducible_type : Error<
"'auto' cannot deduce type %0">;

// HLSL Change Ends

// SPIRV Change Starts
Expand Down
4 changes: 4 additions & 0 deletions tools/clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ bool DiagnoseTypeElements(clang::Sema &S, clang::SourceLocation Loc,
TypeDiagContext LongVecDiagContext,
const clang::FieldDecl *FD = nullptr);

// Returns true if 'auto' is allowed to deduce the given type. Container types
// are deducible only when the type they wrap is deducible.
bool IsTypeDeducibleWithAuto(clang::Sema &S, clang::QualType Ty);

void DiagnoseControlFlowConditionForHLSL(clang::Sema *self,
clang::Expr *condExpr,
llvm::StringRef StmtName);
Expand Down
10 changes: 10 additions & 0 deletions tools/clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9051,6 +9051,16 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
VDecl->setInvalidDecl();
return;
}

// A dependent deduced type cannot be classified yet; defer the check to
// instantiation, when 'auto' is re-deduced to a concrete type.
if (!DeducedType->isDependentType() &&
!hlsl::IsTypeDeducibleWithAuto(*this, DeducedType)) {
Diag(VDecl->getLocation(), diag::err_hlsl_auto_undeducible_type)
<< DeducedType;
VDecl->setInvalidDecl();
return;
}
}

VDecl->setType(DeducedType);
Expand Down
43 changes: 43 additions & 0 deletions tools/clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4773,6 +4773,45 @@ class HLSLExternalSource : public ExternalSemaSource {
return type;
}

bool IsTypeDeducibleWithAuto(QualType type) {
if (type.isNull())
return false;

switch (GetTypeObjectKind(type)) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the only two cases here that actually matter are AR_TOBJ_INNER_OBJ and AR_TOBJ_STRING right?
Any other case should result in an error from somewhere else in the compiler.

Why not just handle the string case and put an attribute on the inner object types that marks them as non-deducible?

If we also put that attribute implicitly on subobject types, we can flatten a lot of this to just a hasAttr check.

// Types with no concrete, nameable form for 'auto' to bind to.
case AR_TOBJ_INVALID:
case AR_TOBJ_VOID:
case AR_TOBJ_INNER_OBJ:
case AR_TOBJ_DEPENDENT:
return false;

// Fully-formed types that 'auto' can deduce directly.
case AR_TOBJ_OBJECT:
case AR_TOBJ_BASIC:
case AR_TOBJ_COMPOUND:
case AR_TOBJ_INTERFACE:
case AR_TOBJ_STRING:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure STRING should be included here.

case AR_TOBJ_LINALG_MATRIX:
return true;

// Container types: deducible iff their wrapped type is deducible.
case AR_TOBJ_MATRIX:
case AR_TOBJ_VECTOR:
return IsTypeDeducibleWithAuto(GetMatrixOrVectorElementType(type));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why matrix/vector types aren't just always deducible. What element type is allowed with these types (we have separate checking for the allowed element template type) that would prevent this?

case AR_TOBJ_ARRAY: {
const ArrayType *arrayType =
GetStructuralForm(type)->getAsArrayTypeUnsafe();
return IsTypeDeducibleWithAuto(arrayType->getElementType());
}
case AR_TOBJ_POINTER:
return IsTypeDeducibleWithAuto(GetStructuralForm(type)->getPointeeType());
case AR_TOBJ_QUALIFIER:
return IsTypeDeducibleWithAuto(
GetStructuralForm(type).getUnqualifiedType());
}
return false;
}

/// <summary>Given a Clang type, return the ArBasicKind classification for its
/// contents.</summary>
ArBasicKind GetTypeElementKind(QualType type) {
Expand Down Expand Up @@ -12787,6 +12826,10 @@ bool hlsl::DiagnoseTypeElements(Sema &S, SourceLocation Loc, QualType Ty,
LongVecDiagContext, CheckedDecls, FD);
}

bool hlsl::IsTypeDeducibleWithAuto(Sema &S, QualType Ty) {
return HLSLExternalSource::FromSema(&S)->IsTypeDeducibleWithAuto(Ty);
}

bool hlsl::DiagnoseNodeStructArgument(Sema *self, TemplateArgumentLoc ArgLoc,
QualType ArgTy, bool &Empty,
const FieldDecl *FD) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// RUN: %dxc -T cs_6_0 -HV 202x -verify %s
// expected-no-diagnostics

struct MyStruct {
float a;
int b;
};

Texture2D<float4> tex : register(t0);
SamplerState samp : register(s0);
RWBuffer<float> output : register(u0);

[numthreads(1,1,1)]
void main() {
// AR_TOBJ_BASIC
auto i = 5;
auto f = 1.5f;
auto b = true;

// AR_TOBJ_VECTOR -> element AR_TOBJ_BASIC
auto v = float4(1, 2, 3, 4);

// AR_TOBJ_MATRIX -> element AR_TOBJ_BASIC
float2x2 matInit = { 1, 2, 3, 4 };
auto m = matInit;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about something like?

    auto row = m[0];


// AR_TOBJ_COMPOUND
MyStruct s = { 1.0f, 2 };
auto sCopy = s;

// AR_TOBJ_OBJECT: resource handles are copyable, so binding one is allowed.
auto t = tex;

// Use every value to prevent dead-code elimination.
output[0] = (float)i + f + (float)b + v.x + m._11 + sCopy.a +
(float)sCopy.b + t.SampleLevel(samp, float2(0, 0), 0).x;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// RUN: %dxc -T cs_6_0 -HV 202x -verify %s


void voidFunc() {}

Texture2D<float4> tex : register(t0);
Texture2DMS<float4> texMS : register(t1);

[numthreads(1,1,1)]
void main() {
int y = 1;

// AR_TOBJ_VOID: a void-returning call has no value type.
// expected-error@+1 {{'auto' cannot deduce type 'void'}}
auto x = voidFunc();

// AR_TOBJ_VOID: an explicit cast to void is equally non-deducible.
// expected-error@+1 {{'auto' cannot deduce type 'void'}}
auto v = (void)y;

// AR_TOBJ_INNER_OBJ: .mips is an inner indexer object (Texture2D::mips_type).
// expected-error@+1 {{'auto' cannot deduce type}}
auto m = tex.mips;

// AR_TOBJ_INNER_OBJ: .sample is an inner indexer object
// (Texture2DMS::sample_type).
// expected-error@+1 {{'auto' cannot deduce type}}
auto s = texMS.sample;
Comment thread
joaosaffran marked this conversation as resolved.
}
Loading