Skip to content

Conversation

@ChuanqiXu9
Copy link
Member

See the example:

export module func;
class C {
public:
    void member() try {

    } catch (...) {

    }
};

We woudln't generate the definition for C::member but we should. Since the function is non-inline in modules.

This turns out to be an oversight in parser to me. Since the try-catch body is relatively rare, so maybe we just forgot it.

…ry-catch body

See the example:

```
export module func;
class C {
public:
    void member() try {

    } catch (...) {

    }
};
```

We woudln't generate the definition for `C::member` but we should. Since
the function is non-inline in modules.

This turns out to be an oversight in parser to me. Since the try-catch
body is relatively rare, so maybe we just forgot it.
@ChuanqiXu9 ChuanqiXu9 added clang Clang issues not falling into any other category clang:modules C++20 modules and Clang Header Modules labels Feb 28, 2025
@llvmbot llvmbot added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Feb 28, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 28, 2025

@llvm/pr-subscribers-clang-modules

@llvm/pr-subscribers-clang

Author: Chuanqi Xu (ChuanqiXu9)

Changes

See the example:

export module func;
class C {
public:
    void member() try {

    } catch (...) {

    }
};

We woudln't generate the definition for C::member but we should. Since the function is non-inline in modules.

This turns out to be an oversight in parser to me. Since the try-catch body is relatively rare, so maybe we just forgot it.


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

2 Files Affected:

  • (modified) clang/lib/Parse/ParseCXXInlineMethods.cpp (+5)
  • (added) clang/test/Modules/try-func-body.cppm (+13)
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index 6c01af55ef3c4..723ebfa59fc03 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -632,6 +632,11 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) {
 
     if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
       ConsumeAnyToken();
+
+    if (auto *FD = dyn_cast_or_null<FunctionDecl>(LM.D))
+      if (isa<CXXMethodDecl>(FD) ||
+          FD->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend))
+        Actions.ActOnFinishInlineFunctionDef(FD);
     return;
   }
   if (Tok.is(tok::colon)) {
diff --git a/clang/test/Modules/try-func-body.cppm b/clang/test/Modules/try-func-body.cppm
new file mode 100644
index 0000000000000..379f5e47f4f8e
--- /dev/null
+++ b/clang/test/Modules/try-func-body.cppm
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++20 %s -fexceptions -fcxx-exceptions -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
+
+export module func;
+class C {
+public:
+    void member() try {
+
+    } catch (...) {
+
+    }
+};
+
+// CHECK: define {{.*}}@_ZNW4func1C6memberEv

Copy link
Contributor

@mizvekov mizvekov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use a scope guard here to avoid the duplication, and this includes the pre-existing EOF handling. This would make this sort of bug more unlikely to happen in the future.

@ChuanqiXu9
Copy link
Member Author

We could use a scope guard here to avoid the duplication, and this includes the pre-existing EOF handling. This would make this sort of bug more unlikely to happen in the future.

Done

Copy link
Contributor

@mizvekov mizvekov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM.

With just a little more effort you could add the EOF stuff in there too.

@ChuanqiXu9
Copy link
Member Author

Thanks, LGTM.

With just a little more effort you could add the EOF stuff in there too.

What do you mean by EOF stuff?

@mizvekov
Copy link
Contributor

mizvekov commented Mar 5, 2025

Thanks, LGTM.
With just a little more effort you could add the EOF stuff in there too.

What do you mean by EOF stuff?

It seems you can deduplicate by moving this block into the scope guard:

      while (Tok.isNot(tok::eof))
        ConsumeAnyToken();
      if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
        ConsumeAnyToken();

@ChuanqiXu9
Copy link
Member Author

Thanks, LGTM.
With just a little more effort you could add the EOF stuff in there too.

What do you mean by EOF stuff?

It seems you can deduplicate by moving this block into the scope guard:

      while (Tok.isNot(tok::eof))
        ConsumeAnyToken();
      if (Tok.is(tok::eof) && Tok.getEofData() == LM.D)
        ConsumeAnyToken();

Done

Copy link
Contributor

@mizvekov mizvekov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect, TYVM!

@ChuanqiXu9 ChuanqiXu9 merged commit 68427bc into llvm:main Mar 5, 2025
7 of 10 checks passed
@ChuanqiXu9 ChuanqiXu9 deleted the module_inline_class_func_try_catch_body branch March 5, 2025 02:42
@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 5, 2025

LLVM Buildbot has detected a new failure on builder clang-armv8-quick running on linaro-clang-armv8-quick while building clang at step 5 "ninja check 1".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/154/builds/12796

Here is the relevant piece of the build log for the reference
Step 5 (ninja check 1) failure: stage 1 checked (failure)
******************** TEST 'Clangd Unit Tests :: ./ClangdTests/49/161' FAILED ********************
Script(shard):
--
GTEST_OUTPUT=json:/home/tcwg-buildbot/worker/clang-armv8-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests-Clangd Unit Tests-2252840-49-161.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=161 GTEST_SHARD_INDEX=49 /home/tcwg-buildbot/worker/clang-armv8-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests
--

Note: This is test shard 50 of 161.
[==========] Running 8 tests from 8 test suites.
[----------] Global test environment set-up.
[----------] 1 test from ClangdServerTest
[ RUN      ] ClangdServerTest.ForceReparseCompileCommand
ASTWorker building file /clangd-test/foo.cpp version null with command 
[/clangd-test]
clang -xc /clangd-test/foo.cpp
Driver produced command: cc1 -cc1 -triple armv8a-unknown-linux-gnueabihf -fsyntax-only -disable-free -clear-ast-before-backend -main-file-name foo.cpp -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -target-cpu generic -target-feature +read-tp-tpidruro -target-feature +vfp2 -target-feature +vfp2sp -target-feature +vfp3 -target-feature +vfp3d16 -target-feature +vfp3d16sp -target-feature +vfp3sp -target-feature +fp16 -target-feature +vfp4 -target-feature +vfp4d16 -target-feature +vfp4d16sp -target-feature +vfp4sp -target-feature +fp-armv8 -target-feature +fp-armv8d16 -target-feature +fp-armv8d16sp -target-feature +fp-armv8sp -target-feature -fullfp16 -target-feature +fp64 -target-feature +d32 -target-feature +neon -target-feature +sha2 -target-feature +aes -target-feature -fp16fml -target-abi aapcs-linux -mfloat-abi hard -debugger-tuning=gdb -fdebug-compilation-dir=/clangd-test -fcoverage-compilation-dir=/clangd-test -resource-dir lib/clang/21 -internal-isystem lib/clang/21/include -internal-isystem /usr/local/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fno-signed-char -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -no-round-trip-args -faddrsig -x c /clangd-test/foo.cpp
Building first preamble for /clangd-test/foo.cpp version null
Built preamble of size 408800 for file /clangd-test/foo.cpp version null in 6.57 seconds
not idle after addDocument
UNREACHABLE executed at ../llvm/clang-tools-extra/clangd/unittests/SyncAPI.cpp:22!
#0 0x01355fd4 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/tcwg-buildbot/worker/clang-armv8-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0xaabfd4)
#1 0x013539c4 llvm::sys::RunSignalHandlers() (/home/tcwg-buildbot/worker/clang-armv8-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests+0xaa99c4)
#2 0x0135689c SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
#3 0xf759d6f0 __default_rt_sa_restorer ./signal/../sysdeps/unix/sysv/linux/arm/sigrestorer.S:80:0
#4 0xf758db06 ./csu/../sysdeps/unix/sysv/linux/arm/libc-do-syscall.S:47:0
#5 0xf75cd292 __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
#6 0xf759c840 gsignal ./signal/../sysdeps/posix/raise.c:27:6

--
exit: -6
--
shard JSON output does not exist: /home/tcwg-buildbot/worker/clang-armv8-quick/stage1/tools/clang/tools/extra/clangd/unittests/./ClangdTests-Clangd Unit Tests-2252840-49-161.json
********************


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants