aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/inline.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-06-18 22:09:19 +0000
committerJordan Rose <jordan_rose@apple.com>2012-06-18 22:09:19 +0000
commit0eb3f45a92f706d50de55aefb19d66febfba78aa (patch)
tree9a2ae3b197b5a70181a405474f11acf49cb08852 /test/SemaCXX/inline.cpp
parentdceccacff28d00717774300f5fe0067286ac65bf (diff)
Support -Winternal-linkage-in-inline in C++ code.
This includes treating anonymous namespaces like internal linkage, and allowing const variables to be used even if internal. The whole thing's been broken out into a separate function to avoid nested ifs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@158683 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaCXX/inline.cpp')
-rw-r--r--test/SemaCXX/inline.cpp105
1 files changed, 105 insertions, 0 deletions
diff --git a/test/SemaCXX/inline.cpp b/test/SemaCXX/inline.cpp
index e569300faf..9ef0229c99 100644
--- a/test/SemaCXX/inline.cpp
+++ b/test/SemaCXX/inline.cpp
@@ -1,5 +1,110 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+#if defined(INCLUDE)
+// -------
+// This section acts like a header file.
+// -------
+
+// Check the use of static variables in non-static inline functions.
+static int staticVar; // expected-note + {{'staticVar' declared here}}
+static int staticFunction(); // expected-note + {{'staticFunction' declared here}}
+const int constVar = 0; // no-warning
+
+namespace {
+ int anonVar; // expected-note + {{'anonVar' declared here}}
+ int anonFunction(); // expected-note + {{'anonFunction' declared here}}
+ const int anonConstVar = 0; // no-warning
+
+ class Anon {
+ public:
+ static int var; // expected-note + {{'var' declared here}}
+ static const int constVar = 0; // no-warning
+ };
+}
+
+inline void useStatic() { // expected-note + {{use 'static' to give inline function 'useStatic' internal linkage}}
+ staticFunction(); // expected-warning{{function 'staticFunction' has internal linkage but is used in an inline function with external linkage}}
+ (void)staticVar; // expected-warning{{variable 'staticVar' has internal linkage but is used in an inline function with external linkage}}
+ anonFunction(); // expected-warning{{function 'anonFunction' is in an anonymous namespace but is used in an inline function with external linkage}}
+ (void)anonVar; // expected-warning{{variable 'anonVar' is in an anonymous namespace but is used in an inline function with external linkage}}
+ (void)Anon::var; // expected-warning{{variable 'var' is in an anonymous namespace but is used in an inline function with external linkage}}
+
+ (void)constVar; // no-warning
+ (void)anonConstVar; // no-warning
+ (void)Anon::constVar; // no-warning
+}
+
+extern inline int useStaticFromExtern() { // no suggestions
+ staticFunction(); // expected-warning{{function 'staticFunction' has internal linkage 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}}
+}
+
+class A {
+public:
+ static inline int useInClass() { // no suggestions
+ return staticFunction(); // expected-warning{{function 'staticFunction' has internal linkage but is used in an inline method with external linkage}}
+ }
+ inline int useInInstance() { // no suggestions
+ return staticFunction(); // expected-warning{{function 'staticFunction' has internal linkage but is used in an inline method with external linkage}}
+ }
+};
+
+static inline void useStaticFromStatic () {
+ // No warnings.
+ staticFunction();
+ (void)staticVar;
+ (void)constVar;
+ anonFunction();
+ (void)anonVar;
+ (void)anonConstVar;
+ (void)Anon::var;
+ (void)Anon::constVar;
+}
+
+namespace {
+ inline void useStaticFromAnon() {
+ // No warnings.
+ staticFunction();
+ (void)staticVar;
+ (void)constVar;
+ anonFunction();
+ (void)anonVar;
+ (void)anonConstVar;
+ (void)Anon::var;
+ (void)Anon::constVar;
+ }
+}
+
+#else
+// -------
+// This is the main source file.
+// -------
+
+#define INCLUDE
+#include "inline.cpp"
+
// Check that we don't allow illegal uses of inline
// (checking C++-only constructs here)
struct c {inline int a;}; // expected-error{{'inline' can only appear on functions}}
+
+// Check that the warnings from the "header file" aren't on by default in
+// the main source file.
+
+inline int useStaticMainFile () {
+ anonFunction(); // no-warning
+ return staticVar; // no-warning
+}
+
+// Check that the warnings show up when explicitly requested.
+
+#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}}
+}
+
+#pragma clang diagnostic pop
+
+#endif