diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-25 18:46:26 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-06-25 18:46:26 +0000 |
commit | e83b1d3e7aa368a5a2e1a6e39f05595da8219eb9 (patch) | |
tree | 608073985e9fa0cae4ed3816885ad6b568576448 | |
parent | c43250338a92a4446194674f51843d66a9eaf19a (diff) | |
download | bcm5719-llvm-e83b1d3e7aa368a5a2e1a6e39f05595da8219eb9.tar.gz bcm5719-llvm-e83b1d3e7aa368a5a2e1a6e39f05595da8219eb9.zip |
More of N3652: don't add an implicit 'const' to 'constexpr' member functions when checking for overloads in C++1y.
llvm-svn: 184865
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 3 | ||||
-rw-r--r-- | clang/test/SemaCXX/constant-expression-cxx11.cpp | 24 | ||||
-rw-r--r-- | clang/test/SemaCXX/constant-expression-cxx1y.cpp | 24 |
3 files changed, 50 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 29644b40b74..d4d08b4bff8 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1080,7 +1080,8 @@ static bool shouldTryToOverload(Sema &S, FunctionDecl *New, FunctionDecl *Old, // or non-static member function). Add it now, on the assumption that this // is a redeclaration of OldMethod. unsigned NewQuals = NewMethod->getTypeQualifiers(); - if (NewMethod->isConstexpr() && !isa<CXXConstructorDecl>(NewMethod)) + if (!S.getLangOpts().CPlusPlus1y && NewMethod->isConstexpr() && + !isa<CXXConstructorDecl>(NewMethod)) NewQuals |= Qualifiers::Const; if (OldMethod->getTypeQualifiers() != NewQuals) return true; diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 4e2b7edb785..ca029d9d124 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -1670,3 +1670,27 @@ namespace StmtExpr { }); } } + +namespace VirtualFromBase { + struct S1 { + virtual int f() const; + }; + struct S2 { + virtual int f(); + }; + template <typename T> struct X : T { + constexpr X() {} + double d = 0.0; + constexpr int f() { return sizeof(T); } // expected-warning {{will not be implicitly 'const' in C++1y}} + }; + + // Virtual f(), not OK. + constexpr X<X<S1>> xxs1; + constexpr X<S1> *p = const_cast<X<X<S1>>*>(&xxs1); + static_assert(p->f() == sizeof(X<S1>), ""); // expected-error {{constant expression}} expected-note {{virtual function call}} + + // Non-virtual f(), OK. + constexpr X<X<S2>> xxs2; + constexpr X<S2> *q = const_cast<X<X<S2>>*>(&xxs2); + static_assert(q->f() == sizeof(S2), ""); +} diff --git a/clang/test/SemaCXX/constant-expression-cxx1y.cpp b/clang/test/SemaCXX/constant-expression-cxx1y.cpp index 6043a1fffc3..0d099c2120c 100644 --- a/clang/test/SemaCXX/constant-expression-cxx1y.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx1y.cpp @@ -790,3 +790,27 @@ namespace StmtExpr { return 0; } } + +namespace VirtualFromBase { + struct S1 { + virtual int f() const; + }; + struct S2 { + virtual int f(); + }; + template <typename T> struct X : T { + constexpr X() {} + double d = 0.0; + constexpr int f() { return sizeof(T); } + }; + + // Non-virtual f(), OK. + constexpr X<X<S1>> xxs1; + constexpr X<S1> *p = const_cast<X<X<S1>>*>(&xxs1); + static_assert(p->f() == sizeof(S1), ""); + + // Virtual f(), not OK. + constexpr X<X<S2>> xxs2; + constexpr X<S2> *q = const_cast<X<X<S2>>*>(&xxs2); + static_assert(q->f() == sizeof(X<S2>), ""); // expected-error {{constant expression}} expected-note {{virtual function call}} +} |