summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-06-25 18:46:26 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-06-25 18:46:26 +0000
commite83b1d3e7aa368a5a2e1a6e39f05595da8219eb9 (patch)
tree608073985e9fa0cae4ed3816885ad6b568576448
parentc43250338a92a4446194674f51843d66a9eaf19a (diff)
downloadbcm5719-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.cpp3
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx11.cpp24
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx1y.cpp24
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}}
+}
OpenPOWER on IntegriCloud