[clang] [Sema] Decay functions/array to pointers in `IncompatiblePointerDiscardsQualifiers` and `IncompatibleOBTKinds` cases (PR #187038)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 1 06:45:10 PDT 2026
https://github.com/NeKon69 updated https://github.com/llvm/llvm-project/pull/187038
>From 689607bea1bc8b23b2bee65be9887686e7d7081b Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Thu, 26 Feb 2026 23:38:45 +0300
Subject: [PATCH 01/11] [clang][Sema] decay functions to pointers for qualifier
discarding and overflow behavior
---
clang/lib/Sema/SemaExpr.cpp | 8 ++++++++
.../CodeGen/incompatible-ptr-function-to-ptr-decay.c | 12 ++++++++++++
2 files changed, 20 insertions(+)
create mode 100644 clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 9cf7f36e12aa6..81d8d3141e72d 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -17531,6 +17531,10 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
// Perform array-to-pointer decay if necessary.
if (SrcType->isArrayType()) SrcType = Context.getArrayDecayedType(SrcType);
+ // Perform function-to-pointer decay if necessary.
+ if (SrcType->isFunctionType())
+ SrcType = Context.getDecayedType(SrcType);
+
isInvalid = true;
Qualifiers lhq = SrcType->getPointeeType().getQualifiers();
@@ -17553,6 +17557,10 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
if (SrcType->isArrayType())
SrcType = Context.getArrayDecayedType(SrcType);
+ // Perform function-to-pointer decay if necessary.
+ if (SrcType->isFunctionType())
+ SrcType = Context.getDecayedType(SrcType);
+
DiagKind = diag::ext_typecheck_convert_discards_overflow_behavior;
break;
case AssignConvertType::CompatiblePointerDiscardsQualifiers:
diff --git a/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c b/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c
new file mode 100644
index 0000000000000..1efe53518f7e4
--- /dev/null
+++ b/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c
@@ -0,0 +1,12 @@
+// RUN: not %clang_cc1 -fsyntax-only %s 2>&1 | FileCheck %s
+
+// Issue 182534
+int a();
+
+// CHECK: error: passing 'int (*)()' to parameter of type '__global int (*)' changes address space of pointer
+void b(__attribute__((opencl_global)) int(*) );
+
+void c() {
+ b(a);
+}
+
>From f87be2c7b8d57779818b59fcb03db440af906060 Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Fri, 27 Feb 2026 11:36:22 +0300
Subject: [PATCH 02/11] [clang][Sema] shorten checks and switch to diagnostic
test syntax
---
clang/lib/Sema/SemaExpr.cpp | 14 ++++----------
.../incompatible-ptr-function-to-ptr-decay.c | 5 +++--
2 files changed, 7 insertions(+), 12 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 81d8d3141e72d..1e39ae951700c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -17528,11 +17528,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
}
break;
case AssignConvertType::IncompatiblePointerDiscardsQualifiers: {
- // Perform array-to-pointer decay if necessary.
- if (SrcType->isArrayType()) SrcType = Context.getArrayDecayedType(SrcType);
-
- // Perform function-to-pointer decay if necessary.
- if (SrcType->isFunctionType())
+ // Perform decay if necessary.
+ if (SrcType->isArrayType() || SrcType->isFunctionType())
SrcType = Context.getDecayedType(SrcType);
isInvalid = true;
@@ -17554,11 +17551,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
// fallthrough
}
case AssignConvertType::IncompatiblePointerDiscardsOverflowBehavior:
- if (SrcType->isArrayType())
- SrcType = Context.getArrayDecayedType(SrcType);
-
- // Perform function-to-pointer decay if necessary.
- if (SrcType->isFunctionType())
+ // Perform decay if necessary.
+ if (SrcType->isArrayType() || SrcType->isFunctionType())
SrcType = Context.getDecayedType(SrcType);
DiagKind = diag::ext_typecheck_convert_discards_overflow_behavior;
diff --git a/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c b/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c
index 1efe53518f7e4..385e9e6929f0d 100644
--- a/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c
+++ b/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c
@@ -1,12 +1,13 @@
-// RUN: not %clang_cc1 -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
// Issue 182534
int a();
-// CHECK: error: passing 'int (*)()' to parameter of type '__global int (*)' changes address space of pointer
void b(__attribute__((opencl_global)) int(*) );
+// expected-note at -1 {{passing argument to parameter here}}
void c() {
b(a);
+ // expected-error at -1 {{passing 'int (*)()' to parameter of type '__global int (*)' changes address space of pointer}}
}
>From d7a7df08be2704526af50943c1e1d8fdab285750 Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Fri, 27 Feb 2026 11:53:40 +0300
Subject: [PATCH 03/11] [clang][Sema] use a label in the test
---
clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c b/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c
index 385e9e6929f0d..ffeac9f46b194 100644
--- a/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c
+++ b/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c
@@ -3,11 +3,11 @@
// Issue 182534
int a();
-void b(__attribute__((opencl_global)) int(*) );
-// expected-note at -1 {{passing argument to parameter here}}
+void b(__attribute__((opencl_global)) int(*) ); // #bdecl
void c() {
b(a);
// expected-error at -1 {{passing 'int (*)()' to parameter of type '__global int (*)' changes address space of pointer}}
+ // expected-note@#bdecl {{passing argument to parameter here}}
}
>From efa75a76379e55ab3382031876275f72f0a21774 Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Wed, 4 Mar 2026 19:07:33 +0300
Subject: [PATCH 04/11] [clang][Sema] add release notes, move tests to another
folder, fix another crash, revert the change involving
`IncompatiblePointerDiscardsOverflowBehavior` case
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/Sema/SemaExpr.cpp | 7 +++++--
.../incompatible-ptr-function-to-ptr-decay.c | 13 -------------
.../Sema/incompatible-function-to-ptr-decay.c | 16 ++++++++++++++++
4 files changed, 22 insertions(+), 15 deletions(-)
delete mode 100644 clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c
create mode 100644 clang/test/Sema/incompatible-function-to-ptr-decay.c
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6c26d514865ea..ef437b76f6a9f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -355,6 +355,7 @@ Miscellaneous Clang Crashes Fixed
- Fixed an assertion when diagnosing address-space qualified ``new``/``delete`` in language-defined address spaces such as OpenCL ``__local``. (#GH178319)
- Fixed an assertion failure in ObjC++ ARC when binding a rvalue reference to reference with different lifetimes (#GH178524)
- Fixed a crash when subscripting a vector type with large unsigned integer values. (#GH180563)
+- Fixed a crash when attempting to diagnose incompatible conversions involving function types (#GH182534)
OpenACC Specific Changes
------------------------
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index a269d35a89032..660f449b4d75a 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -17559,8 +17559,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
}
case AssignConvertType::IncompatiblePointerDiscardsOverflowBehavior:
// Perform decay if necessary.
- if (SrcType->isArrayType() || SrcType->isFunctionType())
- SrcType = Context.getDecayedType(SrcType);
+ if (SrcType->isArrayType())
+ SrcType = Context.getArrayDecayedType(SrcType);
DiagKind = diag::ext_typecheck_convert_discards_overflow_behavior;
break;
@@ -17741,6 +17741,9 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
Diag(IFace->getLocation(), diag::note_incomplete_class_and_qualified_id)
<< IFace << PDecl;
+ if (SrcType->isArrayType() || SrcType->isFunctionType()) {
+ SrcType = Context.getDecayedType(SrcType);
+ }
if (SecondType == Context.OverloadTy)
NoteAllOverloadCandidates(OverloadExpr::find(SrcExpr).Expression,
FirstType, /*TakingAddress=*/true);
diff --git a/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c b/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c
deleted file mode 100644
index ffeac9f46b194..0000000000000
--- a/clang/test/CodeGen/incompatible-ptr-function-to-ptr-decay.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-// Issue 182534
-int a();
-
-void b(__attribute__((opencl_global)) int(*) ); // #bdecl
-
-void c() {
- b(a);
- // expected-error at -1 {{passing 'int (*)()' to parameter of type '__global int (*)' changes address space of pointer}}
- // expected-note@#bdecl {{passing argument to parameter here}}
-}
-
diff --git a/clang/test/Sema/incompatible-function-to-ptr-decay.c b/clang/test/Sema/incompatible-function-to-ptr-decay.c
new file mode 100644
index 0000000000000..483387eb60a72
--- /dev/null
+++ b/clang/test/Sema/incompatible-function-to-ptr-decay.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -fexperimental-overflow-behavior-types -verify %s
+
+// Issue 182534
+int foo();
+
+void bar(__attribute__((opencl_global)) int*); // #cldecl
+void baz(__ob_wrap int*); // #ofdecl
+
+void a() {
+ bar(foo);
+ __ob_trap int val[10];
+ baz(val);
+ // expected-error at -1 {{passing 'int (*)()' to parameter of type '__ob_wrap int (*)' changes address space of pointer}}
+ // expected-note@#ofdecl {{passing argument to parameter here}}
+}
+
>From 57eb487928de71135b803f7905ffe15b8317eeee Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Wed, 4 Mar 2026 19:19:34 +0300
Subject: [PATCH 05/11] [clang][Sema] extends previous commit
---
clang/lib/Sema/SemaExpr.cpp | 6 +++---
clang/test/Sema/incompatible-function-to-ptr-decay.c | 4 +++-
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 660f449b4d75a..aeb5d22f4bddd 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -17651,6 +17651,9 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
case AssignConvertType::CompatibleOBTDiscards:
return false;
case AssignConvertType::IncompatibleOBTKinds: {
+ if (SrcType->isArrayType() || SrcType->isFunctionType()) {
+ SrcType = Context.getDecayedType(SrcType);
+ }
auto getOBTKindName = [](QualType Ty) -> StringRef {
if (Ty->isPointerType())
Ty = Ty->getPointeeType();
@@ -17741,9 +17744,6 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
Diag(IFace->getLocation(), diag::note_incomplete_class_and_qualified_id)
<< IFace << PDecl;
- if (SrcType->isArrayType() || SrcType->isFunctionType()) {
- SrcType = Context.getDecayedType(SrcType);
- }
if (SecondType == Context.OverloadTy)
NoteAllOverloadCandidates(OverloadExpr::find(SrcExpr).Expression,
FirstType, /*TakingAddress=*/true);
diff --git a/clang/test/Sema/incompatible-function-to-ptr-decay.c b/clang/test/Sema/incompatible-function-to-ptr-decay.c
index 483387eb60a72..240b5b8763a23 100644
--- a/clang/test/Sema/incompatible-function-to-ptr-decay.c
+++ b/clang/test/Sema/incompatible-function-to-ptr-decay.c
@@ -8,9 +8,11 @@ void baz(__ob_wrap int*); // #ofdecl
void a() {
bar(foo);
+ // expected-error at -1 {{passing 'int (*)()' to parameter of type '__global int *' changes address space of pointer}}
+ // expected-note@#cldecl {{passing argument to parameter here}}
__ob_trap int val[10];
baz(val);
- // expected-error at -1 {{passing 'int (*)()' to parameter of type '__ob_wrap int (*)' changes address space of pointer}}
+ // expected-error at -1 {{assigning to '__ob_wrap int *' from '__ob_trap int *' with incompatible overflow behavior types ('__ob_wrap' and '__ob_trap')}}
// expected-note@#ofdecl {{passing argument to parameter here}}
}
>From b5555c869e04f9d29079d8732d104ff06a6c07da Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Wed, 11 Mar 2026 19:14:12 +0300
Subject: [PATCH 06/11] fix check
---
clang/lib/Sema/SemaExpr.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index aeb5d22f4bddd..1d4c35cc4e523 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -17651,7 +17651,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
case AssignConvertType::CompatibleOBTDiscards:
return false;
case AssignConvertType::IncompatibleOBTKinds: {
- if (SrcType->isArrayType() || SrcType->isFunctionType()) {
+ if (SrcType->isArrayType()) {
SrcType = Context.getDecayedType(SrcType);
}
auto getOBTKindName = [](QualType Ty) -> StringRef {
>From 6af94eb27e6cdd759d71dca50713b789277f87ae Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Thu, 12 Mar 2026 18:18:45 +0300
Subject: [PATCH 07/11] delete braces and comment
---
clang/lib/Sema/SemaExpr.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 1d4c35cc4e523..d5dc62715bb47 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -17558,7 +17558,6 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
// fallthrough
}
case AssignConvertType::IncompatiblePointerDiscardsOverflowBehavior:
- // Perform decay if necessary.
if (SrcType->isArrayType())
SrcType = Context.getArrayDecayedType(SrcType);
@@ -17651,9 +17650,9 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
case AssignConvertType::CompatibleOBTDiscards:
return false;
case AssignConvertType::IncompatibleOBTKinds: {
- if (SrcType->isArrayType()) {
+ if (SrcType->isArrayType())
SrcType = Context.getDecayedType(SrcType);
- }
+
auto getOBTKindName = [](QualType Ty) -> StringRef {
if (Ty->isPointerType())
Ty = Ty->getPointeeType();
>From 959cacedca89e1de4698c0e41ef75ed935760675 Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Thu, 12 Mar 2026 18:36:13 +0300
Subject: [PATCH 08/11] add an assertion for function type
---
clang/lib/Sema/SemaExpr.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index d5dc62715bb47..48293c8d7e92f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -64,6 +64,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/TypeSize.h"
@@ -17653,6 +17654,9 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
if (SrcType->isArrayType())
SrcType = Context.getDecayedType(SrcType);
+ assert(!SrcType->isFunctionType() &&
+ "Unexpected function type found in IncompatibleOBTKinds assignment");
+
auto getOBTKindName = [](QualType Ty) -> StringRef {
if (Ty->isPointerType())
Ty = Ty->getPointeeType();
>From b43299968b6ed734a4626f9e61bfc5d5c48a896a Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Mon, 30 Mar 2026 20:31:17 +0300
Subject: [PATCH 09/11] apply suggestions
---
clang/lib/Sema/SemaExpr.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 48293c8d7e92f..af7feab37b6da 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -64,7 +64,6 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/TypeSize.h"
@@ -17537,7 +17536,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
break;
case AssignConvertType::IncompatiblePointerDiscardsQualifiers: {
// Perform decay if necessary.
- if (SrcType->isArrayType() || SrcType->isFunctionType())
+ if (SrcType->canDecayToPointerType())
SrcType = Context.getDecayedType(SrcType);
isInvalid = true;
>From 50fac0c17b76e6177d331d71d55bd1123ff20f6d Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Wed, 1 Apr 2026 11:41:00 +0300
Subject: [PATCH 10/11] switch to canDecayToPointerType for
IncompatibleOBTKinds
---
clang/lib/Sema/SemaExpr.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index af7feab37b6da..270694dbee7f0 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -17650,11 +17650,11 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
case AssignConvertType::CompatibleOBTDiscards:
return false;
case AssignConvertType::IncompatibleOBTKinds: {
- if (SrcType->isArrayType())
- SrcType = Context.getDecayedType(SrcType);
-
assert(!SrcType->isFunctionType() &&
"Unexpected function type found in IncompatibleOBTKinds assignment");
+ if (SrcType->canDecayToPointerType()) {
+ SrcType = Context.getDecayedType(SrcType);
+ }
auto getOBTKindName = [](QualType Ty) -> StringRef {
if (Ty->isPointerType())
>From 19e8ec9ed1501b704c08e2d5897c665a6f746999 Mon Sep 17 00:00:00 2001
From: NeKon69 <nobodqwe at gmail.com>
Date: Wed, 1 Apr 2026 13:44:54 +0000
Subject: [PATCH 11/11] fix fomatting
Co-authored-by: Aaron Ballman <aaron at aaronballman.com>
---
clang/lib/Sema/SemaExpr.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3431410c0e498..70fcb8d66ceee 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -17708,9 +17708,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
case AssignConvertType::IncompatibleOBTKinds: {
assert(!SrcType->isFunctionType() &&
"Unexpected function type found in IncompatibleOBTKinds assignment");
- if (SrcType->canDecayToPointerType()) {
+ if (SrcType->canDecayToPointerType())
SrcType = Context.getDecayedType(SrcType);
- }
auto getOBTKindName = [](QualType Ty) -> StringRef {
if (Ty->isPointerType())
More information about the cfe-commits
mailing list