aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2013-04-09 01:56:28 +0000
committerJohn McCall <rjmccall@apple.com>2013-04-09 01:56:28 +0000
commit045d2524e136fabd10613d7ac0063df632a7c2a5 (patch)
tree07909878f066a34dd610d29db8dd66fecdd06242
parent34366208e3ec6876ef501e85978466d2ddecb3d2 (diff)
When checking for illegal expressions in a default-argument
expression, look through pseudo-object expressions. rdar://13602832 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179080 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDeclCXX.cpp18
-rw-r--r--test/SemaObjCXX/property-reference.mm18
2 files changed, 36 insertions, 0 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 8f8e22a68a..ddc077456b 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -65,6 +65,7 @@ namespace {
bool VisitDeclRefExpr(DeclRefExpr *DRE);
bool VisitCXXThisExpr(CXXThisExpr *ThisE);
bool VisitLambdaExpr(LambdaExpr *Lambda);
+ bool VisitPseudoObjectExpr(PseudoObjectExpr *POE);
};
/// VisitExpr - Visit all of the children of this expression.
@@ -115,6 +116,23 @@ namespace {
<< ThisE->getSourceRange();
}
+ bool CheckDefaultArgumentVisitor::VisitPseudoObjectExpr(PseudoObjectExpr *POE) {
+ bool Invalid = false;
+ for (PseudoObjectExpr::semantics_iterator
+ i = POE->semantics_begin(), e = POE->semantics_end(); i != e; ++i) {
+ Expr *E = *i;
+
+ // Look through bindings.
+ if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) {
+ E = OVE->getSourceExpr();
+ assert(E && "pseudo-object binding without source expression?");
+ }
+
+ Invalid |= Visit(E);
+ }
+ return Invalid;
+ }
+
bool CheckDefaultArgumentVisitor::VisitLambdaExpr(LambdaExpr *Lambda) {
// C++11 [expr.lambda.prim]p13:
// A lambda-expression appearing in a default argument shall not
diff --git a/test/SemaObjCXX/property-reference.mm b/test/SemaObjCXX/property-reference.mm
index b86ae5e9f5..cfac9f30db 100644
--- a/test/SemaObjCXX/property-reference.mm
+++ b/test/SemaObjCXX/property-reference.mm
@@ -57,3 +57,21 @@ template<typename T> void f() {
}
template void f<int>();
+
+// rdar://13602832
+//
+// Make sure that the default-argument checker looks through
+// pseudo-object expressions correctly. The default argument
+// needs to force l2r to test this effectively because the checker
+// is syntactic and runs before placeholders are handled.
+@interface Test13602832
+- (int) x;
+@end
+namespace test13602832 {
+ template <int N> void foo(Test13602832 *a, int limit = a.x + N) {} // expected-error {{default argument references parameter 'a'}}
+
+ void test(Test13602832 *a) {
+ // FIXME: this is a useless cascade error.
+ foo<1024>(a); // expected-error {{no matching function}}
+ }
+}