v.g.vassilev created this revision. v.g.vassilev added reviewers: rsmith, bkramer. v.g.vassilev added a subscriber: cfe-commits. v.g.vassilev set the repository for this revision to rL LLVM.
Repository: rL LLVM https://reviews.llvm.org/D25678 Files: lib/Sema/SemaDecl.cpp test/Modules/Inputs/merge-var-template-def/a.h test/Modules/Inputs/merge-var-template-def/b1.h test/Modules/Inputs/merge-var-template-def/b2.h test/Modules/merge-var-template-def.cpp Index: test/Modules/merge-var-template-def.cpp =================================================================== --- test/Modules/merge-var-template-def.cpp +++ test/Modules/merge-var-template-def.cpp @@ -1,7 +1,10 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -I%S/Inputs/merge-var-template-def -verify -fmodules -Werror=undefined-internal -fmodules-local-submodule-visibility -fmodules-cache-path=%t -fimplicit-module-maps %s +// 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" namespace { struct X; } void *x = get<X>(); + +const bool *y = &S<bool, false>::value; Index: test/Modules/Inputs/merge-var-template-def/b2.h =================================================================== --- test/Modules/Inputs/merge-var-template-def/b2.h +++ test/Modules/Inputs/merge-var-template-def/b2.h @@ -3,4 +3,10 @@ template<typename T> struct A { static bool b; }; template<typename T> bool A<T>::b = false; template<typename T> void *get() { return &(A<T>::b); } + +template<typename T, T v> +struct S { static constexpr T value = v; }; +template<typename T, T v> +constexpr T S<T, v>::value; + #endif Index: test/Modules/Inputs/merge-var-template-def/b1.h =================================================================== --- test/Modules/Inputs/merge-var-template-def/b1.h +++ test/Modules/Inputs/merge-var-template-def/b1.h @@ -3,5 +3,11 @@ template<typename T> struct A { static bool b; }; template<typename T> bool A<T>::b = false; template<typename T> void *get() { return &(A<T>::b); } + +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 Index: test/Modules/Inputs/merge-var-template-def/a.h =================================================================== --- test/Modules/Inputs/merge-var-template-def/a.h +++ test/Modules/Inputs/merge-var-template-def/a.h @@ -3,4 +3,10 @@ template<typename T> struct A { static bool b; }; template<typename T> bool A<T>::b = false; template<typename T> void *get() { return &(A<T>::b); } + +template<typename T, T v> +struct S { static constexpr T value = v; }; +template<typename T, T v> +constexpr T S<T, v>::value; + #endif Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -10124,7 +10124,10 @@ // 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.
Index: test/Modules/merge-var-template-def.cpp =================================================================== --- test/Modules/merge-var-template-def.cpp +++ test/Modules/merge-var-template-def.cpp @@ -1,7 +1,10 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -I%S/Inputs/merge-var-template-def -verify -fmodules -Werror=undefined-internal -fmodules-local-submodule-visibility -fmodules-cache-path=%t -fimplicit-module-maps %s +// 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" namespace { struct X; } void *x = get<X>(); + +const bool *y = &S<bool, false>::value; Index: test/Modules/Inputs/merge-var-template-def/b2.h =================================================================== --- test/Modules/Inputs/merge-var-template-def/b2.h +++ test/Modules/Inputs/merge-var-template-def/b2.h @@ -3,4 +3,10 @@ template<typename T> struct A { static bool b; }; template<typename T> bool A<T>::b = false; template<typename T> void *get() { return &(A<T>::b); } + +template<typename T, T v> +struct S { static constexpr T value = v; }; +template<typename T, T v> +constexpr T S<T, v>::value; + #endif Index: test/Modules/Inputs/merge-var-template-def/b1.h =================================================================== --- test/Modules/Inputs/merge-var-template-def/b1.h +++ test/Modules/Inputs/merge-var-template-def/b1.h @@ -3,5 +3,11 @@ template<typename T> struct A { static bool b; }; template<typename T> bool A<T>::b = false; template<typename T> void *get() { return &(A<T>::b); } + +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 Index: test/Modules/Inputs/merge-var-template-def/a.h =================================================================== --- test/Modules/Inputs/merge-var-template-def/a.h +++ test/Modules/Inputs/merge-var-template-def/a.h @@ -3,4 +3,10 @@ template<typename T> struct A { static bool b; }; template<typename T> bool A<T>::b = false; template<typename T> void *get() { return &(A<T>::b); } + +template<typename T, T v> +struct S { static constexpr T value = v; }; +template<typename T, T v> +constexpr T S<T, v>::value; + #endif Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -10124,7 +10124,10 @@ // 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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits