aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td9
-rw-r--r--lib/Sema/SemaExpr.cpp24
-rw-r--r--test/Sema/inline.c1
-rw-r--r--test/SemaCXX/inline.cpp8
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