]> granicus.if.org Git - clang/commitdiff
Objective-C++ (and c++) Sema: Patch fixes a sema crash when gnu’s ?: extension
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 17 May 2013 16:29:36 +0000 (16:29 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 17 May 2013 16:29:36 +0000 (16:29 +0000)
is used for Objective-C++’s dictionary subscripting. This is done by filtering
out all placeholder types before check on lowering of the
common expression is done. // rdar://1374918.
Reviewed by John McCall.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182120 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/SemaObjCXX/missing-lhs-gun-extension.mm [new file with mode: 0644]

index 8c612b42ca029c101b9c141ac7b954a920f1b6f9..67c4f3e7dddd946a411886b184d4a505012ca766 100644 (file)
@@ -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/test/SemaObjCXX/missing-lhs-gun-extension.mm b/test/SemaObjCXX/missing-lhs-gun-extension.mm
new file mode 100644 (file)
index 0000000..0b5c998
--- /dev/null
@@ -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 <class T, class U = T> T tfoo(U x) { return x; }
+
+void func() {
+  NSDictionary* foo;
+  NSString* result = foo[@"bar"] ? : foo[@"baz"];
+
+  int (*fn)(int) = (&tfoo<int> ?: 0);
+
+  int x = 0;
+  const int &y = foo.random ?: x;
+}