diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11576,5 +11576,12 @@ def err_hlsl_numthreads_invalid : Error<"total number of threads cannot exceed %0">; def err_hlsl_attribute_param_mismatch : Error<"%0 attribute parameters do not match the previous declaration">; +def err_hlsl_pointers_unsupported : Error<"%select{pointers|references}0 are " + "unsupported in HLSL">; + +def err_hlsl_operator_unsupported : Error<"the %select{address of (&)|" + "dereference (*)|arrow (->)}0 " + "operator is unsupported in HLSL">; + } // end of sema component. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -15249,6 +15249,13 @@ } } + if (getLangOpts().HLSL) { + if (Opc == UO_AddrOf) + return ExprError(Diag(OpLoc, diag::err_hlsl_operator_unsupported) << 0); + if (Opc == UO_Deref) + return ExprError(Diag(OpLoc, diag::err_hlsl_operator_unsupported) << 1); + } + switch (Opc) { case UO_PreInc: case UO_PreDec: diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -1736,6 +1736,9 @@ DeclarationName Name = NameInfo.getName(); bool IsArrow = (OpKind == tok::arrow); + if (getLangOpts().HLSL && IsArrow) + return ExprError(Diag(OpLoc, diag::err_hlsl_operator_unsupported) << 2); + NamedDecl *FirstQualifierInScope = (!SS.isSet() ? nullptr : FindFirstQualifierInScope(S, SS.getScopeRep())); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2143,6 +2143,11 @@ return QualType(); } + if (getLangOpts().HLSL) { + Diag(Loc, diag::err_hlsl_pointers_unsupported) << 0; + return QualType(); + } + if (checkQualifiedFunction(*this, T, Loc, QFK_Pointer)) return QualType(); @@ -2208,6 +2213,11 @@ return QualType(); } + if (getLangOpts().HLSL) { + Diag(Loc, diag::err_hlsl_pointers_unsupported) << 1; + return QualType(); + } + if (checkQualifiedFunction(*this, T, Loc, QFK_Reference)) return QualType(); @@ -2967,6 +2977,11 @@ return QualType(); } + if (getLangOpts().HLSL) { + Diag(Loc, diag::err_hlsl_pointers_unsupported) << 0; + return QualType(); + } + // Adjust the default free function calling convention to the default method // calling convention. bool IsCtorOrDtor = diff --git a/clang/test/SemaHLSL/prohibit_pointer.hlsl b/clang/test/SemaHLSL/prohibit_pointer.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/SemaHLSL/prohibit_pointer.hlsl @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - -fsyntax-only %s -verify + +// expected-error@+1 {{pointers are unsupported in HLSL}} +typedef int (*fn_int)(int); +void* bark(int); // expected-error {{pointers are unsupported in HLSL}} +void meow(int*); // expected-error {{pointers are unsupported in HLSL}} + +struct Foo { + int X; + int Y; +} *bad; // expected-error {{pointers are unsupported in HLSL}} + +// expected-error@+1 {{pointers are unsupported in HLSL}} +void woof(int Foo::*Member); + +int entry() { + int X; + Foo F; + + // expected-error@+2 {{the address of (&) operator is unsupported in HLSL}} + // expected-error@+1 {{pointers are unsupported in HLSL}} + int Foo::*Member = &F.X; + + // expected-error@+1 {{the address of (&) operator is unsupported in HLSL}} + int *Y = &X; // expected-error {{pointers are unsupported in HLSL}} + + // expected-error@+2 {{the arrow (->) operator is unsupported in HLSL}} + // expected-error@+1 {{the address of (&) operator is unsupported in HLSL}} + int W = (&F)->X; + + int Array[2]; + // expected-error@+1 {{the address of (&) operator is unsupported in HLSL}} + *(&Array[0] + 1) = 12; + // expected-error@+1 {{the dereference (*) operator is unsupported in HLSL}} + *Array = 12; +} + +int roar(Foo *F) { // expected-error {{pointers are unsupported in HLSL}} + // expected-error@+1 {{the arrow (->) operator is unsupported in HLSL}} + return F->X; +} + +template +void devilish_language(T look_ma_no_pointers); + +void make_me_cry() { + int X; + // expected-error@+1 {{the address of (&) operator is unsupported in HLSL}} + devilish_language(&X); + + // not-expected-error@+1 {{pointers are unsupported in HLSL}} + devilish_language(roar); // allow function pointer decay + + // not-expected-error@+1 {{pointers are unsupported in HLSL}} + devilish_language("roar"); // allow array pointer decay +} diff --git a/clang/test/SemaHLSL/prohibit_reference.hlsl b/clang/test/SemaHLSL/prohibit_reference.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/SemaHLSL/prohibit_reference.hlsl @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - -fsyntax-only %s -verify + +int& bark(int); // expected-error {{references are unsupported in HLSL}} +void meow(int&); // expected-error {{references are unsupported in HLSL}} + +struct Foo { + int X; + int Y; +}; + +int entry() { + int X; + int &Y = X; // expected-error {{references are unsupported in HLSL}} +} + +int roar(Foo &F) { // expected-error {{references are unsupported in HLSL}} + return F.X; +}