diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 5317b9d805b58..e441c338a2c76 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3314,8 +3314,23 @@ bool FunctionDecl::isInlineBuiltinDeclaration() const { return false; const FunctionDecl *Definition; - return hasBody(Definition) && Definition->isInlineSpecified() && - Definition->hasAttr(); + if (!hasBody(Definition)) + return false; + + if (!Definition->isInlineSpecified() || + !Definition->hasAttr()) + return false; + + ASTContext &Context = getASTContext(); + switch (Context.GetGVALinkageForFunction(this)) { + case GVA_Internal: + case GVA_DiscardableODR: + case GVA_StrongODR: + return false; + case GVA_AvailableExternally: + case GVA_StrongExternal: + return true; + } } bool FunctionDecl::isDestroyingOperatorDelete() const { diff --git a/clang/test/CodeGen/inline-builtin-comdat.c b/clang/test/CodeGen/inline-builtin-comdat.c new file mode 100644 index 0000000000000..1b00711de43e8 --- /dev/null +++ b/clang/test/CodeGen/inline-builtin-comdat.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple x86_64-windows -S -emit-llvm -disable-llvm-passes %s -o - | FileCheck %s +// Inline builtin are not supported for odr linkage +// CHECK-NOT: .inline + +double __cdecl frexp( double _X, int* _Y); +inline __attribute__((always_inline)) long double __cdecl frexpl( long double __x, int *__exp ) { + return (long double) frexp((double)__x, __exp ); +} + +long double pain(void) +{ + long double f = 123.45; + int i; + long double f2 = frexpl(f, &i); + return f2; +}