[HLSL] Pointers are unsupported in HLSL
authorChris Bieneman <chris.bieneman@me.com>
Thu, 14 Apr 2022 01:47:28 +0000 (20:47 -0500)
committerChris Bieneman <chris.bieneman@me.com>
Thu, 14 Apr 2022 18:32:51 +0000 (13:32 -0500)
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

clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprMember.cpp
clang/lib/Sema/SemaType.cpp
clang/test/SemaHLSL/prohibit_pointer.hlsl [new file with mode: 0644]
clang/test/SemaHLSL/prohibit_reference.hlsl [new file with mode: 0644]

index ea3db40..7ffd123 100644 (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">;
index f210a8b..db5ab00 100644 (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:
index cb95f70..d5e7a2c 100644 (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()));
 
index 43ab907..a9cb5fd 100644 (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 =
diff --git a/clang/test/SemaHLSL/prohibit_pointer.hlsl b/clang/test/SemaHLSL/prohibit_pointer.hlsl
new file mode 100644 (file)
index 0000000..4a328f6
--- /dev/null
@@ -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;
+}
diff --git a/clang/test/SemaHLSL/prohibit_reference.hlsl b/clang/test/SemaHLSL/prohibit_reference.hlsl
new file mode 100644 (file)
index 0000000..6e76cfa
--- /dev/null
@@ -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;
+}