diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8c612b42ca02..67c4f3e7dddd 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5630,7 +5630,14 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, Expr *commonExpr = 0; if (LHSExpr == 0) { commonExpr = CondExpr; - + // Lower out placeholder types first. This is important so that we don't + // try to capture a placeholder. This happens in few cases in C++; such + // as Objective-C++'s dictionary subscripting syntax. + if (commonExpr->hasPlaceholderType()) { + ExprResult result = CheckPlaceholderExpr(commonExpr); + if (!result.isUsable()) return ExprError(); + commonExpr = result.take(); + } // We usually want to apply unary conversions *before* saving, except // in the special case of a C++ l-value conditional. if (!(getLangOpts().CPlusPlus diff --git a/clang/test/SemaObjCXX/missing-lhs-gun-extension.mm b/clang/test/SemaObjCXX/missing-lhs-gun-extension.mm new file mode 100644 index 000000000000..0b5c998bd755 --- /dev/null +++ b/clang/test/SemaObjCXX/missing-lhs-gun-extension.mm @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// expected-no-diagnostics +// rdar://13749180 + +@interface NSDictionary +- (id)objectForKeyedSubscript:(id)key; +- (void)setObject:(id)object forKeyedSubscript:(id)key; +- (int &) random; +@end + +@class NSString; + +template T tfoo(U x) { return x; } + +void func() { + NSDictionary* foo; + NSString* result = foo[@"bar"] ? : foo[@"baz"]; + + int (*fn)(int) = (&tfoo ?: 0); + + int x = 0; + const int &y = foo.random ?: x; +}