]> granicus.if.org Git - clang/commitdiff
Fix a bug in Sema::CheckConditionalOperands(). When mixing pointers and null pointer...
authorSteve Naroff <snaroff@apple.com>
Thu, 18 Oct 2007 05:13:08 +0000 (05:13 +0000)
committerSteve Naroff <snaroff@apple.com>
Thu, 18 Oct 2007 05:13:08 +0000 (05:13 +0000)
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

Sema/SemaExpr.cpp
test/Sema/implicit-cast.c [new file with mode: 0644]

index f3381b8148f9495e7f0c166a857098c44bb5c129..12897ea291ccf7a0d8ef8a9b77cdf07e0f7b82b1 100644 (file)
@@ -705,6 +705,16 @@ ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
   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 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
     }
   }
   // 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 @@ Action::ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
   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.
diff --git a/test/Sema/implicit-cast.c b/test/Sema/implicit-cast.c
new file mode 100644 (file)
index 0000000..fe83bd9
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: clang -fsyntax-only %s
+
+static char *test1(int cf) {
+  return cf ? "abc" : 0;
+}
+static char *test2(int cf) {
+  return cf ? 0 : "abc";
+}