Refine integer signedness use for static analyizers (#24)


diff --git a/Makefile b/Makefile
index 919c4c1..adb38ba 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 # Makefile -- UNIX-style make for qcbor as a lib and command line test
 #
-# Copyright (c) 2018-2019, Laurence Lundblade. All rights reserved.
+# Copyright (c) 2018-2020, Laurence Lundblade. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -8,7 +8,7 @@
 #
 
 
-CFLAGS=-I inc -I test -Os -Wcast-align -Wall -Werror -pedantic-errors -Wextra -Wshadow -Wparentheses -xc -std=c99
+CFLAGS=-I inc -I test -Os -Wcast-align -Wall -Werror -pedantic-errors -Wextra -Wshadow -Wparentheses -Wconversion -xc -std=c99
 
 QCBOR_OBJ=src/UsefulBuf.o src/qcbor_encode.o src/qcbor_decode.o src/ieee754.o
 
diff --git a/QCBOR.xcodeproj/project.pbxproj b/QCBOR.xcodeproj/project.pbxproj
index 857c6fc..14b61be 100644
--- a/QCBOR.xcodeproj/project.pbxproj
+++ b/QCBOR.xcodeproj/project.pbxproj
@@ -216,6 +216,7 @@
 			hasScannedForEncodings = 0;
 			knownRegions = (
 				en,
+				Base,
 			);
 			mainGroup = E776E073214ADF7F00E67947;
 			productRefGroup = E776E07D214ADF7F00E67947 /* Products */;
@@ -315,6 +316,7 @@
 				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
 				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
@@ -323,6 +325,7 @@
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
 				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
@@ -340,11 +343,15 @@
 					"DEBUG=1",
 					"$(inherited)",
 				);
+				GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_SHADOW = YES;
+				GCC_WARN_SIGN_COMPARE = YES;
 				GCC_WARN_UNDECLARED_SELECTOR = YES;
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_LABEL = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				MACOSX_DEPLOYMENT_TARGET = 10.13;
 				MTL_ENABLE_DEBUG_INFO = YES;
@@ -373,6 +380,7 @@
 				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
 				CLANG_WARN_INFINITE_RECURSION = YES;
 				CLANG_WARN_INT_CONVERSION = YES;
 				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
@@ -381,6 +389,7 @@
 				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
 				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
@@ -393,11 +402,15 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_SHADOW = YES;
+				GCC_WARN_SIGN_COMPARE = YES;
 				GCC_WARN_UNDECLARED_SELECTOR = YES;
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_LABEL = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				MACOSX_DEPLOYMENT_TARGET = 10.13;
 				MTL_ENABLE_DEBUG_INFO = NO;
diff --git a/src/UsefulBuf.c b/src/UsefulBuf.c
index 1d13f10..a96f74e 100644
--- a/src/UsefulBuf.c
+++ b/src/UsefulBuf.c
@@ -41,7 +41,8 @@
 
  when        who          what, where, why
  --------    ----         ---------------------------------------------------
- 01/08/2020 llundblade    Documentation corrections & improved code formatting.
+ 01/28/2020  llundblade   Refine integer signedness to quiet static analysis.
+ 01/08/2020  llundblade   Documentation corrections & improved code formatting.
  11/08/2019  llundblade   Re check pointer math and update comments
  3/6/2019    llundblade   Add UsefulBuf_IsValue()
  09/07/17    llundbla     Fix critical bug in UsefulBuf_Find() -- a read off
@@ -109,7 +110,8 @@
    for(const uint8_t *p = UB.ptr; p < pEnd; p++) {
       if(*p != uValue) {
          /* Byte didn't match */
-         return p - (uint8_t *)UB.ptr;
+         /* Cast from signed  to unsigned . Safe because the loop increments.*/
+         return (size_t)(p - (uint8_t *)UB.ptr);
       }
    }
 
diff --git a/src/ieee754.c b/src/ieee754.c
index ef0adef..41f60cf 100644
--- a/src/ieee754.c
+++ b/src/ieee754.c
@@ -65,10 +65,10 @@
 #define HALF_EXPONENT_SHIFT       (HALF_NUM_SIGNIFICAND_BITS)
 #define HALF_SIGN_SHIFT           (HALF_NUM_SIGNIFICAND_BITS + HALF_NUM_EXPONENT_BITS)
 
-#define HALF_SIGNIFICAND_MASK     (0x3ff) // The lower 10 bits  // 0x03ff
-#define HALF_EXPONENT_MASK        (0x1f << HALF_EXPONENT_SHIFT) // 0x7c00 5 bits of exponent
-#define HALF_SIGN_MASK            (0x01 << HALF_SIGN_SHIFT) //  // 0x80001 bit of sign
-#define HALF_QUIET_NAN_BIT        (0x01 << (HALF_NUM_SIGNIFICAND_BITS-1)) // 0x0200
+#define HALF_SIGNIFICAND_MASK     (0x3ffU) // The lower 10 bits  // 0x03ff
+#define HALF_EXPONENT_MASK        (0x1fU << HALF_EXPONENT_SHIFT) // 0x7c00 5 bits of exponent
+#define HALF_SIGN_MASK            (0x01U << HALF_SIGN_SHIFT) //  // 0x8000 1 bit of sign
+#define HALF_QUIET_NAN_BIT        (0x01U << (HALF_NUM_SIGNIFICAND_BITS-1)) // 0x0200
 
 /* Biased    Biased    Unbiased   Use
     0x00       0        -15       0 and subnormal
@@ -91,10 +91,10 @@
 #define SINGLE_EXPONENT_SHIFT       (SINGLE_NUM_SIGNIFICAND_BITS)
 #define SINGLE_SIGN_SHIFT           (SINGLE_NUM_SIGNIFICAND_BITS + SINGLE_NUM_EXPONENT_BITS)
 
-#define SINGLE_SIGNIFICAND_MASK     (0x7fffffUL) // The lower 23 bits
-#define SINGLE_EXPONENT_MASK        (0xffUL << SINGLE_EXPONENT_SHIFT) // 8 bits of exponent
-#define SINGLE_SIGN_MASK            (0x01UL << SINGLE_SIGN_SHIFT) // 1 bit of sign
-#define SINGLE_QUIET_NAN_BIT        (0x01UL << (SINGLE_NUM_SIGNIFICAND_BITS-1))
+#define SINGLE_SIGNIFICAND_MASK     (0x7fffffU) // The lower 23 bits
+#define SINGLE_EXPONENT_MASK        (0xffU << SINGLE_EXPONENT_SHIFT) // 8 bits of exponent
+#define SINGLE_SIGN_MASK            (0x01U << SINGLE_SIGN_SHIFT) // 1 bit of sign
+#define SINGLE_QUIET_NAN_BIT        (0x01U << (SINGLE_NUM_SIGNIFICAND_BITS-1))
 
 /* Biased  Biased   Unbiased  Use
     0x0000     0     -127      0 and subnormal
@@ -229,7 +229,7 @@
         // Also have to shift the significand by the difference in number of bits between a single and a half significand
         const uint32_t uSignificandBitsDiff = SINGLE_NUM_SIGNIFICAND_BITS - HALF_NUM_SIGNIFICAND_BITS;
         // Add in the 1 that is implied in the significand of a normal number; it needs to be present in a subnormal
-        const uint32_t uSingleSignificandSubnormal = uSingleSignificand + (0x01UL << SINGLE_NUM_SIGNIFICAND_BITS);
+        const uint32_t uSingleSignificandSubnormal = uSingleSignificand + (0x01U << SINGLE_NUM_SIGNIFICAND_BITS);
         uHalfSignificand = uSingleSignificandSubnormal >> (uExpDiff + uSignificandBitsDiff);
     } else {
         // The normal case, exponent is in range for half-precision
diff --git a/src/qcbor_decode.c b/src/qcbor_decode.c
index 661264e..1b6ff3e 100644
--- a/src/qcbor_decode.c
+++ b/src/qcbor_decode.c
@@ -42,6 +42,7 @@
 
  when       who             what, where, why
  --------   ----            ---------------------------------------------------
+ 01/28/2020 llundblade      Refine integer signedness to quiet static analysis.
  01/25/2020 llundblade      Cleaner handling of too-long encoded string input.
  01/25/2020 llundblade      Refine use of integer types to quiet static analysis
  01/08/2020 llundblade      Documentation corrections & improved code formatting
@@ -1199,7 +1200,7 @@
  The epoch formatted date. Turns lots of different forms of encoding
  date into uniform one
  */
-static int DecodeDateEpoch(QCBORItem *pDecodedItem)
+static QCBORError DecodeDateEpoch(QCBORItem *pDecodedItem)
 {
    // Stack usage: 1
    QCBORError nReturn = QCBOR_SUCCESS;
@@ -1217,7 +1218,7 @@
             nReturn = QCBOR_ERR_DATE_OVERFLOW;
             goto Done;
          }
-         pDecodedItem->val.epochDate.nSeconds = pDecodedItem->val.uint64;
+         pDecodedItem->val.epochDate.nSeconds = (int64_t)pDecodedItem->val.uint64;
          break;
 
       case QCBOR_TYPE_DOUBLE:
@@ -1341,7 +1342,9 @@
       // Got a good big num mantissa
       pDecodedItem->val.expAndMantissa.Mantissa.bigNum = mantissaItem.val.bigNum;
       // Depends on numbering of QCBOR_TYPE_XXX
-      pDecodedItem->uDataType += 1 + mantissaItem.uDataType - QCBOR_TYPE_POSBIGNUM;
+      pDecodedItem->uDataType = (uint8_t)(pDecodedItem->uDataType +
+                                          mantissaItem.uDataType - QCBOR_TYPE_POSBIGNUM +
+                                          1);
    } else {
       // Wrong type of mantissa or a QCBOR_TYPE_UINT64 > INT64_MAX
       nReturn = QCBOR_ERR_BAD_EXP_AND_MANTISSA;
@@ -1508,7 +1511,7 @@
  */
 QCBORError QCBORDecode_Finish(QCBORDecodeContext *me)
 {
-   int nReturn = QCBOR_SUCCESS;
+   QCBORError nReturn = QCBOR_SUCCESS;
 
    // Error out if all the maps/arrays are not closed out
    if(DecodeNesting_IsNested(&(me->nesting))) {
@@ -1688,7 +1691,7 @@
          if(uNewSize <= uPoolSize - uFreeOffset) {
             ReturnValue.len = uNewSize;
             ReturnValue.ptr = (uint8_t *)pPool + uFreeOffset;
-            uFreeOffset    += uNewSize;
+            uFreeOffset    += (uint32_t)uNewSize;
          }
       }
    } else {
diff --git a/test/qcbor_decode_tests.c b/test/qcbor_decode_tests.c
index 1009e16..125560e 100644
--- a/test/qcbor_decode_tests.c
+++ b/test/qcbor_decode_tests.c
@@ -835,14 +835,14 @@
 {
    int nResult = 0;
 
-   for(int nNum = sizeof(spExpectedEncodedInts)-1; nNum; nNum--) {
+   for(size_t nNum = sizeof(spExpectedEncodedInts)-1; nNum; nNum--) {
       QCBORDecodeContext DCtx;
 
       QCBORDecode_Init(&DCtx,
                        (UsefulBufC){spExpectedEncodedInts, nNum},
                        QCBOR_DECODE_MODE_NORMAL);
 
-      const QCBORError nErr = IntegerValuesParseTestInternal(&DCtx);
+      const int nErr = IntegerValuesParseTestInternal(&DCtx);
 
       if(nErr != QCBOR_ERR_HIT_END && nErr != QCBOR_ERR_NO_MORE_ITEMS) {
          nResult = -1;
@@ -1615,8 +1615,9 @@
       if(nCBORError != pF->nError ||
          Item.uDataType != QCBOR_TYPE_NONE ||
          Item.uLabelType != QCBOR_TYPE_NONE) {
-         // return index of CBOR + 1000
-         return (int)(pF -  pFailInputs) * 100 + nCBORError;
+         // return index of CBOR + 100
+         const size_t nIndex = (size_t)(pF - pFailInputs)/sizeof(struct FailInput);
+         return (int32_t)(nIndex * 100 + nCBORError);
       }
    }
 
@@ -1969,7 +1970,7 @@
 /* Try all 256 values of the byte at nLen including recursing for
  each of the values to try values at nLen+1 ... up to nLenMax
  */
-static void ComprehensiveInputRecurser(uint8_t *pBuf, int nLen, int nLenMax)
+static void ComprehensiveInputRecurser(uint8_t *pBuf, size_t nLen, size_t nLenMax)
 {
    if(nLen >= nLenMax) {
       return;
diff --git a/test/qcbor_encode_tests.c b/test/qcbor_encode_tests.c
index e922503..36187e3 100644
--- a/test/qcbor_encode_tests.c
+++ b/test/qcbor_encode_tests.c
@@ -1129,18 +1129,18 @@
    // add array with 31 items
    QCBOREncode_OpenArrayInMap(&ECtx, "arr");
    for (size_t ix = 0; ix < 31; ix++) {
-      QCBOREncode_AddInt64(&ECtx, ix);
+      QCBOREncode_AddInt64(&ECtx, (int64_t)ix);
    }
    QCBOREncode_CloseArray(&ECtx);
 
    // add map with 31 items
    QCBOREncode_OpenMapInMap(&ECtx, "map");
-   for (size_t ix = 0; ix < 31; ix++) {
+   for (int ix = 0; ix < 31; ix++) {
       // make sure we have unique keys in the map (a-z then follow by A-Z)
-      char c = 'a';
+      int c = 'a';
       if (ix < 26) c = c + ix;
       else c = 'A' + (ix - 26);
-      char buffer[2] = { c, 0 };
+      char buffer[2] = { (char)c, 0 };
       QCBOREncode_AddInt64ToMap(&ECtx, buffer, ix);
    }
    QCBOREncode_CloseMap(&ECtx);
@@ -1563,8 +1563,8 @@
  */
 
 static UsefulBufC
-FormatRTICResults(uint64_t uRResult,
-                  uint64_t time,
+FormatRTICResults(uint8_t uRResult,
+                  int64_t time,
                   const char *szType,
                   const char *szAlexString,
                   UsefulBuf Storage)
diff --git a/test/run_tests.c b/test/run_tests.c
index 133103f..f8ed83b 100644
--- a/test/run_tests.c
+++ b/test/run_tests.c
@@ -288,7 +288,7 @@
 
    (*pfOutput)(szWhat, pOutCtx, 0);
    (*pfOutput)(" ", pOutCtx, 0);
-   (*pfOutput)(NumToString(uSize, buffer), pOutCtx, 0);
+   (*pfOutput)(NumToString((int32_t)uSize, buffer), pOutCtx, 0);
    (*pfOutput)("", pOutCtx, 1);
 }