From a676944b08172a0327838309e5bde17b4cf96a79 Mon Sep 17 00:00:00 2001 From: Joao Saffran Date: Thu, 24 Oct 2024 17:33:23 +0000 Subject: [PATCH] Adding Sema test --- clang/lib/CodeGen/CGBuiltin.cpp | 5 +- clang/lib/Sema/SemaHLSL.cpp | 12 +++++ .../test/SemaHLSL/BuiltIns/asuint-errors.hlsl | 26 ++++++++++ .../SemaHLSL/BuiltIns/splitdouble-errors.hlsl | 52 +++++++++++++++++++ 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaHLSL/BuiltIns/splitdouble-errors.hlsl diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 05a41d75c1c419..57ea4ef8b3f781 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -134,8 +134,9 @@ static Value *handleHlslSplitdouble(const CallExpr *E, CodeGenFunction *CGF) { // For Non DXIL targets we generate the instructions. // TODO: This code accounts for known limitations in // SPIR-V and splitdouble. Such should be handled, - // in a later compilation stage. After [issue link here] - // is fixed, this shall be refactored. + // in a later compilation stage. After + // https://github.com/llvm/llvm-project/issues/113597 is fixed, this shall + // be refactored. // casts `<2 x double>` to `<4 x i32>`, then shuffles into high and low // `<2 x i32>` vectors. diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 4346863d1869d9..7c13294afa7db7 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -1745,6 +1745,15 @@ static bool CheckFloatOrHalfRepresentations(Sema *S, CallExpr *TheCall) { checkFloatorHalf); } +static bool CheckModifiableLValue(Sema *S, CallExpr *TheCall, + unsigned ArgIndex) { + auto *Arg = TheCall->getArg(ArgIndex); + if (Arg->isModifiableLvalue(S->getASTContext()) == Expr::MLV_Valid) + return false; + S->Diag(Arg->getBeginLoc(), diag::error_hlsl_inout_lvalue) << Arg << 0; + return true; +} + static bool CheckNoDoubleVectors(Sema *S, CallExpr *TheCall) { auto checkDoubleVector = [](clang::QualType PassedType) -> bool { if (const auto *VecTy = PassedType->getAs()) @@ -2093,6 +2102,9 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { CheckScalarOrVector(&SemaRef, TheCall, SemaRef.Context.UnsignedIntTy, 2)) return true; + if (CheckModifiableLValue(&SemaRef, TheCall, 1) || + CheckModifiableLValue(&SemaRef, TheCall, 2)) + return true; break; } diff --git a/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl index b9a920f9f1b4d0..4adb0555c35be6 100644 --- a/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/asuint-errors.hlsl @@ -27,3 +27,29 @@ uint test_asuint_half(half p1) { // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: could not match 'vector' against 'half'}} // expected-note@hlsl/hlsl_detail.h:* {{candidate template ignored: substitution failure [with U = uint, T = half]: no type named 'Type'}} } + +void test_asuint_first_arg_const(double D) { + const uint A = 0; + uint B; + asuint(D, A, B); + // expected-error@hlsl/hlsl_intrinsics.h:* {{read-only variable is not assignable}} +} + +void test_asuint_second_arg_const(double D) { + const uint A = 0; + uint B; + asuint(D, B, A); + // expected-error@hlsl/hlsl_intrinsics.h:* {{read-only variable is not assignable}} +} + +void test_asuint_imidiate_value(double D) { + uint B; + asuint(D, B, 1); + // expected-error@-1 {{cannot bind non-lvalue argument 1 to out paramemter}} +} + +void test_asuint_expr(double D) { + uint B; + asuint(D, B, B + 1); + // expected-error@-1 {{cannot bind non-lvalue argument B + 1 to out paramemter}} +} diff --git a/clang/test/SemaHLSL/BuiltIns/splitdouble-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/splitdouble-errors.hlsl new file mode 100644 index 00000000000000..5bac11c4216a98 --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/splitdouble-errors.hlsl @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -verify + +void test_no_second_arg(double D) { + __builtin_hlsl_elementwise_splitdouble(D); + // expected-error@-1 {{too few arguments to function call, expected 3, have 1}} +} + +void test_no_third_arg(double D) { + uint A; + __builtin_hlsl_elementwise_splitdouble(D, A); + // expected-error@-1 {{too few arguments to function call, expected 3, have 2}} +} + +void test_too_many_arg(double D) { + uint A, B, C; + __builtin_hlsl_elementwise_splitdouble(D, A, B, C); + // expected-error@-1 {{too many arguments to function call, expected 3, have 4}} +} + +void test_first_arg_type_mismatch(bool3 D) { + uint3 A, B; + __builtin_hlsl_elementwise_splitdouble(D, A, B); + // expected-error@-1 {{invalid operand of type 'bool3' (aka 'vector') where 'double' or a vector of such type is required}} +} + +void test_second_arg_type_mismatch(double D) { + bool A; + uint B; + __builtin_hlsl_elementwise_splitdouble(D, A, B); + // expected-error@-1 {{invalid operand of type 'bool' where 'unsigned int' or a vector of such type is required}} +} + +void test_third_arg_type_mismatch(double D) { + bool A; + uint B; + __builtin_hlsl_elementwise_splitdouble(D, B, A); + // expected-error@-1 {{invalid operand of type 'bool' where 'unsigned int' or a vector of such type is required}} +} + +void test_const_second_arg(double D) { + const uint A = 1; + uint B; + __builtin_hlsl_elementwise_splitdouble(D, A, B); + // expected-error@-1 {{cannot bind non-lvalue argument}} +} + +void test_const_third_arg(double D) { + uint A; + const uint B = 2; + __builtin_hlsl_elementwise_splitdouble(D, A, B); + // expected-error@-1 {{cannot bind non-lvalue argument}} +}