llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: yonghong-song

<details>
<summary>Changes</summary>

Sema::BuildBuiltinCallExpr() refers to the builtin with the type of its 
declaration, so the callee of the generated call is a reference to an ordinary 
function:
```
  ImplicitCastExpr 'void *(*)() noexcept' &lt;FunctionToPointerDecay&gt;
  `-DeclRefExpr 'void *() noexcept' lvalue Function '__builtin_coro_frame'
```
But a builtin written in the source, which is not directly addressable, is 
referred to with the builtin function type and converted by BuiltinFnToFnPtr:
```
  ImplicitCastExpr 'void *(*)() noexcept' &lt;BuiltinFnToFnPtr&gt;
  `-DeclRefExpr '&lt;builtin fn type&gt;' Function '__builtin_coro_frame'
```
The two forms are not handled the same way. For example, for a builtin which 
cannot be constant evaluated, the constant evaluator gives up on the 
BuiltinFnToFnPtr callee right away, but for the FunctionToPointerDecay callee 
it evaluates the arguments first, which may emit additional notes, e.g., 
"dereferencing a null pointer is not allowed in a constant expression".

Build the reference with BuildDeclarationNameExpr() as the parser does, so a 
builtin call built by Sema is the same as an explicit one. This will be used by 
a following BPF change, which builds a __builtin_preserve_enum_value() call in 
Sema and expects the same diagnostics as an explicit call.

The only visible change is the AST of the generated builtin calls, e.g., for 
coroutine builtins and HLSL __builtin_get_spirv_spec_constant_*.

---
Full diff: https://github.com/llvm/llvm-project/pull/235231.diff


3 Files Affected:

- (modified) clang/lib/Sema/SemaExpr.cpp (+4-2) 
- (modified) clang/test/AST/HLSL/vk.spec-constant.usage.hlsl (+24-24) 
- (modified) clang/test/SemaCXX/co_await-ast.cpp (+2-2) 


``````````diff
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 43b0c86132172b..0e8b67145aef85 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7255,8 +7255,10 @@ Expr *Sema::BuildBuiltinCallExpr(SourceLocation Loc, 
Builtin::ID Id,
   auto *BuiltInDecl = R.getAsSingle<FunctionDecl>();
   assert(BuiltInDecl && "failed to find builtin declaration");
 
-  ExprResult DeclRef =
-      BuildDeclRefExpr(BuiltInDecl, BuiltInDecl->getType(), VK_LValue, Loc);
+  // Refer to the builtin as if it were written in the source, so that the
+  // call is handled the same as an explicit one.
+  ExprResult DeclRef = BuildDeclarationNameExpr(
+      CXXScopeSpec(), R.getLookupNameInfo(), BuiltInDecl);
   assert(DeclRef.isUsable() && "Builtin reference cannot fail");
 
   ExprResult Call =
diff --git a/clang/test/AST/HLSL/vk.spec-constant.usage.hlsl 
b/clang/test/AST/HLSL/vk.spec-constant.usage.hlsl
index a7e8223a325e67..c8b5648b3a7ca2 100644
--- a/clang/test/AST/HLSL/vk.spec-constant.usage.hlsl
+++ b/clang/test/AST/HLSL/vk.spec-constant.usage.hlsl
@@ -2,8 +2,8 @@
 
 // CHECK: VarDecl {{.*}} bool_const 'const hlsl_private bool' static cinit
 // CHECK-NEXT: CallExpr {{.*}} 'bool'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'bool (*)(unsigned int, bool) noexcept' 
<FunctionToPointerDecay>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'bool (unsigned int, bool) noexcept' lvalue 
Function {{.*}} '__builtin_get_spirv_spec_constant_bool' 'bool (unsigned int, 
bool) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'bool (*)(unsigned int, bool) noexcept' 
<BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_get_spirv_spec_constant_bool' 'bool (unsigned int, bool) noexcept'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 1
 // CHECK-NEXT: CXXBoolLiteralExpr {{.*}} 'bool' true
@@ -12,8 +12,8 @@ const bool bool_const = true;
 
 // CHECK: VarDecl {{.*}} short_const 'const hlsl_private short' static cinit
 // CHECK-NEXT: CallExpr {{.*}} 'short'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'short (*)(unsigned int, short) 
noexcept' <FunctionToPointerDecay>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'short (unsigned int, short) noexcept' 
lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_short' 'short 
(unsigned int, short) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'short (*)(unsigned int, short) 
noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_get_spirv_spec_constant_short' 'short (unsigned int, short) noexcept'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 2
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'short' <IntegralCast>
@@ -23,8 +23,8 @@ const short short_const = 4;
 
 // CHECK: VarDecl {{.*}} int_const 'const hlsl_private int' static cinit
 // CHECK-NEXT: CallExpr {{.*}} 'int'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int (*)(unsigned int, int) noexcept' 
<FunctionToPointerDecay>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'int (unsigned int, int) noexcept' lvalue 
Function {{.*}} '__builtin_get_spirv_spec_constant_int' 'int (unsigned int, 
int) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int (*)(unsigned int, int) noexcept' 
<BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_get_spirv_spec_constant_int' 'int (unsigned int, int) noexcept'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 3
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 5
@@ -33,8 +33,8 @@ const int int_const = 5;
 
 // CHECK: VarDecl {{.*}} long_const 'const hlsl_private long long' static cinit
 // CHECK-NEXT: CallExpr {{.*}} 'long long'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'long long (*)(unsigned int, long long) 
noexcept' <FunctionToPointerDecay>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'long long (unsigned int, long long) 
noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_longlong' 
'long long (unsigned int, long long) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'long long (*)(unsigned int, long long) 
noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_get_spirv_spec_constant_longlong' 'long long (unsigned int, long 
long) noexcept'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 4
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'long long' <IntegralCast>
@@ -44,8 +44,8 @@ const long long long_const = 8;
 
 // CHECK: VarDecl {{.*}} ushort_const 'const hlsl_private unsigned short' 
static cinit
 // CHECK-NEXT: CallExpr {{.*}} 'unsigned short'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned short (*)(unsigned int, 
unsigned short) noexcept' <FunctionToPointerDecay>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned short (unsigned int, unsigned 
short) noexcept' lvalue Function {{.*}} 
'__builtin_get_spirv_spec_constant_ushort' 'unsigned short (unsigned int, 
unsigned short) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned short (*)(unsigned int, 
unsigned short) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_get_spirv_spec_constant_ushort' 'unsigned short (unsigned int, 
unsigned short) noexcept'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 5
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned short' <IntegralCast>
@@ -55,8 +55,8 @@ const unsigned short ushort_const = 10;
 
 // CHECK: VarDecl {{.*}} uint_const 'const hlsl_private unsigned int' static 
cinit
 // CHECK-NEXT: CallExpr {{.*}} 'unsigned int'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int (*)(unsigned int, 
unsigned int) noexcept' <FunctionToPointerDecay>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int (unsigned int, unsigned int) 
noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_uint' 
'unsigned int (unsigned int, unsigned int) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int (*)(unsigned int, 
unsigned int) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_get_spirv_spec_constant_uint' 'unsigned int (unsigned int, unsigned 
int) noexcept'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 6
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
@@ -66,8 +66,8 @@ const unsigned int uint_const = 12;
 
 // CHECK: VarDecl {{.*}} uint_const_2 'const hlsl_private uint':'const 
hlsl_private unsigned int' static cinit
 // CHECK-NEXT: CallExpr {{.*}} 'unsigned int'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int (*)(unsigned int, 
unsigned int) noexcept' <FunctionToPointerDecay>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int (unsigned int, unsigned int) 
noexcept' lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_uint' 
'unsigned int (unsigned int, unsigned int) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int (*)(unsigned int, 
unsigned int) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_get_spirv_spec_constant_uint' 'unsigned int (unsigned int, unsigned 
int) noexcept'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 6
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
@@ -78,8 +78,8 @@ const uint uint_const_2 = 12;
 
 // CHECK: VarDecl {{.*}} ulong_const 'const hlsl_private unsigned long long' 
static cinit
 // CHECK-NEXT: CallExpr {{.*}} 'unsigned long long'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned long long (*)(unsigned int, 
unsigned long long) noexcept' <FunctionToPointerDecay>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned long long (unsigned int, unsigned 
long long) noexcept' lvalue Function {{.*}} 
'__builtin_get_spirv_spec_constant_ulonglong' 'unsigned long long (unsigned 
int, unsigned long long) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned long long (*)(unsigned int, 
unsigned long long) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_get_spirv_spec_constant_ulonglong' 'unsigned long long (unsigned 
int, unsigned long long) noexcept'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 7
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned long long' <IntegralCast>
@@ -89,8 +89,8 @@ const unsigned long long ulong_const = 25;
 
 // CHECK: VarDecl {{.*}} half_const 'const hlsl_private half' static cinit
 // CHECK-NEXT: CallExpr {{.*}} 'half'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'half (*)(unsigned int, half) noexcept' 
<FunctionToPointerDecay>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'half (unsigned int, half) noexcept' lvalue 
Function {{.*}} '__builtin_get_spirv_spec_constant_half' 'half (unsigned int, 
half) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'half (*)(unsigned int, half) noexcept' 
<BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_get_spirv_spec_constant_half' 'half (unsigned int, half) noexcept'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 8
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'half' <FloatingCast>
@@ -100,8 +100,8 @@ const half half_const = 40.4;
 
 // CHECK: VarDecl {{.*}} float_const 'const hlsl_private float' static cinit
 // CHECK-NEXT: CallExpr {{.*}} 'float'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float (*)(unsigned int, float) 
noexcept' <FunctionToPointerDecay>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'float (unsigned int, float) noexcept' 
lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_float' 'float 
(unsigned int, float) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float (*)(unsigned int, float) 
noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_get_spirv_spec_constant_float' 'float (unsigned int, float) noexcept'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 8
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <IntegralToFloating>
@@ -111,8 +111,8 @@ const float float_const = 50;
 
 // CHECK: VarDecl {{.*}} double_const 'const hlsl_private double' static cinit
 // CHECK-NEXT: CallExpr {{.*}} 'double'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'double (*)(unsigned int, double) 
noexcept' <FunctionToPointerDecay>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'double (unsigned int, double) noexcept' 
lvalue Function {{.*}} '__builtin_get_spirv_spec_constant_double' 'double 
(unsigned int, double) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'double (*)(unsigned int, double) 
noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_get_spirv_spec_constant_double' 'double (unsigned int, double) 
noexcept'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 9
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'double' <IntegralToFloating>
@@ -123,8 +123,8 @@ const double double_const = 100;
 // CHECK: VarDecl {{.*}} enum_const 'const hlsl_private E' static cinit
 // CHECK-NEXT: CStyleCastExpr {{.*}} 'E' <IntegralCast>
 // CHECK-NEXT: CallExpr {{.*}} 'int'
-// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int (*)(unsigned int, int) noexcept' 
<FunctionToPointerDecay>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'int (unsigned int, int) noexcept' lvalue 
Function {{.*}} '__builtin_get_spirv_spec_constant_int' 'int (unsigned int, 
int) noexcept'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int (*)(unsigned int, int) noexcept' 
<BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_get_spirv_spec_constant_int' 'int (unsigned int, int) noexcept'
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <IntegralCast>
 // CHECK-NEXT: IntegerLiteral {{.*}} 'int' 10 
 // CHECK-NEXT: ImplicitCastExpr {{.*}} 'int' <IntegralCast>
diff --git a/clang/test/SemaCXX/co_await-ast.cpp 
b/clang/test/SemaCXX/co_await-ast.cpp
index 90683cd08d482c..8487a7bfd4f4cd 100644
--- a/clang/test/SemaCXX/co_await-ast.cpp
+++ b/clang/test/SemaCXX/co_await-ast.cpp
@@ -82,8 +82,8 @@ awaitable foo() {
 // CHECK:   |     |           |-ImplicitCastExpr {{.*}} 
'coroutine_handle<awaitable_frame> (*)(void *) noexcept' 
<FunctionToPointerDecay>
 // CHECK:   |     |           | `-DeclRefExpr {{.*}} 
'coroutine_handle<awaitable_frame> (void *) noexcept' lvalue CXXMethod {{.*}} 
'from_address' 'coroutine_handle<awaitable_frame> (void *) noexcept'
 // CHECK:   |     |           `-CallExpr {{.*}} 'void *'
-// CHECK:   |     |             `-ImplicitCastExpr {{.*}} 'void *(*)() 
noexcept' <FunctionToPointerDecay>
-// CHECK:   |     |               `-DeclRefExpr {{.*}} 'void *() noexcept' 
lvalue Function {{.*}} '__builtin_coro_frame' 'void *() noexcept'
+// CHECK:   |     |             `-ImplicitCastExpr {{.*}} 'void *(*)() 
noexcept' <BuiltinFnToFnPtr>
+// CHECK:   |     |               `-DeclRefExpr {{.*}} '<builtin fn type>' 
Function {{.*}} '__builtin_coro_frame' 'void *() noexcept'
 // CHECK:   |     `-CXXMemberCallExpr {{.*}} 'void'
 // CHECK:   |       `-MemberExpr {{.*}} '<bound member function type>' 
.await_resume {{.*}}
 // CHECK:   |         `-ImplicitCastExpr {{.*}} 'const 
awaitable_frame::result_t' lvalue <NoOp>

``````````

</details>


https://github.com/llvm/llvm-project/pull/235231
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to