================
@@ -0,0 +1,78 @@
+// -fkeep-inline-functions has an effect without optimization, although it is
+// primarily useful with optimization enabled.
+
+// RUN: %clang_cc1 -O2 -fkeep-inline-functions -emit-llvm %s -o - -triple 
x86_64-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -O0 -fkeep-inline-functions -emit-llvm %s -o - -triple 
x86_64-unknown-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -O2 -fkeep-inline-functions -emit-llvm %s -o - -triple 
powerpc64-ibm-aix-xcoff | FileCheck %s
+// RUN: %clang_cc1 -O0 -fkeep-inline-functions -emit-llvm %s -o - -triple 
powerpc64-ibm-aix-xcoff | FileCheck %s
+
+// -fkeep-inline-functions retains inline function definitions available in
+// this translation unit. Definitions emitted with available_externally
+// linkage are excluded.
+
+// Retained:
+//   f1  explicit inline and referenced
+//   f2  static inline
+//   f3  constexpr (implicit inline)
+//   f4  in-class member definition (implicit inline)
+//   f7  explicit inline and unreferenced
+//   f8  explicitly instantiated inline template
+//   TestCtorDtor implicitly inline constructor/destructor variants.
+
+//   Also exercises the GlobalDecl construction path in MustBeEmitted() for
+//   constructors/destructors. Without the special handling, debug builds hit
+//   the GlobalDecl(FunctionDecl*) assertion.
+
+// Not retained:
+//   f5  non-inline
+//   f6  GNU extern inline
+//   f9  extern template specialization
+
+inline int f1(int x) { return x + 1; }
+
+static inline int f2(int x) { return x + 2; }
+
+constexpr int f3(int x) { return x + 3; }
+
+struct S {
+  int f4() { return 4; }
+};
+
+int f5(int x) { return x + 5; }
+
+__attribute__((gnu_inline)) extern inline int f6(int x) { return x + 6; }
+
+inline int f7(int x) { return x + 7; }
+
+template <typename T> inline T f8(T x) { return x + 8; }
+template int f8<int>(int);
+
+template <typename T>
+struct A {
+  static int f9() { return 9; }
+};
+extern template int A<int>::f9();
+
+// Implicitly inline ctor and dtor intentionally unreferenced so
+// MustBeEmitted() is the sole mechanism that forces their emission.
+struct TestCtorDtor {
+  TestCtorDtor() {}
+  ~TestCtorDtor() {}
+};
+
+int use(S s) {
+  return f1(0) + f5(0) + f6(0) + A<int>::f9();
+}
+// CHECK: @llvm{{(\.compiler)?}}.used = appending global [10 x ptr]
+
+// CHECK-DAG: define {{.*}}@_Z2f1i
+// CHECK-DAG: define internal {{.*}}@_ZL2f2i
+// CHECK-DAG: define {{.*}}@_Z2f3i
+// CHECK-DAG: define {{.*}}@_ZN1S2f4Ev
+// CHECK-DAG: define {{.*}}@_Z2f7i
+// CHECK-DAG: define {{.*}}@_Z2f8IiET_S0_
+// CHECK-DAG: define {{.*}}@_ZN12TestCtorDtorC1Ev
+// CHECK-DAG: define {{.*}}@_ZN12TestCtorDtorD1Ev
+// CHECK-DAG: define {{.*}}@_ZN12TestCtorDtorC2Ev
+// CHECK-DAG: define {{.*}}@_ZN12TestCtorDtorD2Ev
----------------
hubert-reinterpretcast wrote:

This passes because `-mconstructor-aliases` is not the default for `-cc1` but 
is passed by the driver by default at least for Linux. A RUN line should be 
added with said option and FIXMEs will be needed.

https://github.com/llvm/llvm-project/pull/218533
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to