diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 9 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 24 | ||||
-rw-r--r-- | test/Sema/inline.c | 1 | ||||
-rw-r--r-- | test/SemaCXX/inline.cpp | 8 |
4 files changed, 26 insertions, 16 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 4507b2fd57..a07f00697b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2997,11 +2997,14 @@ def warn_undefined_internal : Warning< def note_used_here : Note<"used here">; def warn_internal_in_extern_inline : ExtWarn< - "%select{function|variable}0 %1 %select{has internal linkage|is in an anonymous" - " namespace}2 but is used in an inline %select{function|method}3 with" - " external linkage">, + "%select{function|variable}0 %1 has internal linkage but is used in an " + "inline function with external linkage">, InGroup<DiagGroup<"internal-linkage-in-inline"> >; def ext_internal_in_extern_inline : Extension< + "%select{function|variable}0 %1 has internal linkage but is used in an " + "inline function with external linkage">, + InGroup<DiagGroup<"internal-linkage-in-inline"> >; +def warn_internal_in_extern_inline_cxx : Warning< "%select{function|variable}0 %1 %select{has internal linkage|is in an anonymous" " namespace}2 but is used in an inline %select{function|method}3 with" " external linkage">, diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index c9b1a694d0..49c84664fc 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -203,15 +203,23 @@ static void diagnoseUseOfInternalDeclInInlineFunction(Sema &S, return; // Don't warn unless -pedantic is on if the inline function is in the main - // source file. These functions will most likely not be inlined into another - // translation unit, so they're effectively internal. + // source file, and in C++ don't warn at all, since the one-definition rule is + // still satisfied. This function will most likely not be inlined into + // another translation unit, so it's effectively internal. bool IsInMainFile = S.getSourceManager().isFromMainFile(Loc); - S.Diag(Loc, IsInMainFile ? diag::ext_internal_in_extern_inline - : diag::warn_internal_in_extern_inline) - << (bool)VD - << D - << (UsedLinkage == UniqueExternalLinkage) - << isa<CXXMethodDecl>(Current); + if (S.getLangOpts().CPlusPlus) { + if (IsInMainFile) + return; + + S.Diag(Loc, diag::warn_internal_in_extern_inline_cxx) + << (bool)VD << D + << (UsedLinkage == UniqueExternalLinkage) + << isa<CXXMethodDecl>(Current); + } else { + S.Diag(Loc, IsInMainFile ? diag::ext_internal_in_extern_inline + : diag::warn_internal_in_extern_inline) + << (bool)VD << D; + } // Suggest "static" on the inline function, if possible. if (!isa<CXXMethodDecl>(Current) && diff --git a/test/Sema/inline.c b/test/Sema/inline.c index 99df8b1106..7f1815e467 100644 --- a/test/Sema/inline.c +++ b/test/Sema/inline.c @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsyntax-only -verify -x c++ %s #if defined(INCLUDE) // ------- diff --git a/test/SemaCXX/inline.cpp b/test/SemaCXX/inline.cpp index 9ef0229c99..6f3570e3ca 100644 --- a/test/SemaCXX/inline.cpp +++ b/test/SemaCXX/inline.cpp @@ -95,14 +95,14 @@ inline int useStaticMainFile () { return staticVar; // no-warning } -// Check that the warnings show up when explicitly requested. +// Check that the warnings don't show up even when explicitly requested in C++. #pragma clang diagnostic push #pragma clang diagnostic warning "-Winternal-linkage-in-inline" -inline int useStaticAgain () { // expected-note 2 {{use 'static' to give inline function 'useStaticAgain' internal linkage}} - anonFunction(); // expected-warning{{function 'anonFunction' is in an anonymous namespace but is used in an inline function with external linkage}} - return staticVar; // expected-warning{{variable 'staticVar' has internal linkage but is used in an inline function with external linkage}} +inline int useStaticAgain () { + anonFunction(); // no-warning + return staticVar; // no-warning } #pragma clang diagnostic pop |