Fix a bug in Sema::CheckConditionalOperands(). When mixing pointers and null pointer constants, we need to promote the null pointer constant (which is an integer) to the pointer type. Test case is self explanatory.
This surfaced yesterday, when compiling test/Sema/cocoa.m on Leopard. Since this has nothing to do with ObjC, it's kind of bizarre this hasn't shown up before. I imagine Cocoa.h on Leopard may have changed recently?
Thanks to Ted for localizing the bug and giving me a useful AST dump...
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43114 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp
index f3381b8..12897ea 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -705,6 +705,16 @@
return new CastExpr(castType, castExpr, LParenLoc);
}
+// promoteExprToType - a helper function to ensure we create exactly one
+// ImplicitCastExpr.
+static void promoteExprToType(Expr *&expr, QualType type) {
+ if (ImplicitCastExpr *impCast = dyn_cast<ImplicitCastExpr>(expr))
+ impCast->setType(type);
+ else
+ expr = new ImplicitCastExpr(type, expr);
+ return;
+}
+
inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
Expr *&cond, Expr *&lex, Expr *&rex, SourceLocation questionLoc) {
UsualUnaryConversions(cond);
@@ -738,11 +748,14 @@
}
}
// C99 6.5.15p3
- if (lexT->isPointerType() && rex->isNullPointerConstant(Context))
+ if (lexT->isPointerType() && rex->isNullPointerConstant(Context)) {
+ promoteExprToType(rex, lexT); // promote the null to a pointer.
return lexT;
- if (rexT->isPointerType() && lex->isNullPointerConstant(Context))
+ }
+ if (rexT->isPointerType() && lex->isNullPointerConstant(Context)) {
+ promoteExprToType(lex, rexT); // promote the null to a pointer.
return rexT;
-
+ }
if (const PointerType *LHSPT = lexT->getAsPointerType()) { // C99 6.5.15p3,6
if (const PointerType *RHSPT = rexT->getAsPointerType()) {
// get the "pointed to" types
@@ -797,16 +810,6 @@
return new ConditionalOperator(CondExpr, LHSExpr, RHSExpr, result);
}
-// promoteExprToType - a helper function to ensure we create exactly one
-// ImplicitCastExpr. As a convenience (to the caller), we return the type.
-static void promoteExprToType(Expr *&expr, QualType type) {
- if (ImplicitCastExpr *impCast = dyn_cast<ImplicitCastExpr>(expr))
- impCast->setType(type);
- else
- expr = new ImplicitCastExpr(type, expr);
- return;
-}
-
/// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
/// do not have a prototype. Integer promotions are performed on each
/// argument, and arguments that have type float are promoted to double.