[HLSL] Pointers are unsupported in HLSL

HLSL does not support pointers or references. This change generates
errors in sema for generating pointer, and reference types as well as
common operators (address-of, dereference, arrow), which are used with
pointers and are unsupported in HLSL.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D123167
This commit is contained in:
Chris Bieneman 2022-04-13 20:47:28 -05:00
parent 02eab52866
commit 3efad612d2
6 changed files with 132 additions and 0 deletions

View File

@ -11590,6 +11590,12 @@ def err_hlsl_numthreads_argument_oor : Error<"argument '%select{X|Y|Z}0' to numt
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">;

View File

@ -15369,6 +15369,13 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
}
}
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:

View File

@ -1736,6 +1736,9 @@ ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
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()));

View File

@ -2143,6 +2143,11 @@ QualType Sema::BuildPointerType(QualType T,
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 @@ QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue,
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 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
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 =

View File

@ -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 <typename T>
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;
}

View File

@ -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;
}