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 @@ -11590,6 +11590,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{&|*|->}0' operator is unsupported in HLSL">; + // Layout randomization warning. def err_cast_from_randomized_struct : Error< "casting from randomized structure pointer type %0 to %1">; 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 @@ -15369,6 +15369,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,81 @@ +// 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 '&' operator is unsupported in HLSL}} + // expected-error@+1 {{pointers are unsupported in HLSL}} + int Foo::*Member = &F.X; + + + // expected-error@+1 {{the '&' operator is unsupported in HLSL}} + int *Y = &X; // expected-error {{pointers are unsupported in HLSL}} + + // expected-error@+2 {{the '->' operator is unsupported in HLSL}} + // expected-error@+1 {{the '&' operator is unsupported in HLSL}} + int W = (&F)->X; + + int Array[2]; + // expected-error@+1 {{the '&' operator is unsupported in HLSL}} + *(&Array[0] + 1) = 12; + // expected-error@+1 {{the '*' operator is unsupported in HLSL}} + *Array = 12; +} + +int roar(Foo *F) { // expected-error {{pointers are unsupported in HLSL}} + // expected-error@+1 {{the '->' 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 '&' 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 +} + +struct Fish { + struct Fins { + int Left; + int Right; + }; + int X; + int operator *() { + return X; + } + + // expected-note@+1 {{'->' applied to return value of the operator->() declared here}} + Fins operator ->() { + return Fins(); + } +}; + +int gone_fishing() { + Fish F; + int Result = *F; // user-defined dereference operators work + // expected-error@+1 {{member reference type 'Fish::Fins' is not a pointer}} + Result += F->Left; + return Result; +} 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,20 @@ +// 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}} +void chirp(int &&); // expected-error {{references are unsupported in HLSL}} +// expected-warning@-1 {{rvalue references are a C++11 extension}} + +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; +}