mstorsjo created this revision. mstorsjo added reviewers: dblaikie, pcc, efriedma. Herald added a project: clang.
This matches how GCC handles it, see e.g. https://gcc.godbolt.org/z/HPplnl. The previous behaviour of gnu_inline in C++, without the extern keyword, can be traced back to the original commit that added support for gnu_inline, SVN r69045. Repository: rC Clang https://reviews.llvm.org/D67414 Files: lib/AST/Decl.cpp test/CodeGen/inline.c Index: test/CodeGen/inline.c =================================================================== --- test/CodeGen/inline.c +++ test/CodeGen/inline.c @@ -52,7 +52,7 @@ // CHECK3-LABEL: define i32 @_Z3barv() // CHECK3-LABEL: define linkonce_odr i32 @_Z3foov() // CHECK3-NOT: unreferenced -// CHECK3-LABEL: define void @_Z10gnu_inlinev() +// CHECK3-LABEL: define available_externally void @_Z10gnu_inlinev() // CHECK3-LABEL: define available_externally void @_Z13gnu_ei_inlinev() // CHECK3-NOT: @_Z5testCv // CHECK3-LABEL: define linkonce_odr i32 @_Z2eiv() @@ -85,6 +85,7 @@ extern __inline void unreferenced2() {} __inline __attribute((__gnu_inline__)) void gnu_inline() {} +void (*P1)() = gnu_inline; // PR3988 extern __inline __attribute__((gnu_inline)) void gnu_ei_inline() {} Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -3257,7 +3257,8 @@ // // FIXME: What happens if gnu_inline gets added on after the first // declaration? - if (!isInlineSpecified() || getStorageClass() == SC_Extern) + if (!isInlineSpecified() || getStorageClass() == SC_Extern || + Context.getLangOpts().CPlusPlus) return false; const FunctionDecl *Prev = this; @@ -3360,6 +3361,8 @@ // If it's not the case that both 'inline' and 'extern' are // specified on the definition, then this inline definition is // externally visible. + if (Context.getLangOpts().CPlusPlus) + return false; if (!(isInlineSpecified() && getStorageClass() == SC_Extern)) return true;
Index: test/CodeGen/inline.c =================================================================== --- test/CodeGen/inline.c +++ test/CodeGen/inline.c @@ -52,7 +52,7 @@ // CHECK3-LABEL: define i32 @_Z3barv() // CHECK3-LABEL: define linkonce_odr i32 @_Z3foov() // CHECK3-NOT: unreferenced -// CHECK3-LABEL: define void @_Z10gnu_inlinev() +// CHECK3-LABEL: define available_externally void @_Z10gnu_inlinev() // CHECK3-LABEL: define available_externally void @_Z13gnu_ei_inlinev() // CHECK3-NOT: @_Z5testCv // CHECK3-LABEL: define linkonce_odr i32 @_Z2eiv() @@ -85,6 +85,7 @@ extern __inline void unreferenced2() {} __inline __attribute((__gnu_inline__)) void gnu_inline() {} +void (*P1)() = gnu_inline; // PR3988 extern __inline __attribute__((gnu_inline)) void gnu_ei_inline() {} Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -3257,7 +3257,8 @@ // // FIXME: What happens if gnu_inline gets added on after the first // declaration? - if (!isInlineSpecified() || getStorageClass() == SC_Extern) + if (!isInlineSpecified() || getStorageClass() == SC_Extern || + Context.getLangOpts().CPlusPlus) return false; const FunctionDecl *Prev = this; @@ -3360,6 +3361,8 @@ // If it's not the case that both 'inline' and 'extern' are // specified on the definition, then this inline definition is // externally visible. + if (Context.getLangOpts().CPlusPlus) + return false; if (!(isInlineSpecified() && getStorageClass() == SC_Extern)) return true;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits