[modules] Do not report missing definitions of demoted constexpr variable templates.
authorVassil Vassilev <v.g.vassilev@gmail.com>
Wed, 19 Oct 2016 11:19:30 +0000 (11:19 +0000)
committerVassil Vassilev <v.g.vassilev@gmail.com>
Wed, 19 Oct 2016 11:19:30 +0000 (11:19 +0000)
This is a followup to regression introduced in r284284.

This should fix our libstdc++ modules builds.

https://reviews.llvm.org/D25678

Reviewed by Richard Smith!

llvm-svn: 284577

clang/lib/Sema/SemaDecl.cpp
clang/test/Modules/Inputs/merge-var-template-def/a.h [new file with mode: 0644]
clang/test/Modules/Inputs/merge-var-template-def/b1.h [new file with mode: 0644]
clang/test/Modules/Inputs/merge-var-template-def/b2.h [new file with mode: 0644]
clang/test/Modules/Inputs/merge-var-template-def/module.modulemap [new file with mode: 0644]
clang/test/Modules/merge-var-template-def.cpp [new file with mode: 0644]

index af1ac44..b483690 100644 (file)
@@ -10124,7 +10124,11 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl,
     // C++11 [dcl.constexpr]p1: The constexpr specifier shall be applied only to
     // the definition of a variable [...] or the declaration of a static data
     // member.
-    if (Var->isConstexpr() && !Var->isThisDeclarationADefinition()) {
+    if (Var->isConstexpr() && !Var->isThisDeclarationADefinition() &&
+        !Var->isThisDeclarationADemotedDefinition()) {
+      assert((!Var->isThisDeclarationADemotedDefinition() ||
+              getLangOpts().Modules) &&
+             "Demoting decls is only in the contest of modules!");
       if (Var->isStaticDataMember()) {
         // C++1z removes the relevant rule; the in-class declaration is always
         // a definition there.
diff --git a/clang/test/Modules/Inputs/merge-var-template-def/a.h b/clang/test/Modules/Inputs/merge-var-template-def/a.h
new file mode 100644 (file)
index 0000000..6b414b3
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef A_H
+#define A_H
+template<typename T, T v>
+struct S { static constexpr T value = v; };
+template<typename T, T v>
+constexpr T S<T, v>::value;
+
+#endif
diff --git a/clang/test/Modules/Inputs/merge-var-template-def/b1.h b/clang/test/Modules/Inputs/merge-var-template-def/b1.h
new file mode 100644 (file)
index 0000000..35cab9d
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef B1_H
+#define B1_H
+template<typename T, T v>
+struct S { static constexpr T value = v; };
+template<typename T, T v>
+constexpr T S<T, v>::value;
+
+#include "a.h"
+#endif
diff --git a/clang/test/Modules/Inputs/merge-var-template-def/b2.h b/clang/test/Modules/Inputs/merge-var-template-def/b2.h
new file mode 100644 (file)
index 0000000..6ab87c2
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef B2_H
+#define B2_H
+
+template<typename T, T v>
+struct S { static constexpr T value = v; };
+template<typename T, T v>
+constexpr T S<T, v>::value;
+
+#endif
diff --git a/clang/test/Modules/Inputs/merge-var-template-def/module.modulemap b/clang/test/Modules/Inputs/merge-var-template-def/module.modulemap
new file mode 100644 (file)
index 0000000..b2c96bd
--- /dev/null
@@ -0,0 +1,5 @@
+module a { header "a.h" export * }
+module b {
+  module b1 { header "b1.h" export * }
+  module b2 { header "b2.h" export * }
+}
diff --git a/clang/test/Modules/merge-var-template-def.cpp b/clang/test/Modules/merge-var-template-def.cpp
new file mode 100644 (file)
index 0000000..97a72a1
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -I%S/Inputs/merge-var-template-def -std=c++11 -verify %s
+// RUN: %clang_cc1 -I%S/Inputs/merge-var-template-def -std=c++11 -verify -fmodules -Werror=undefined-internal -fmodules-local-submodule-visibility -fmodules-cache-path=%t -fimplicit-module-maps %s
+// expected-no-diagnostics
+
+#include "b2.h"
+const bool *y = &S<bool, false>::value;