[cfe-commits] r55346 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/CodeGen/2008-08-25-incompatible-cond-expr.m test/SemaObjC/conditional-expr2.m

Daniel Dunbar daniel at zuster.org
Mon Aug 25 17:41:40 PDT 2008


Author: ddunbar
Date: Mon Aug 25 19:41:39 2008
New Revision: 55346

URL: http://llvm.org/viewvc/llvm-project?rev=55346&view=rev
Log:
In incompatible pointer-typed ?: expressions, add implicit conversion
of RHSs to id type instead of void* if either has Objective-C object
type.
 - This ensures the result can still be used in normal places an
   object can be used, like a message send.

Add implicit conversions for ?: applied to qualified id types to
ensure that the RHSs are compatible. 
 - This prevents a codegen crash (creating invalid PHI nodes).
 - Again, this relates to the fact that qualified id types have no
   canonical types.
 - Note that the implicit type casted to is incorrect, however this
   doesn't currently cause problems because of the flexibility of the
   id type.

Test cases for above.

Added:
    cfe/trunk/test/CodeGen/2008-08-25-incompatible-cond-expr.m
    cfe/trunk/test/SemaObjC/conditional-expr2.m
Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=55346&r1=55345&r2=55346&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Aug 25 19:41:39 2008
@@ -1248,13 +1248,21 @@
         Diag(questionLoc, diag::warn_typecheck_cond_incompatible_pointers,
              lexT.getAsString(), rexT.getAsString(),
              lex->getSourceRange(), rex->getSourceRange());
-        // In this situation, we assume void* type. No especially good
-        // reason, but this is what gcc does, and we do have to pick
-        // to get a consistent AST.
-        QualType voidPtrTy = Context.getPointerType(Context.VoidTy);
-        ImpCastExprToType(lex, voidPtrTy);
-        ImpCastExprToType(rex, voidPtrTy);
-        return voidPtrTy;
+        // In this situation, assume a conservative type; in general
+        // we assume void* type. No especially good reason, but this
+        // is what gcc does, and we do have to pick to get a
+        // consistent AST. However, if either type is an Objective-C
+        // object type then use id.
+        QualType incompatTy;
+        if (Context.isObjCObjectPointerType(lexT) || 
+            Context.isObjCObjectPointerType(rexT)) {
+          incompatTy = Context.getObjCIdType();
+        } else {
+          incompatTy = Context.getPointerType(Context.VoidTy);
+        }
+        ImpCastExprToType(lex, incompatTy);
+        ImpCastExprToType(rex, incompatTy);
+        return incompatTy;
       }
       // The pointer types are compatible.
       // C99 6.5.15p6: If both operands are pointers to compatible types *or* to
@@ -1271,10 +1279,15 @@
   }
   // 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). FIXME: Do we need an ImpCastExprToType?
+  // id with statically typed objects). 
   if (lexT->isObjCQualifiedIdType() || rexT->isObjCQualifiedIdType()) {
-    if (ObjCQualifiedIdTypesAreCompatible(lexT, rexT, true))
-      return Context.getObjCIdType();
+    if (ObjCQualifiedIdTypesAreCompatible(lexT, rexT, true)) {
+      // FIXME: This is not the correct composite type. 
+      QualType compositeType = Context.getObjCIdType();
+      ImpCastExprToType(lex, compositeType);
+      ImpCastExprToType(rex, compositeType);
+      return compositeType;
+    }
   }
   // Otherwise, the operands are not compatible.
   Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands,

Added: cfe/trunk/test/CodeGen/2008-08-25-incompatible-cond-expr.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/2008-08-25-incompatible-cond-expr.m?rev=55346&view=auto

==============================================================================
--- cfe/trunk/test/CodeGen/2008-08-25-incompatible-cond-expr.m (added)
+++ cfe/trunk/test/CodeGen/2008-08-25-incompatible-cond-expr.m Mon Aug 25 19:41:39 2008
@@ -0,0 +1,8 @@
+ at protocol P0
+ at end
+ at interface A <P0>
+ at end
+
+id f0(int a, id<P0> x, A* p) {
+  return a ? x : p;
+}

Added: cfe/trunk/test/SemaObjC/conditional-expr2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/conditional-expr2.m?rev=55346&view=auto

==============================================================================
--- cfe/trunk/test/SemaObjC/conditional-expr2.m (added)
+++ cfe/trunk/test/SemaObjC/conditional-expr2.m Mon Aug 25 19:41:39 2008
@@ -0,0 +1,12 @@
+// RUN: clang -fsyntax-only -verify %s
+
+ at interface A
+ at end
+ at interface B
+ at end
+
+void f0(int cond, A *a, B *b) {
+  // Ensure that we can still send a message to result of incompatible
+  // conditional expression.
+  [ (cond ? a : b) test ]; // expected-warning {{pointer type mismatch}}, expected-warning {{method '-test' not found}}
+}





More information about the cfe-commits mailing list