[clang] [clang][Sema] Fix diagnostic for function overloading in extern "C" (PR #106033)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 26 19:28:04 PDT 2024
https://github.com/s-watanabe314 updated https://github.com/llvm/llvm-project/pull/106033
>From 9baf5ad604782827af0a8a42aa1fd5bf2894a84e Mon Sep 17 00:00:00 2001
From: Shunsuke Watanabe <watanabe.shu-06 at fujitsu.com>
Date: Fri, 23 Aug 2024 17:37:57 +0900
Subject: [PATCH 1/2] poor diagnostic due to overloading in extern "C" block
#80235
Fixes #80235
When trying to overload a function within `extern "C"`, the diagnostic
`functions that differ only in their return type cannot be overloaded`
is given. This diagnostic is inappropriate because overloading is
basically not allowed in the C language. However, if the redeclared
function has the `((overloadable))` attribute, it should be diagnosed as
`functions that differ only in their return type cannot be overloaded`.
This patch uses `isExternC()` to provide an appropriate diagnostic
during the diagnostic process. `isExternC()` updates the linkage
information cache internally, so calling it before merging functions
can cause clang to crash. An example is declaring `static void foo()`
and `void foo()` within an `extern "C"` block. Therefore, I decided to
call `isExternC()` after the compilation error is confirmed and select
the diagnostic message. The diagnostic message is
`conflicting types for 'func'` similar to the diagnostic in C, and
`functions that differ only in their return type cannot be overloaded`
if the `((overloadable))` attribute is given.
Regression tests verify that the expected diagnostics are given when
trying to overload functions within `extern "C"` and when the
`((overloadable))` attribute is present.
---
clang/lib/Sema/SemaDecl.cpp | 4 ++++
clang/test/SemaCXX/extern-c.cpp | 19 +++++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index b0ccbbe34b70c3..cd256ae81f53d9 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3882,6 +3882,10 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, Scope *S,
if (New->isCXXClassMember() && New->isOutOfLine())
Diag(New->getLocation(), diag::err_member_def_does_not_match_ret_type)
<< New << New->getReturnTypeSourceRange();
+ else if (Old->isExternC() && New->isExternC() &&
+ !Old->hasAttr<OverloadableAttr>() &&
+ !New->hasAttr<OverloadableAttr>())
+ Diag(New->getLocation(), diag::err_conflicting_types) << New;
else
Diag(New->getLocation(), diag::err_ovl_diff_return_type)
<< New->getReturnTypeSourceRange();
diff --git a/clang/test/SemaCXX/extern-c.cpp b/clang/test/SemaCXX/extern-c.cpp
index 68d1494b94918f..86012670ddcd57 100644
--- a/clang/test/SemaCXX/extern-c.cpp
+++ b/clang/test/SemaCXX/extern-c.cpp
@@ -77,6 +77,19 @@ namespace foo {
}
}
+namespace extern_ovl {
+ extern "C" {
+ __attribute__((overloadable))
+ void ovl_decl(void); // expected-note {{previous}}
+
+ __attribute__((overloadable))
+ int ovl_decl(int);
+
+ __attribute__((overloadable))
+ int ovl_decl(void); // expected-error {{functions that differ only in their return type}}
+ }
+}
+
namespace linkage {
namespace redecl {
extern "C" {
@@ -88,6 +101,12 @@ namespace linkage {
void linkage_redecl(double); // expected-error {{conflicting types}}
}
}
+ namespace redecl_2 {
+ extern "C" {
+ void linkage_redecl_2(); // expected-note {{previous}}
+ int linkage_redecl_2(int); // expected-error {{conflicting types}}
+ }
+ }
namespace from_outer {
void linkage_from_outer_1(); // expected-note {{previous}}
void linkage_from_outer_2(); // expected-note {{previous}}
>From 69ebe6abc38b94fd9b21c78ddd72a059dcc32a59 Mon Sep 17 00:00:00 2001
From: Shunsuke Watanabe <watanabe.shu-06 at fujitsu.com>
Date: Tue, 27 Aug 2024 11:21:41 +0900
Subject: [PATCH 2/2] fixup! poor diagnostic due to overloading in extern "C"
block #80235
---
clang/docs/ReleaseNotes.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2c29d49ba20f03..75e74549cbca1c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -261,6 +261,8 @@ Improvements to Clang's diagnostics
compilation speed with modules. This warning is disabled by default and it needs
to be explicitly enabled or by ``-Weverything``.
+- Improved diagnostics when trying to overload a function in extern "C". (#GH80235)
+
Improvements to Clang's time-trace
----------------------------------
More information about the cfe-commits
mailing list