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...@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...@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 ---------------------------------- _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits