Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Sema] Prevent unwanted conversions related to ResourceDescriptorHeap/SamplerDescriptorHeap #6779

Closed
wants to merge 7 commits into from
6 changes: 4 additions & 2 deletions lib/DxcSupport/HLSLOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,8 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
// through an argument. The value should default to 'main', but we let the
// caller apply this policy.

opts.VerifyDiagnostics = Args.hasFlag(OPT_verify, OPT_INVALID, false);

if (opts.TargetProfile.empty()) {
opts.TargetProfile = Args.getLastArgValue(OPT_target_profile);
}
Expand Down Expand Up @@ -508,7 +510,8 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
}

if (opts.HLSLVersion == hlsl::LangStd::v2015 &&
!(flagsToInclude & HlslFlags::ISenseOption)) {
!((flagsToInclude & HlslFlags::ISenseOption) != 0 ||
opts.VerifyDiagnostics)) {
errors << "HLSL Version 2015 is only supported for language services";
return 1;
}
Expand Down Expand Up @@ -825,7 +828,6 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
Args.hasFlag(OPT_fnew_inlining_behavior, OPT_INVALID, false);
opts.TimeReport = Args.hasFlag(OPT_ftime_report, OPT_INVALID, false);
opts.TimeTrace = Args.hasFlag(OPT_ftime_trace, OPT_INVALID, false) ? "-" : "";
opts.VerifyDiagnostics = Args.hasFlag(OPT_verify, OPT_INVALID, false);
if (Args.hasArg(OPT_ftime_trace_EQ))
opts.TimeTrace = Args.getLastArgValue(OPT_ftime_trace_EQ);
if (Arg *A = Args.getLastArg(OPT_ftime_trace_granularity_EQ)) {
Expand Down
1 change: 1 addition & 0 deletions tools/clang/include/clang/AST/HlslTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@ bool IsHLSLNodeOutputType(clang::QualType type);

DXIL::NodeIOKind GetNodeIOType(clang::QualType type);

bool IsHLSLSamplerType(clang::QualType type);
bool IsHLSLStructuredBufferType(clang::QualType type);
bool IsHLSLNumericOrAggregateOfNumericType(clang::QualType type);
bool IsHLSLNumericUserDefinedType(clang::QualType type);
Expand Down
11 changes: 11 additions & 0 deletions tools/clang/lib/AST/HlslTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,17 @@ bool IsHLSLNodeOutputType(clang::QualType type) {
static_cast<uint32_t>(DXIL::NodeIOFlags::Output);
}

bool IsHLSLSamplerType(clang::QualType type)
{
if (const RecordType *RT = type->getAs<RecordType>()) {
StringRef name = RT->getDecl()->getName();

if (name == "SamplerState" || name == "SamplerComparisonState")
return true;
}
return false;
}

bool IsHLSLStructuredBufferType(clang::QualType type) {
if (const RecordType *RT = type->getAs<RecordType>()) {
StringRef name = RT->getDecl()->getName();
Expand Down
6 changes: 6 additions & 0 deletions tools/clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4136,9 +4136,15 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
case tok::kw_union: {
// HLSL Change Starts
if (getLangOpts().HLSL) {

if (Tok.is(tok::kw_union) || Tok.is(tok::kw___interface)) {
goto HLSLReservedKeyword;
}

if (getLangOpts().HLSLVersion != hlsl::LangStd::v2015 &&
Tok.is(tok::kw_interface)) {
goto HLSLReservedKeyword;
}
}
// HLSL Change Ends
tok::TokenKind Kind = Tok.getKind();
Expand Down
16 changes: 11 additions & 5 deletions tools/clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9555,11 +9555,17 @@ bool HLSLExternalSource::CanConvert(SourceLocation loc, Expr *sourceExpr,
goto lSuccess;
}

// Cast from Resource to Object types.
if (SourceInfo.EltKind == AR_OBJECT_HEAP_RESOURCE ||
SourceInfo.EltKind == AR_OBJECT_HEAP_SAMPLER) {
// TODO: skip things like PointStream.
if (TargetInfo.ShapeKind == AR_TOBJ_OBJECT) {

if (SourceInfo.EltKind == AR_OBJECT_HEAP_SAMPLER) {
if (TargetInfo.ShapeKind == AR_TOBJ_OBJECT &&
hlsl::IsHLSLSamplerType(target)) {
Second = ICK_Flat_Conversion;
goto lSuccess;
}
}
if (SourceInfo.EltKind == AR_OBJECT_HEAP_RESOURCE) {
if (TargetInfo.ShapeKind == AR_TOBJ_OBJECT &&
hlsl::IsHLSLResourceType(target) && !hlsl::IsHLSLSamplerType(target)) {
Second = ICK_Flat_Conversion;
goto lSuccess;
}
Expand Down
10 changes: 0 additions & 10 deletions tools/clang/test/HLSL/cpp-errors.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -295,24 +295,14 @@ struct my_struct { };

class my_class { };

interface my_interface { };

class my_class_2 : my_class { };

class my_class_3 : my_interface { };

class my_class_4 : my_struct { };

struct my_struct_2 : my_struct { };

struct my_struct_3 : my_class { };

struct my_struct_4 : my_interface { };
struct my_struct_5 : my_class, my_interface { };
struct my_struct_6 : my_class, my_interface, my_struct { }; // expected-error {{multiple concrete base types specified}}

interface my_interface_2 : my_interface { }; // expected-error {{interfaces cannot inherit from other types}}

class my_class_public : public my_class { }; // expected-error {{base type access specifier is unsupported in HLSL}}

struct forward_struct; // this fails in fxc, but we allow it now
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,14 @@ struct my_struct {
};
class my_class {
};
interface my_interface {
};
class my_class_2 : my_class {
};
class my_class_3 : my_interface {
};
class my_class_4 : my_struct {
class my_class_3 : my_struct {
};
struct my_struct_2 : my_struct {
};
struct my_struct_3 : my_class {
};
struct my_struct_4 : my_interface {
};
struct my_struct_5 : my_class, my_interface {
};
struct my_struct_type_decl {
int a;
};
Expand Down
8 changes: 1 addition & 7 deletions tools/clang/test/HLSL/rewriter/cpp-errors_noerr.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -308,20 +308,14 @@ struct my_struct { };

class my_class { };

interface my_interface { };

class my_class_2 : my_class { };

class my_class_3 : my_interface { };

class my_class_4 : my_struct { };
class my_class_3 : my_struct { };

struct my_struct_2 : my_struct { };

struct my_struct_3 : my_class { };

struct my_struct_4 : my_interface { };
struct my_struct_5 : my_class, my_interface { };
//struct my_struct_6 : my_class, my_interface, my_struct { }; // expected-error {{multiple concrete base types specified}}
//
//interface my_interface_2 : my_interface { }; // expected-error {{interfaces cannot inherit from other types}}
Expand Down
111 changes: 111 additions & 0 deletions tools/clang/test/SemaHLSL/heap-assignments.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// RUN: %dxc -Tcs_6_6 -verify %s

struct MyStruct
{
float f;
};

void TestSamplerDescriptorHeap()
{
SamplerState s1 = SamplerDescriptorHeap[0];
SamplerComparisonState s2 = SamplerDescriptorHeap[0];

Texture1D<float> t1 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'Texture1D<float>' with an rvalue of type 'const .Sampler'}}
RWTexture1D<float> t2 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RWTexture1D<float>' with an rvalue of type 'const .Sampler'}}
Texture2D<float> t3 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'Texture2D<float>' with an rvalue of type 'const .Sampler'}}
RWTexture2D<float> t4 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RWTexture2D<float>' with an rvalue of type 'const .Sampler'}}
Texture3D<float> t5 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'Texture3D<float>' with an rvalue of type 'const .Sampler'}}
RWTexture3D<float> t6 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RWTexture3D<float>' with an rvalue of type 'const .Sampler'}}

Texture2DMS<float> t7 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'Texture2DMS<float>' with an rvalue of type 'const .Sampler'}}
RWTexture2DMS<float> t8 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RWTexture2DMS<float>' with an rvalue of type 'const .Sampler'}}
TextureCube<float> t9 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'TextureCube<float>' with an rvalue of type 'const .Sampler'}}

Texture1DArray<float> t10 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'Texture1DArray<float>' with an rvalue of type 'const .Sampler'}}
RWTexture1DArray<float> t11 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RWTexture1DArray<float>' with an rvalue of type 'const .Sampler'}}
Texture2DArray<float> t12 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'Texture2DArray<float>' with an rvalue of type 'const .Sampler'}}
RWTexture2DArray<float> t13 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RWTexture2DArray<float>' with an rvalue of type 'const .Sampler'}}
Texture2DMSArray<float> t14 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'Texture2DMSArray<float>' with an rvalue of type 'const .Sampler'}}
RWTexture2DMSArray<float> t15 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RWTexture2DMSArray<float>' with an rvalue of type 'const .Sampler'}}
TextureCubeArray<float> t16 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'TextureCubeArray<float>' with an rvalue of type 'const .Sampler'}}

FeedbackTexture2D<SAMPLER_FEEDBACK_MIN_MIP> t17 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'FeedbackTexture2D<SAMPLER_FEEDBACK_MIN_MIP>' with an rvalue of type 'const .Sampler'}}
FeedbackTexture2DArray<SAMPLER_FEEDBACK_MIN_MIP> t18 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'FeedbackTexture2DArray<SAMPLER_FEEDBACK_MIN_MIP>' with an rvalue of type 'const .Sampler'}}

RasterizerOrderedTexture1D<float> t19 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RasterizerOrderedTexture1D<float>' with an rvalue of type 'const .Sampler'}}
RasterizerOrderedTexture2D<float> t20 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RasterizerOrderedTexture2D<float>' with an rvalue of type 'const .Sampler'}}
RasterizerOrderedTexture3D<float> t21 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RasterizerOrderedTexture3D<float>' with an rvalue of type 'const .Sampler'}}
RasterizerOrderedTexture1DArray<float> t22 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RasterizerOrderedTexture1DArray<float>' with an rvalue of type 'const .Sampler'}}
RasterizerOrderedTexture2DArray<float> t23 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RasterizerOrderedTexture2DArray<float>' with an rvalue of type 'const .Sampler'}}

ByteAddressBuffer b1 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'ByteAddressBuffer' with an rvalue of type 'const .Sampler'}}
RWByteAddressBuffer b2 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RWByteAddressBuffer' with an rvalue of type 'const .Sampler'}}
StructuredBuffer<float> b3 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'StructuredBuffer<float>' with an rvalue of type 'const .Sampler'}}
RWStructuredBuffer<float> b4 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RWStructuredBuffer<float>' with an rvalue of type 'const .Sampler'}}
AppendStructuredBuffer<float> b5 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'AppendStructuredBuffer<float>' with an rvalue of type 'const .Sampler'}}
ConsumeStructuredBuffer<float> b6 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'ConsumeStructuredBuffer<float>' with an rvalue of type 'const .Sampler'}}
Buffer<float> b7 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'Buffer<float>' with an rvalue of type 'const .Sampler'}}
RWBuffer<float> b8 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RWBuffer<float>' with an rvalue of type 'const .Sampler'}}
RasterizerOrderedBuffer<float> b9 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RasterizerOrderedBuffer<float>' with an rvalue of type 'const .Sampler'}}
RasterizerOrderedByteAddressBuffer b10 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RasterizerOrderedByteAddressBuffer' with an rvalue of type 'const .Sampler'}}
RasterizerOrderedStructuredBuffer<float> b11 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RasterizerOrderedStructuredBuffer<float>' with an rvalue of type 'const .Sampler'}}

ConstantBuffer<MyStruct> cb0 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'ConstantBuffer<MyStruct>' with an rvalue of type 'const .Sampler'}}
TextureBuffer<MyStruct> tb0 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'TextureBuffer<MyStruct>' with an rvalue of type 'const .Sampler'}}

RaytracingAccelerationStructure as0 = SamplerDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'RaytracingAccelerationStructure' with an rvalue of type 'const .Sampler'}}
}

void TestResourceDescriptorHeap()
{
SamplerState s1 = ResourceDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'SamplerState' with an rvalue of type 'const .Resource'}}
SamplerComparisonState s2 = ResourceDescriptorHeap[0]; // expected-error{{cannot initialize a variable of type 'SamplerComparisonState' with an rvalue of type 'const .Resource'}}

Texture3D<float> t5 = ResourceDescriptorHeap[0];
RWTexture3D<float> t6 = ResourceDescriptorHeap[0];

Texture2DMS<float> t7 = ResourceDescriptorHeap[0];
RWTexture2DMS<float> t8 = ResourceDescriptorHeap[0];
TextureCube<float> t9 = ResourceDescriptorHeap[0];

Texture1DArray<float> t10 = ResourceDescriptorHeap[0];
RWTexture1DArray<float> t11 = ResourceDescriptorHeap[0];
Texture2DArray<float> t12 = ResourceDescriptorHeap[0];
RWTexture2DArray<float> t13 = ResourceDescriptorHeap[0];
Texture2DMSArray<float> t14 = ResourceDescriptorHeap[0];
RWTexture2DMSArray<float> t15 = ResourceDescriptorHeap[0];
TextureCubeArray<float> t16 = ResourceDescriptorHeap[0];

FeedbackTexture2D<SAMPLER_FEEDBACK_MIN_MIP> t17 = ResourceDescriptorHeap[0];
FeedbackTexture2DArray<SAMPLER_FEEDBACK_MIN_MIP> t18 = ResourceDescriptorHeap[0];

RasterizerOrderedTexture1D<float> t19 = ResourceDescriptorHeap[0];
RasterizerOrderedTexture2D<float> t20 = ResourceDescriptorHeap[0];
RasterizerOrderedTexture3D<float> t21 = ResourceDescriptorHeap[0];
RasterizerOrderedTexture1DArray<float> t22 = ResourceDescriptorHeap[0];
RasterizerOrderedTexture2DArray<float> t23 = ResourceDescriptorHeap[0];

ByteAddressBuffer b1 = ResourceDescriptorHeap[0];
RWByteAddressBuffer b2 = ResourceDescriptorHeap[0];
StructuredBuffer<float> b3 = ResourceDescriptorHeap[0];
RWStructuredBuffer<float> b4 = ResourceDescriptorHeap[0];
AppendStructuredBuffer<float> b5 = ResourceDescriptorHeap[0];
ConsumeStructuredBuffer<float> b6 = ResourceDescriptorHeap[0];
Buffer<float> b7 = ResourceDescriptorHeap[0];
RWBuffer<float> b8 = ResourceDescriptorHeap[0];
RasterizerOrderedBuffer<float> b9 = ResourceDescriptorHeap[0];
RasterizerOrderedByteAddressBuffer b10 = ResourceDescriptorHeap[0];
RasterizerOrderedStructuredBuffer<float> b11 = ResourceDescriptorHeap[0];

ConstantBuffer<MyStruct> cb0 = ResourceDescriptorHeap[0];
TextureBuffer<MyStruct> tb0 = ResourceDescriptorHeap[0];

RaytracingAccelerationStructure as0 = ResourceDescriptorHeap[0];
}

[numthreads(1, 1, 1)]
void main()
{
TestSamplerDescriptorHeap();
TestResourceDescriptorHeap();
}
13 changes: 13 additions & 0 deletions tools/clang/test/SemaHLSL/interfaces-HV-2015.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: %dxc -Tlib_6_3 -verify -HV 2015 %s

interface my_interface { };

class my_class { };
class my_class_3 : my_interface { };
struct my_struct { };
struct my_struct_4 : my_interface { };
struct my_struct_5 : my_class, my_interface { };

struct my_struct_6 : my_class, my_interface, my_struct { }; // expected-error {{multiple concrete base types specified}}

interface my_interface_2 : my_interface { }; // expected-error {{interfaces cannot inherit from other types}}
17 changes: 17 additions & 0 deletions tools/clang/test/SemaHLSL/reserved_keywords.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: %dxc -Tps_6_0 -verify %s

// expected-error@+2 {{'interface' is a reserved keyword in HLSL}}
// expected-error@+1 {{HLSL requires a type specifier for all declarations}}
interface I
{ // expected-warning {{effect state block ignored - effect syntax is deprecated. To use braces as an initializer use them with equal signs.}}
void f();
};

// expected-error@+2 {{'union' is a reserved keyword in HLSL}}
// expected-error@+1 {{HLSL requires a type specifier for all declarations}}
union U
{ // expected-warning {{effect state block ignored - effect syntax is deprecated. To use braces as an initializer use them with equal signs.}}
void f();
};

void main() {}
2 changes: 0 additions & 2 deletions tools/clang/tools/dxcompiler/dxcutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,6 @@ void ReadOptsAndValidate(hlsl::options::MainArgs &mainArgs,
finished = true;
return;
}
DXASSERT(opts.HLSLVersion > hlsl::LangStd::v2015,
"else ReadDxcOpts didn't fail for non-isense");
finished = false;
}

Expand Down
Loading