diff --git a/docs/language-reference/types-pointer.md b/docs/language-reference/types-pointer.md index d7c92e4462..4d46423ec4 100644 --- a/docs/language-reference/types-pointer.md +++ b/docs/language-reference/types-pointer.md @@ -68,8 +68,9 @@ See [pointer traits](#traits). The pointer declaration `*` applied to a base type creates a pointer type. The base type may be any [addressable](types-traits.md) type including pointer and [array](types-array.md) types. -To obtain the address of an object, the *address-of* operator `&` is used. The address may be assigned to a -pointer variable with a matching type. Alternatively, `__getAddress(obj)` may be used. +Pointer values are obtained from pointer-typed shader parameters (such as constant buffer fields) or by +performing pointer arithmetic on an existing pointer. There is no address-of operator that takes the address +of an arbitrary object. To access the *pointed-to* object, the pointer dereference operator `*` is used. If the pointed-to type is a [structure](types-struct.md) or a [class](types-class.md) type, the member access operators `.` or `->` may be @@ -97,23 +98,23 @@ For a comprehensive description, see [pointer expressions (TODO)](expressions.md > 📝 **Remark 1:** Currently, there are no `const` pointers in Slang. Pointers to read-only data and immutable > data may be declared with [generic pointer types](#generic-pointer). -> 📝 **Remark 2:** Consider the following pointer arithmetic: +> 📝 **Remark 2:** Consider the following pointer arithmetic, where `g_data` is a pointer obtained from a +> shader parameter (e.g., a constant buffer field) referencing an array of at least 10 elements: > > ```hlsl -> var arr : uint[10] = { }; > var ptr : uint *; > -> ptr = &arr[9]; // OK: ptr points to the last element -> // of the array +> ptr = g_data + 9; // OK: ptr points to the last element +> // of the referenced array > -> ptr++; // Still OK: ptr points to one past the -> // last element +> ptr++; // Still OK: ptr points to one past the +> // last element > -> ptr++; // Pointer is now invalid +> ptr++; // Pointer is now invalid > -> ptr--; // No validity guarantees with invalid -> // pointers in pointer expressions; -> // dereferencing would be undefined behavior +> ptr--; // No validity guarantees with invalid +> // pointers in pointer expressions; +> // dereferencing would be undefined behavior > ``` @@ -168,6 +169,6 @@ void main(uint3 id : SV_DispatchThreadID) // the input data buffer is big enough. outputBuffer[id.x] += sumOfValues( - g_inputData, &g_inputData[min(g_inputDataLen, 10)]); + g_inputData, g_inputData + min(g_inputDataLen, 10)); } ``` diff --git a/docs/user-guide/03-convenience-features.md b/docs/user-guide/03-convenience-features.md index 5b24ca7df4..7873c9da11 100644 --- a/docs/user-guide/03-convenience-features.md +++ b/docs/user-guide/03-convenience-features.md @@ -555,7 +555,7 @@ struct MyType int test(MyType* pObj) { MyType* pNext = pObj + 1; - MyType* pNext2 = &pNext[1]; + MyType* pNext2 = pNext + 1; return pNext.a + pNext->a + (*pNext2).a + pNext2[0].a; } @@ -568,13 +568,6 @@ int validTest() { return test(ptr); } - -int invalidTest() -{ - // cannot produce a pointer from a local variable - MyType obj; - return test(&obj); // !! ERROR !! -} ``` Pointer types can also be specified using the generic syntax @@ -589,7 +582,9 @@ declaring pointers to read-only and immutable values, and pointers to address sp - Slang supports pointers that are defined as shader parameters (e.g. as a constant buffer field). -- Slang can produce pointers using the & operator from data in global memory. +- Pointer values are obtained from pointer-typed shader parameters or by performing pointer arithmetic on + an existing pointer. Slang does not provide an address-of operator that takes the address of an arbitrary + object. - Slang doesn't support forming pointers to opaque handle types, e.g. `Texture2D`. For handle pointers, use `DescriptorHandle` instead. diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 925835ad2b..ef1d46f62b 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -2933,11 +2933,11 @@ __generic __intrinsic_op(0) __prefix Ref operator*(Ptr value); -// TODO: [require(cpu)]. This cannot be done yet since this change breaks slangpy __generic __intrinsic_op(0) [KnownBuiltin( $((int)KnownBuiltinDeclName::OperatorAddressOf))] [require(cpp_cuda_spirv_llvm)] +[RemovedSince(-1, "the '&' operator for taking addresses is no longer supported in Slang")] __prefix Ptr operator&(__ref T value); __generic<$(ptrTypeParameterList), TInt : __BuiltinIntegerType> diff --git a/tests/diagnostics/address-of-operator-unsupported.slang b/tests/diagnostics/address-of-operator-unsupported.slang new file mode 100644 index 0000000000..9cb7408708 --- /dev/null +++ b/tests/diagnostics/address-of-operator-unsupported.slang @@ -0,0 +1,14 @@ +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target spirv -entry computeMain -stage compute +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target cpp -entry computeMain -stage compute +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target cuda -entry computeMain -stage compute + +RWStructuredBuffer buffer; + +[shader("compute")] +[numthreads(1,1,1)] +void computeMain(uint3 threadId : SV_DispatchThreadID) +{ + // CHECK: error[E31207]: use of removed declaration + // CHECK: the '&' operator for taking addresses is no longer supported in Slang + float* p = &buffer[threadId.x]; +} diff --git a/tests/diagnostics/invalid-constant-pointer-taking.slang b/tests/diagnostics/invalid-constant-pointer-taking.slang index 0675eb5d4a..02c7fe6e7d 100644 --- a/tests/diagnostics/invalid-constant-pointer-taking.slang +++ b/tests/diagnostics/invalid-constant-pointer-taking.slang @@ -12,6 +12,8 @@ StructuredBuffer constant_uint_buffer; void computeMain(uint3 threadId : SV_DispatchThreadID) { float* mutablePtr1 = &mutable_float_buffer[threadId.x]; +//diag: ^ use of removed declaration +//diag: ^ the '&' operator for taking addresses is no longer supported in Slang float* mutablePtr2 = __getAddress(mutable_float_buffer[threadId.x]); //diag: ^^^^^^^^^^^^ invalid __getAddress usage @@ -21,6 +23,8 @@ void computeMain(uint3 threadId : SV_DispatchThreadID) // Constant pointers arent a thing in slang float* ptr1 = &constant_float_buffer[threadId.x]; +//diag: ^ use of removed declaration +//diag: ^ the '&' operator for taking addresses is no longer supported in Slang //diag: ^ cannot take address of immutable object //diag: ^ Not allowed to take the address of an immutable object //diag: ^ argument must be l-value diff --git a/tests/language-feature/dynamic-dispatch/diagnose-ptr-to-interface-implicit-cast.slang b/tests/language-feature/dynamic-dispatch/diagnose-ptr-to-interface-implicit-cast.slang index 1235a208de..29c0d8c9b7 100644 --- a/tests/language-feature/dynamic-dispatch/diagnose-ptr-to-interface-implicit-cast.slang +++ b/tests/language-feature/dynamic-dispatch/diagnose-ptr-to-interface-implicit-cast.slang @@ -36,6 +36,7 @@ void computeMain() { Foo f; f.val = 5; + // CHECK: error[E31207] Foo* pf = &f; // 1. Ptr -> Ptr: rejected (layout mismatch) diff --git a/tests/language-feature/dynamic-dispatch/ptr-to-interface-local.slang b/tests/language-feature/dynamic-dispatch/ptr-to-interface-local.slang index 99ff609c6d..107bc56e8c 100644 --- a/tests/language-feature/dynamic-dispatch/ptr-to-interface-local.slang +++ b/tests/language-feature/dynamic-dispatch/ptr-to-interface-local.slang @@ -26,5 +26,6 @@ void computeMain() IFoo local = a; // CHECK: error[E30019] + // CHECK: error[E31207] IFoo* p = &local; }