Skip to content

Commit ca8a411

Browse files
committed
[C++20] [Modules] Always emit the inline builtins
See the attached test for the motivation example. If we're too greedy to not emit the definition for inline builtins, we may meet a middle end crash. And it should be good to emit inline builtins always.
1 parent b1542af commit ca8a411

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4022,6 +4022,11 @@ bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
40224022
return true;
40234023

40244024
const auto *F = cast<FunctionDecl>(GD.getDecl());
4025+
// Inline builtins declaration must be emitted. They often are fortified
4026+
// functions.
4027+
if (F->isInlineBuiltinDeclaration())
4028+
return true;
4029+
40254030
if (CodeGenOpts.OptimizationLevel == 0 && !F->hasAttr<AlwaysInlineAttr>())
40264031
return false;
40274032

@@ -4067,11 +4072,6 @@ bool CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
40674072
}
40684073
}
40694074

4070-
// Inline builtins declaration must be emitted. They often are fortified
4071-
// functions.
4072-
if (F->isInlineBuiltinDeclaration())
4073-
return true;
4074-
40754075
// PR9614. Avoid cases where the source code is lying to us. An available
40764076
// externally function should have an equivalent function somewhere else,
40774077
// but a function that calls itself through asm label/`__builtin_` trickery is
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: rm -rf %t
2+
// RUN: split-file %s %t
3+
// RUN: cd %t
4+
//
5+
// RUN: %clang_cc1 -std=c++20 -O3 %t/a.cppm -emit-module-interface -o %t/a.pcm
6+
// RUN: %clang_cc1 -std=c++20 -O3 %t/test.cc -fmodule-file=a=%t/a.pcm \
7+
// RUN: -emit-llvm -o - | FileCheck %t/test.cc
8+
9+
//--- memmove.h
10+
typedef long unsigned int size_t;
11+
extern "C" void *memmove (void *__dest, const void *__src, size_t __n)
12+
throw () __attribute__ ((__nonnull__ (1, 2)));
13+
extern "C" __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) void *
14+
memmove (void *__dest, const void *__src, size_t __len) throw ()
15+
{
16+
return __builtin_memmove(__dest, __src, __len);
17+
}
18+
19+
//--- a.cppm
20+
module;
21+
#include "memmove.h"
22+
export module a;
23+
export using ::memmove;
24+
25+
//--- test.cc
26+
import a;
27+
28+
void test() {
29+
int a, b;
30+
unsigned c = 0;
31+
memmove(&a, &b, c);
32+
}
33+
34+
// CHECK-NOT: memmove

0 commit comments

Comments
 (0)