From 045d2524e136fabd10613d7ac0063df632a7c2a5 Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 9 Apr 2013 01:56:28 +0000 Subject: [PATCH] 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 --- lib/Sema/SemaDeclCXX.cpp | 18 ++++++++++++++++++ test/SemaObjCXX/property-reference.mm | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) 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(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 void f() { } template void f(); + +// 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 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}} + } +} -- 2.40.0