[clang] [clang][Sema] decay functions to pointers for qualifier discarding and overflow behavior (PR #183616)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 4 08:19:55 PST 2026
https://github.com/NeKon69 updated https://github.com/llvm/llvm-project/pull/183616
>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 1/5] [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 2/5] [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 3/5] [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 4/5] [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 5/5] [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}}
}
More information about the cfe-commits
mailing list