aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaDecl.cpp15
-rw-r--r--test/SemaCXX/static-initializers.cpp12
2 files changed, 23 insertions, 4 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 021673bf07..d8d77b0d54 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1325,8 +1325,12 @@ void Sema::AddInitializerToDecl(DeclTy *dcl, ExprTy *init) {
} else if (!VDecl->isInvalidDecl()) {
if (CheckInitializerTypes(Init, DclT))
VDecl->setInvalidDecl();
- if (SC == VarDecl::Static) // C99 6.7.8p4.
- CheckForConstantInitializer(Init, DclT);
+
+ // C++ 3.6.2p2, allow dynamic initialization of static initializers.
+ if (!getLangOptions().CPlusPlus) {
+ if (SC == VarDecl::Static) // C99 6.7.8p4.
+ CheckForConstantInitializer(Init, DclT);
+ }
}
} else if (VDecl->isFileVarDecl()) {
if (VDecl->getStorageClass() == VarDecl::Extern)
@@ -1335,8 +1339,11 @@ void Sema::AddInitializerToDecl(DeclTy *dcl, ExprTy *init) {
if (CheckInitializerTypes(Init, DclT))
VDecl->setInvalidDecl();
- // C99 6.7.8p4. All file scoped initializers need to be constant.
- CheckForConstantInitializer(Init, DclT);
+ // C++ 3.6.2p2, allow dynamic initialization of static initializers.
+ if (!getLangOptions().CPlusPlus) {
+ // C99 6.7.8p4. All file scoped initializers need to be constant.
+ CheckForConstantInitializer(Init, DclT);
+ }
}
// If the type changed, it means we had an incomplete type that was
// completed by the initializer. For example:
diff --git a/test/SemaCXX/static-initializers.cpp b/test/SemaCXX/static-initializers.cpp
new file mode 100644
index 0000000000..0da412ab29
--- /dev/null
+++ b/test/SemaCXX/static-initializers.cpp
@@ -0,0 +1,12 @@
+// RUN: clang -fsyntax-only -verify %s
+int f()
+{
+ return 10;
+}
+
+void g()
+{
+ static int a = f();
+}
+
+static int b = f();