diff options
author | Tom Stellard <thomas.stellard@amd.com> | 2015-05-04 18:23:59 +0000 |
---|---|---|
committer | Tom Stellard <thomas.stellard@amd.com> | 2015-05-04 18:23:59 +0000 |
commit | e1d60147c8246e289429baac914e28afe5699333 (patch) | |
tree | 015e932e488f035c0aec04b47a78b2c54ccbac2d | |
parent | 67d49afc70d3810c0699525e964c0ff5762613f3 (diff) | |
download | llvm-e1d60147c8246e289429baac914e28afe5699333.zip llvm-e1d60147c8246e289429baac914e28afe5699333.tar.gz llvm-e1d60147c8246e289429baac914e28afe5699333.tar.bz2 |
Merging r232786:
------------------------------------------------------------------------
r232786 | david.majnemer | 2015-03-19 20:02:27 -0400 (Thu, 19 Mar 2015) | 7 lines
Don't crash-on-valid when an inline function is friend of class template
We assumed that the most recent declaration of an inline function would
also be inline. However, a more recent declaration can come from a
friend declaration in a class template that is instantiated at the
definition of the function.
------------------------------------------------------------------------
llvm-svn: 236442
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/Decl.cpp | 3 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/inline-functions.cpp | 15 |
3 files changed, 18 insertions, 2 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 2875508..c9fb80c 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -7874,7 +7874,7 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, // Functions specified with extern and inline in -fms-compatibility mode // forcibly get emitted. While the body of the function cannot be later // replaced, the function definition cannot be discarded. - if (FD->getMostRecentDecl()->isMSExternInline()) + if (FD->isMSExternInline()) return GVA_StrongODR; return GVA_DiscardableODR; diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index e43c28a..dc08d23 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2674,7 +2674,8 @@ bool FunctionDecl::isMSExternInline() const { if (!Context.getLangOpts().MSVCCompat && !hasAttr<DLLExportAttr>()) return false; - for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDecl()) + for (const FunctionDecl *FD = getMostRecentDecl(); FD; + FD = FD->getPreviousDecl()) if (FD->getStorageClass() == SC_Extern) return true; diff --git a/clang/test/CodeGenCXX/inline-functions.cpp b/clang/test/CodeGenCXX/inline-functions.cpp index 622cfa9..20da1f6 100644 --- a/clang/test/CodeGenCXX/inline-functions.cpp +++ b/clang/test/CodeGenCXX/inline-functions.cpp @@ -121,3 +121,18 @@ struct TypeWithInlineMethods { // CHECK-NOT: _ZN21TypeWithInlineMethods12NonStaticFunEv void NonStaticFun() { StaticFun(); } }; + +namespace PR22959 { +template <typename> +struct S; + +S<int> Foo(); + +template <typename> +struct S { + friend S<int> Foo(); +}; + +__attribute__((used)) inline S<int> Foo() { return S<int>(); } +// CHECK-LABEL: define linkonce_odr void @_ZN7PR229593FooEv( +} |