Author: mstorsjo Date: Fri Sep 27 05:25:19 2019 New Revision: 373078 URL: http://llvm.org/viewvc/llvm-project?rev=373078&view=rev Log: [clang] [AST] Treat "inline gnu_inline" the same way as "extern inline gnu_inline" in C++ mode
This matches how GCC handles it, see e.g. https://gcc.godbolt.org/z/HPplnl. GCC documents the gnu_inline attribute with "In C++, this attribute does not depend on extern in any way, but it still requires the inline keyword to enable its special behavior." 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. Differential Revision: https://reviews.llvm.org/D67414 Added: cfe/trunk/test/SemaCXX/gnu_inline.cpp Modified: cfe/trunk/docs/ReleaseNotes.rst cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/AST/Decl.cpp cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/test/CodeGen/inline.c cfe/trunk/test/SemaCUDA/gnu-inline.cu cfe/trunk/test/SemaCXX/undefined-inline.cpp Modified: cfe/trunk/docs/ReleaseNotes.rst URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=373078&r1=373077&r2=373078&view=diff ============================================================================== --- cfe/trunk/docs/ReleaseNotes.rst (original) +++ cfe/trunk/docs/ReleaseNotes.rst Fri Sep 27 05:25:19 2019 @@ -128,7 +128,10 @@ C11 Feature Support C++ Language Changes in Clang ----------------------------- -- ... +- The behaviour of the `gnu_inline` attribute now matches GCC, for cases + where used without the `extern` keyword. As this is a change compared to + how it behaved in previous Clang versions, a warning is emitted for this + combination. C++1z Feature Support ^^^^^^^^^^^^^^^^^^^^^ Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=373078&r1=373077&r2=373078&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Sep 27 05:25:19 2019 @@ -3008,6 +3008,10 @@ def warn_gnu_inline_attribute_requires_i "'gnu_inline' attribute requires function to be marked 'inline'," " attribute ignored">, InGroup<IgnoredAttributes>; +def warn_gnu_inline_cplusplus_without_extern : Warning< + "'gnu_inline' attribute without 'extern' in C++ treated as externally" + " available, this changed in Clang 10">, + InGroup<DiagGroup<"gnu-inline-cpp-without-extern">>; def err_attribute_vecreturn_only_vector_member : Error< "the vecreturn attribute can only be used on a class or structure with one member, which must be a vector">; def err_attribute_vecreturn_only_pod_record : Error< Modified: cfe/trunk/lib/AST/Decl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=373078&r1=373077&r2=373078&view=diff ============================================================================== --- cfe/trunk/lib/AST/Decl.cpp (original) +++ cfe/trunk/lib/AST/Decl.cpp Fri Sep 27 05:25:19 2019 @@ -3261,6 +3261,9 @@ bool FunctionDecl::doesDeclarationForceE return true; } + if (Context.getLangOpts().CPlusPlus) + return false; + if (Context.getLangOpts().GNUInline || hasAttr<GNUInlineAttr>()) { // With GNU inlining, a declaration with 'inline' but not 'extern', forces // an externally visible definition. @@ -3289,9 +3292,6 @@ bool FunctionDecl::doesDeclarationForceE return FoundBody; } - if (Context.getLangOpts().CPlusPlus) - return false; - // C99 6.7.4p6: // [...] If all of the file scope declarations for a function in a // translation unit include the inline function specifier without extern, @@ -3371,6 +3371,8 @@ bool FunctionDecl::isInlineDefinitionExt // 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; Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=373078&r1=373077&r2=373078&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Sep 27 05:25:19 2019 @@ -4255,6 +4255,9 @@ static void handleGNUInlineAttr(Sema &S, return; } + if (S.LangOpts.CPlusPlus && Fn->getStorageClass() != SC_Extern) + S.Diag(AL.getLoc(), diag::warn_gnu_inline_cplusplus_without_extern); + D->addAttr(::new (S.Context) GNUInlineAttr(S.Context, AL)); } Modified: cfe/trunk/test/CodeGen/inline.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/inline.c?rev=373078&r1=373077&r2=373078&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/inline.c (original) +++ cfe/trunk/test/CodeGen/inline.c Fri Sep 27 05:25:19 2019 @@ -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 @@ __inline void unreferenced1() {} 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() {} Modified: cfe/trunk/test/SemaCUDA/gnu-inline.cu URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCUDA/gnu-inline.cu?rev=373078&r1=373077&r2=373078&view=diff ============================================================================== --- cfe/trunk/test/SemaCUDA/gnu-inline.cu (original) +++ cfe/trunk/test/SemaCUDA/gnu-inline.cu Fri Sep 27 05:25:19 2019 @@ -7,4 +7,4 @@ // Check that we can handle gnu_inline functions when compiling in CUDA mode. void foo(); -inline __attribute__((gnu_inline)) void bar() { foo(); } +extern inline __attribute__((gnu_inline)) void bar() { foo(); } Added: cfe/trunk/test/SemaCXX/gnu_inline.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/gnu_inline.cpp?rev=373078&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/gnu_inline.cpp (added) +++ cfe/trunk/test/SemaCXX/gnu_inline.cpp Fri Sep 27 05:25:19 2019 @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +extern inline +__attribute__((__gnu_inline__)) +void gnu_inline1() {} + +inline +__attribute__((__gnu_inline__)) // expected-warning {{'gnu_inline' attribute without 'extern' in C++ treated as externally available, this changed in Clang 10}} +void gnu_inline2() {} Modified: cfe/trunk/test/SemaCXX/undefined-inline.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/undefined-inline.cpp?rev=373078&r1=373077&r2=373078&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/undefined-inline.cpp (original) +++ cfe/trunk/test/SemaCXX/undefined-inline.cpp Fri Sep 27 05:25:19 2019 @@ -40,20 +40,20 @@ namespace test7 { } namespace test8 { - inline void foo() __attribute__((gnu_inline)); + inline void foo() __attribute__((gnu_inline)); // expected-warning {{'gnu_inline' attribute without 'extern' in C++ treated as externally available, this changed in Clang 10}} void test() { foo(); } } namespace test9 { void foo(); void test() { foo(); } - inline void foo() __attribute__((gnu_inline)); + inline void foo() __attribute__((gnu_inline)); // expected-warning {{'gnu_inline' attribute without 'extern' in C++ treated as externally available, this changed in Clang 10}} } namespace test10 { inline void foo(); void test() { foo(); } - inline void foo() __attribute__((gnu_inline)); + inline void foo() __attribute__((gnu_inline)); // expected-warning {{'gnu_inline' attribute without 'extern' in C++ treated as externally available, this changed in Clang 10}} } namespace test11 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits