fix problem with ternary operator in varargs function calls
authorkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 23 May 2001 22:17:12 +0000 (22:17 +0000)
committerkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 23 May 2001 22:17:12 +0000 (22:17 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@845 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/SDCCast.c
src/SDCCast.h

index 2824561ad249cf27cd3c2879c28cb94850e3b856..9eefea9c6ba0d7da99953ef6b13893f2b3c94396 100644 (file)
@@ -641,6 +641,7 @@ processParms (ast * func,
   if (!defParm && actParm && func->hasVargs)
     {
       ast *newType = NULL;
+      sym_link *ftype;
 
       if (IS_CAST_OP (actParm)
          || (IS_AST_LIT_VALUE (actParm) && actParm->values.literalFromCast))
@@ -649,25 +650,39 @@ processParms (ast * func,
          return 0;
        }
 
+      /* The ternary ('?') operator is weird: the ftype of the 
+       * operator is the type of the condition, but it will return a 
+       * (possibly) different type. 
+       */
+      if (IS_TERNARY_OP(actParm))
+      {
+          assert(IS_COLON_OP(actParm->right));
+          assert(actParm->right->left);
+          ftype = actParm->right->left->ftype;
+      }
+      else
+      {
+          ftype = actParm->ftype;
+      }
+          
       /* If it's a small integer, upcast to int. */
-      if (IS_INTEGRAL (actParm->ftype)
-         && getSize (actParm->ftype) < (unsigned) INTSIZE)
+      if (IS_INTEGRAL (ftype)
+         && (getSize (ftype) < (unsigned) INTSIZE))
        {
-         newType = newAst_LINK (INTTYPE);
+         newType = newAst_LINK(INTTYPE);
        }
 
-      if (IS_PTR (actParm->ftype) && !IS_GENPTR (actParm->ftype))
+      if (IS_PTR(ftype) && !IS_GENPTR(ftype))
        {
-         newType = newAst_LINK (copyLinkChain (actParm->ftype));
+         newType = newAst_LINK (copyLinkChain(ftype));
          DCL_TYPE (newType->opval.lnk) = GPOINTER;
        }
 
-      if (IS_AGGREGATE (actParm->ftype))
+      if (IS_AGGREGATE (ftype))
        {
-         newType = newAst_LINK (copyLinkChain (actParm->ftype));
+         newType = newAst_LINK (copyLinkChain (ftype));
          DCL_TYPE (newType->opval.lnk) = GPOINTER;
        }
-
       if (newType)
        {
          /* cast required; change this op to a cast. */
index a6ddbfb9fe3cf135119ecfcf9e1ab814a9f78124..dc1b6e65f7c71766558f2ecb5b4f54495f651ad1 100644 (file)
@@ -130,6 +130,8 @@ ast;
                                   x->opval.op == EQ_OP ||              \
                                   x->opval.op == NE_OP ))
 #define IS_CAST_OP(x) (IS_AST_OP(x) && x->opval.op == CAST)
+#define IS_TERNARY_OP(x) (IS_AST_OP(x) && x->opval.op == '?')
+#define IS_COLON_OP(x) (IS_AST_OP(x) && x->opval.op == ':')
 #define IS_ADDRESS_OF_OP(x)    (IS_AST_OP(x)            &&              \
                                x->opval.op == '&'      &&              \
                                x->right == NULL )