aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-06-21 05:54:50 +0000
committerJordan Rose <jordan_rose@apple.com>2012-06-21 05:54:50 +0000
commit05233276b5b0d76e9ebd75eaa2709dff9b316590 (patch)
treec0f0c572edb867cb1c19dd9fecf53f6092da5082 /lib/Sema/SemaExpr.cpp
parent20e4129bd088da0a3bb7ea4941242802096cfcfc (diff)
Don't warn for -Wstatic-in-inline if the used function is also inline.
Also, don't warn if the used function is __attribute__((const)), in which case it's not supposed to use global variables anyway. The inline-in-inline thing is a heuristic, and one that's possibly incorrect fairly often because the function being inlined could definitely use global variables. However, even some C standard library functions are written using other (trivial) static-inline functions in the headers, and we definitely don't want to be warning on that (or on anything that /uses/ these trivial inline functions). So we're using "inlined" as a marker for "fairly trivial". (Note that __attribute__((pure)) does /not/ guarantee safety like ((const), because ((const)) does not guarantee that global variables are not being used, and the warning is about globals not being shared across TUs.) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158898 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp22
1 files changed, 15 insertions, 7 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index de0de89b83..e50dfca8f5 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -172,13 +172,21 @@ static void diagnoseUseOfInternalDeclInInlineFunction(Sema &S,
if (D->getLinkage() != InternalLinkage)
return;
- // Don't warn unless -pedantic is on if the inline function is in the main
- // source file. 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)
- << isa<VarDecl>(D) << D;
+ // Downgrade from ExtWarn to Extension if
+ // (1) the supposedly external inline function is in the main file,
+ // and probably won't be included anywhere else.
+ // (2) the thing we're referencing is a pure function.
+ // (3) the thing we're referencing is another inline function.
+ // This last can give us false negatives, but it's better than warning on
+ // wrappers for simple C library functions.
+ const FunctionDecl *UsedFn = dyn_cast<FunctionDecl>(D);
+ bool DowngradeWarning = S.getSourceManager().isFromMainFile(Loc);
+ if (!DowngradeWarning && UsedFn)
+ DowngradeWarning = UsedFn->isInlined() || UsedFn->hasAttr<ConstAttr>();
+
+ S.Diag(Loc, DowngradeWarning ? diag::ext_internal_in_extern_inline
+ : diag::warn_internal_in_extern_inline)
+ << /*IsVar=*/!UsedFn << D;
// Suggest "static" on the inline function, if possible.
if (!hasAnyExplicitStorageClass(Current)) {