aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-02-18 04:38:20 +0000
committerChris Lattner <sabre@nondot.org>2009-02-18 04:38:20 +0000
commita119a3b07372888a2f5b9ec693c52daae7c0f522 (patch)
treefc43f9727b3fa4bb30a5db7ca0570229dfb23117
parentefdc39d4f5e61df2d0b41a5de8e744f252b5aff3 (diff)
fix rdar://6597252: two exactly identical pointer types are always
compatible, even if they are weird implicit objc pointer types like Class. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64885 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExpr.cpp22
-rw-r--r--test/SemaObjC/exprs.m7
2 files changed, 22 insertions, 7 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 3b80cd0132..4eb29c4f94 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2218,8 +2218,9 @@ Sema::ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
/// Note that lex is not null here, even if this is the gnu "x ?: y" extension.
/// In that case, lex = cond.
-inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
- Expr *&Cond, Expr *&LHS, Expr *&RHS, SourceLocation QuestionLoc) {
+/// C99 6.5.15
+QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
+ SourceLocation QuestionLoc) {
UsualUnaryConversions(Cond);
UsualUnaryConversions(LHS);
UsualUnaryConversions(RHS);
@@ -2284,6 +2285,7 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
ImpCastExprToType(LHS, RHSTy); // promote the null to a pointer.
return RHSTy;
}
+
// Handle the case where both operands are pointers before we handle null
// pointer constants in case both operands are null pointer constants.
if (const PointerType *LHSPT = LHSTy->getAsPointerType()) { // C99 6.5.15p3,6
@@ -2310,6 +2312,11 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
return destType;
}
+ if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
+ // Two identical pointers types are always compatible.
+ return LHSTy;
+ }
+
QualType compositeType = LHSTy;
// If either type is an Objective-C object type then check
@@ -2373,6 +2380,12 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
return compositeType;
}
}
+
+ // Selection between block pointer types is ok as long as they are the same.
+ if (LHSTy->isBlockPointerType() && RHSTy->isBlockPointerType() &&
+ Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy))
+ return LHSTy;
+
// Need to handle "id<xx>" explicitly. Unlike "id", whose canonical type
// evaluates to "struct objc_object *" (and is handled above when comparing
// id with statically typed objects).
@@ -2398,11 +2411,6 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
}
}
- // Selection between block pointer types is ok as long as they are the same.
- if (LHSTy->isBlockPointerType() && RHSTy->isBlockPointerType() &&
- Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy))
- return LHSTy;
-
// Otherwise, the operands are not compatible.
Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
diff --git a/test/SemaObjC/exprs.m b/test/SemaObjC/exprs.m
new file mode 100644
index 0000000000..d675865eb5
--- /dev/null
+++ b/test/SemaObjC/exprs.m
@@ -0,0 +1,7 @@
+// RUN: clang %s -fsyntax-only
+
+// rdar://6597252
+Class foo(Class X) {
+ return 1 ? X : X;
+}
+